R 3.3.3版本data.frame按字符列子集化异常,求解释
关于R中字符列条件子集化的NA行为解释
这是个非常典型的R逻辑比较误区,咱们来一步步搞清楚问题出在哪:
1. NA值的比较特性
在R里,NA(缺失值)和任何值进行比较运算(包括==、!=等),结果都会是NA,而不是你预期的TRUE或FALSE。
回到你的例子,当你执行foo$bar != 'a'时,实际得到的逻辑向量是:
> foo$bar != 'a' [1] FALSE NA TRUE FALSE
其中原第二行的NA和'a'比较,结果自然是NA。
2. 逻辑向量子集化的规则
当你用包含NA的逻辑向量对data.frame做子集化时,R的处理逻辑是:
- TRUE:保留对应行的所有原始值
- FALSE:直接排除该行
- NA:保留该行,但将该行的所有列值替换为NA(因为R无法判断这行是否满足条件,用NA表示不确定)
这就是你看到结果里第一行全是NA的原因——它对应原数据框的第二行,因为比较结果是NA,所以被保留但值全变成了NA,而不是保留原来的baz=2。
3. 正确的子集化写法
根据你的需求,分两种情况:
情况1:想要所有bar不等于'a'且不是NA的行
需要明确排除NA,写法如下:
foo[foo$bar != 'a' & !is.na(foo$bar), ]
执行后会得到:
bar baz 3 b 3
情况2:想要所有**bar不是'a'(包括NA)**的行
需要把NA的情况单独纳入条件:
foo[is.na(foo$bar) | foo$bar != 'a', ]
执行后会得到:
bar baz 2 <NA> 2 3 b 3
另外还有个更简洁的写法,用%in%运算符(它会自动把NA的比较结果转为FALSE,取反后就会保留NA):
foo[!foo$bar %in% 'a', ]
这个写法和情况2的效果完全一致,因为foo$bar %in% 'a'会返回c(TRUE, FALSE, FALSE, TRUE),取反后就是c(FALSE, TRUE, TRUE, FALSE),刚好选中原第二、三行。
内容的提问来源于stack exchange,提问作者qdread
相关产品推荐
相关产品推荐

