错误地,我发现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
,但事实并非如此。
有人可以解释一下吗?感谢。
答案 0 :(得分:3)
你只期望TRUE和FALSE(并且结果只是FALSE),但逻辑矢量也可以有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建议不要在逻辑表达式周围使用which()。我仍然不相信。不应该将它与否定索引结合起来是正确的。
编辑不使用构造“减去哪个”(负索引与哪个)的原因是,在所有项目都未通过which-test并且因此您希望返回所有项目的情况下,它返回意外的空矢量:
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。
答案 1 :(得分:2)
如果你分解每个命令并查看输出,那就更具启发性了:
> 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)
不同。
答案 2 :(得分:0)
您可以使用'sum':
> tmp <- c(NA, NA, NA, 3)
> sum(tmp > 1)
[1] NA
> sum(tmp > 1, na.rm=TRUE)
[1] 1
一点解释:'sum'需要数字,但'tmp&gt; 1'是合乎逻辑的。因此它会自动强制为数字:TRUE =&gt; 1; FALSE =&gt; 0; NA =&gt; NA。
我不认为“The R Inferno”中有任何类似的东西,但这绝对是它所针对的问题。 http://www.burns-stat.com/pages/Tutor/R_inferno.pdf