使用dplyr::filter()删除包含NA的观测值

68

我的数据看起来像这样:

library(tidyverse)

df <- tribble(
    ~a, ~b, ~c,
    1, 2, 3, 
    1, NA, 3, 
    NA, 2, 3
)

我可以使用drop_na()函数删除所有带有NA的观测值:

df %>% drop_na()

或者在单个列(例如a)中删除所有的NA观测值:

df %>% drop_na(a)

为什么我不能只使用普通的 != 过滤器管道呢?

df %>% filter(a != NA)

为什么我们必须使用tidyr中的特殊函数来删除NA值?


1
price != "NA" 应该可以工作。 - Metrics
8
由于任何与 NA 的比较,包括 NA==NA,都将返回 NA - Marat Talipov
4
顺便说一句,这与 dplyr/filter 没有特定关系。 - Ben Bolker
相关但不完全相同:https://dev59.com/6l8f5IYBdhLWcg3wB-7E - Ben Bolker
1
@user3731467 我没有“diamonds”数据,但在示例数据上,Metrics的建议起作用了。 - akrun
显示剩余5条评论
5个回答

91

例如:

你可以使用:

df %>% filter(!is.na(a))

删除列a中的NA。


对于大数据(包括730万行和290列的数据框),这需要太长时间了...有更快的方法吗? - MJimitater

46

如果有人在2020年看到这里,在完成所有管道操作后,如果你使用管道%>% na.exclude,那么它将从管道中删除所有的NAs!


39

来自 @Ben Bolker:

[T]这与dplyr::filter()无关

来自 @Marat Talipov:

任何与NA的比较,包括NA == NA,都将返回NA

来自于相关回答by @farnsy:

==运算符不会像您期望的那样处理NA。

把NA看作是“我不知道那里有什么”。3>NA的正确答案显然是NA,因为我们不知道缺失值是否大于3。好吧,NA == NA也是一样的。它们都是缺失值,但真实值可能相当不同,因此正确的答案是“我不知道”。

R不知道您在分析中正在做什么,因此,它不允许比较运算符认为NA是一个值,以避免引入潜在的错误,这些错误最终可能被发布并让您尴尬。


2
我经常使用这个功能,它一直运行得非常完美。
cool$day[cool$day==''] <- NA  
cool$day[is.na(cool$day)] <- "NA"

cool <- cool[!cool$day == "NA", ]

0
另一个选择可能是在您的过滤器中使用complete.cases,例如移除列A中的NA。以下是一些可再现的代码:

library(dplyr)
df %>%
  filter(complete.cases(a))
#> # A tibble: 2 × 3
#>       a     b     c
#>   <dbl> <dbl> <dbl>
#> 1     1     2     3
#> 2     1    NA     3

使用reprex v2.0.2于2023年3月26日创建


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接