我有一个数据集df
,我想删除变量y
没有值a
的所有行。变量y
还包含一些NAs
:
df <- data.frame(x=1:3, y=c('a', NA, 'c'))
我可以使用R的索引语法实现这一点:
df[df$y!='a',]
x y
2 <NA>
3 c
请注意,这会返回NA
和值c
- 这就是我想要的。
但是,当我使用subset
或dplyr::filter
尝试相同的操作时,NA
会被删除:
subset(df, y!='a')
x y
3 c
dplyr::filter(df, y!='a')
x y
3 c
为什么subset
和dplyr::filter
会像这样工作?这对我来说似乎不合逻辑 - NA
与a
不同,所以为什么在我指定我想要除变量NA
等于的所有行之外删除y
a
?
除了明确要求NAs
返回之外,还有一些方法可以改变这些功能的行为,即
subset(df, y!='a' | is.na(y))
由于
答案 0 :(得分:8)
“预期”行为的示例实际上并不会返回您在问题中显示的内容。我明白了:
> df[df$y != 'a',]
x y
NA NA <NA>
3 3 c
这可能比<{1}}和subset
返回的更多错误。请记住,在R中,dplyr::filter
的意思是“未知”,因此NA
会返回,
df$y != 'a'
所以R被告知你肯定不想要第一行,你确实想要最后一行,但是你是否想要第二行字面意思是“未知”。因此,它包含一行> df$y != 'a'
[1] FALSE NA TRUE
s。
许多人不喜欢这种行为,但它就是这样。
NA
和subset
提供了一个不同的默认选择,即只删除dplyr::filter
行,这可能是准确的。
但实际上,这里的教训是,如果您的数据有NA
s,那就意味着您需要通过使用NA
之类的条件,或者如上所述,在所有点进行防御性编码在另一个答案中使用基于is.na(df$y) | df$y != 'a'
的{{1}}。
答案 1 :(得分:7)
一种解决方法是使用%in%
:
subset(df, !y %in% "a")
dplyr::filter(df, !y %in% "a")