请考虑以下代码。当您未在条件中明确测试NA
时,该代码将在稍后的某个日期失败,然后您的数据会发生变化。
> # A toy example
> a <- as.data.frame(cbind(col1=c(1,2,3,4),col2=c(2,NA,2,3),col3=c(1,2,3,4),col4=c(4,3,2,1)))
> a
col1 col2 col3 col4
1 1 2 1 4
2 2 NA 2 3
3 3 2 3 2
4 4 3 4 1
>
> # Bummer, there's an NA in my condition
> a$col2==2
[1] TRUE NA TRUE FALSE
>
> # Why is this a good thing to do?
> # It NA'd the whole row, and kept it
> a[a$col2==2,]
col1 col2 col3 col4
1 1 2 1 4
NA NA NA NA NA
3 3 2 3 2
>
> # Yes, this is the right way to do it
> a[!is.na(a$col2) & a$col2==2,]
col1 col2 col3 col4
1 1 2 1 4
3 3 2 3 2
>
> # Subset seems designed to avoid this problem
> subset(a, col2 == 2)
col1 col2 col3 col4
1 1 2 1 4
3 3 2 3 2
有人可以解释为什么没有is.na
检查的行为会变得好或有用吗?
答案 0 :(得分:30)
我绝对同意这不直观(I made that point before on SO)。为了防御R,我认为知道何时有缺失值是有用的(即这不是错误)。 ==
运算符明确设计为通知用户NA或NaN值。有关更多信息,请参阅?“==”。它声明:
缺少值('NA')和'NaN'值被视为 即使对自己也不具有可比性,因此需要进行比较 总会产生'NA'。
换句话说,使用二元运算符(因为它是未知的),缺失值是不可比较的。
超越is.na(),你也可以这样做:
which(a$col2==2) # tests explicitly for TRUE
或者
a$col2 %in% 2 # only checks for 2
%in%定义为使用match()
函数:
'"%in%" <- function(x, table) match(x, table, nomatch = 0) > 0'
"The R Inferno"也涵盖了这一点。
在R中检查数据中的NA值至关重要,因为许多重要的操作符都没有按照您的预期处理它。除了==之外,对于诸如&amp;,|,&lt;,sum()之类的东西也是如此。当我写R代码时,我总是在想“如果在这里有一个NA会发生什么”。要求R用户小心缺少值是“按设计”。
NA
是一个逻辑常量,如果您不考虑可能返回的内容(例如NA | TRUE == TRUE
),则可能会出现意外的子集。来自?Logic
的这些真值表可以提供有用的说明:
outer(x, x, "&") ## AND table
# <NA> FALSE TRUE
#<NA> NA FALSE NA
#FALSE FALSE FALSE FALSE
#TRUE NA FALSE TRUE
outer(x, x, "|") ## OR table
# <NA> FALSE TRUE
#<NA> NA NA TRUE
#FALSE NA FALSE TRUE
#TRUE TRUE TRUE TRUE