gpt4 book ai didi

r - 子集化 data.frame 时的 NA 会发生一些意想不到的事情

转载 作者:行者123 更新时间:2023-12-03 01:14:35 24 4
gpt4 key购买 nike

考虑以下代码。如果您没有在您的条件下明确测试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,我认为知道何时有缺失值是有用的(即这不是一个错误)。 == 运算符明确设计用于通知用户 NA 或 NaN 值。请参阅 ?"=="了解更多信息。它指出:

Missing values ('NA') and 'NaN' values are regarded as non-comparable even to themselves, so comparisons involving them will always result in '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 值至关重要,因为许多重要的运算符不会按照您期望的方式处理它。除了 == 之外,对于 &、|、<、sum() 等也同样如此。当我编写 R 代码时,我总是在想“如果这里有 NA 会发生什么”。要求 R 用户小心缺失值是“设计使然”。

更新:当存在多个逻辑条件时,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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com