подсчет векторов с включенным NA - PullRequest
2 голосов
/ 14 сентября 2011

По ошибке я обнаружил, что вектор подсчета R с NA включен интересным образом:

> temp <- c(NA,NA,NA,1) # 4 items
> length(temp[temp>1])
[1] 3

> temp <- c(NA,NA,1) # 3 items
> length(temp[temp>1])
[1] 2

Сначала я предполагаю, что R обработает все NA с в один NA, ноэто не тот случай.

Кто-нибудь может объяснить?Спасибо.

Ответы [ 3 ]

3 голосов
/ 14 сентября 2011

Вы ожидали только ИСТИНА и ЛОЖЬ (и результаты будут только ЛОЖЬ), но логический вектор также может иметь NA. Если вы надеялись получить нулевой результат, у вас было по крайней мере три других варианта:

> temp <- c(NA,NA,NA,1) # 4 items
>  length(temp[ which(temp>1) ] )
[1] 0

> temp <- c(NA,NA,NA,1) # 4 items
>  length(subset( temp, temp>1) )
[1] 0

> temp <- c(NA,NA,NA,1) # 4 items
>  length( temp[ !is.na(temp) & temp>1 ] )
[1] 0

Вы найдете последнюю форму во многих внутренних кодах хорошо установленных функций. Мне кажется, что первая версия более экономична и проще для чтения, но R Core, похоже, не согласен. Мне несколько раз советовали на R help не использовать which () вокруг логических выражений. Я остаюсь убежденным. Это правильно, что нельзя сочетать это с отрицательной индексацией.

РЕДАКТИРОВАТЬ Причиной того, чтобы не использовать конструкцию "минус который" (отрицательное индексирование с помощью), является то, что в случае, когда все элементы не проходят тест "который" и, следовательно, можно ожидать, что все они будут возвращены, он возвращает неожиданный пустой вектор:

 temp <- c(1,2,3,4,NA)
 temp[!temp > 5]
#[1]  1  2  3  4 NA             As expected
 temp[-which(temp > 5)]
#numeric(0)                 Not as expected
 temp[!temp > 5 & !is.na(temp)]
#[1] 1 2 3 4           A correct way to handle negation

Я допускаю, что представление о том, что NA должны выбирать элементы NA, кажется немного странным, но оно уходит корнями в историю S и, следовательно, R. В ?"[" есть раздел о "NA в индексации". Обоснование состоит в том, что каждый NA в качестве индекса должен возвращать неизвестный результат, то есть другой NA.

2 голосов
/ 14 сентября 2011

Если разбить каждую команду и посмотреть на вывод, это будет более поучительно:

> tmp = c(NA, NA, 1)
> tmp > 1
[1]    NA    NA FALSE
> tmp[tmp > 1]
[1] NA NA

Итак, когда мы в следующий раз выполняем length(tmp[tmp > 1]), мы как бы выполняем length(c(NA,NA)). Хорошо иметь вектор, полный NA - он имеет фиксированную длину (как если бы мы создали его с помощью NA * vector(length = 2), что должно отличаться от NA * vector(length = 3).

0 голосов
/ 14 сентября 2011

Вы можете использовать 'sum':

> tmp <- c(NA, NA, NA, 3)
> sum(tmp > 1)
[1] NA
> sum(tmp > 1, na.rm=TRUE)
[1] 1

Небольшое объяснение: «sum» ожидает числа, но «tmp> 1» логично. Таким образом, оно автоматически приводится к числовому: TRUE => 1; ЛОЖЬ => 0; NA => NA.

Я не думаю, что в «The Inferno» есть что-то подобное, но это определенно тот вопрос, на который он нацелен. http://www.burns -stat.com / страницы / Репетитор / R_inferno.pdf

...