考虑以下代码。如果您没有在条件下显式测试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检查就会得到好的或有用的行为吗?

最佳答案

我绝对同意这不是直观的(I made that point before on SO)。为了捍卫R,我认为知道何时缺少值是有用的(即,这不是bug)。 ==运算符专门用于通知用户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值至关重要,因为许多重要的运算符都无法按照您期望的方式处理它。除了==以外,对于&,|,
更新:存在多个逻辑条件时如何处理NA?

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

关于r - 子集data.frame中的NA发生意外,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1773366/

10-14 16:17