为什么dplyr';s过滤器从因子变量中删除NA值?

为什么dplyr';s过滤器从因子变量中删除NA值?,r,dplyr,subset,na,R,Dplyr,Subset,Na,当我使用dplyr包中的filter删除因子变量级别时,filter也会删除NA值。下面是一个例子: library(dplyr) set.seed(919) (dat <- data.frame(var1 = factor(sample(c(1:3, NA), size = 10, replace = T)))) # var1 # 1 <NA> # 2 3 # 3 3 # 4 1 # 5 1 # 6 <NA> # 7

当我使用
dplyr
包中的
filter
删除因子变量级别时,
filter
也会删除
NA
值。下面是一个例子:

library(dplyr)
set.seed(919)
(dat <- data.frame(var1 = factor(sample(c(1:3, NA), size = 10, replace = T))))
#    var1
# 1  <NA>
# 2     3
# 3     3
# 4     1
# 5     1
# 6  <NA>
# 7     2
# 8     2
# 9  <NA>
# 10    1

filter(dat, var1 != 1)
#   var1
# 1    3
# 2    3
# 3    2
# 4    2
库(dplyr)
种子集(919)
(dat你可以用这个:

 filter(dat, var1 != 1 | is.na(var1))
  var1
1 <NA>
2    3
3    3
4 <NA>
5    2
6    2
7 <NA>

上述测试取自对
filter
的测试。

我经常将
相同的
映射为
mapply

(注:我相信由于R3.6.0的变化,
set.seed
sample
最终会得到不同的测试数据)

库(dplyr,warn.conflicts=FALSE)
种子集(919)
(dat var1)
#> 1     3
#> 2     1
#> 3  
#> 4     3
#> 5     1
#> 6     3
#> 7     2
#> 8     3
#> 9     2
#> 10    1
过滤器(dat,var1!=1)
#>var1
#> 1    3
#> 2    3
#> 3    3
#> 4    2
#> 5    3
#> 6    2
过滤器(dat,!mapply(相同,如.numeric(var1),1))
#>var1
#> 1    3
#> 2 
#> 3    3
#> 4    3
#> 5    2
#> 6    3
#> 7    2
它也适用于数字和字符串(可能是更常见的用例)

库(dplyr,warn.conflicts=FALSE)
种子集(919)
(dat var1 var2
#> 1     3 
#>21 a
#>3不适用
#>4.3 b
#>51B
#> 6     3 
#>7.2 a
#>8.3 c
#> 9     2 
#>101B
过滤器(dat,!mapply(相同,变量1,1L))
#>var1 var2
#> 1    3 
#>2 NA a
#>3 b
#> 4    3 
#>5.2 a
#>6.3 c
#> 7    2 
过滤器(dat,!mapply(相同,变量2,'a'))
#>var1 var2
#> 1    3 
#>2.3 b
#>31B
#> 4    3 
#>5.3 c
#> 6    2 
#>71B

前面给出的答案很好,但是当您的筛选语句涉及多个字段的函数时,解决方法可能不是很好。另外,谁想使用
mapply
非矢量化的
相同的
。下面是另一个使用
合并的更简单的解决方案

filter(dat, coalesce( var1 != 1, TRUE))

@因为某种原因,我没有收到这个通知:P。我想OP已经知道了,正如他提到的
filter(dat,!(var1%in%1))
这与之类似,但我认为这是使用
dplyr::filter
实现这一点的唯一方法。我不认为有任何方法可以明确告诉
filter
不要删除
NA
值,但一般来说,逻辑NA查询可以使用base
%in%
运算符及其否定(定义为
%ni%是的,我确实知道这个方法和@LyzandeR用于回答问题的方法。看起来过滤器没有明确的选项“保留NA”,所以这些变通方法会很好。谢谢你的帮助。啊,这件事发生在我身上,我疯狂地试图理解为什么我丢失了这么多数据。同意这似乎不理想……冒险进入基于意见的领域,你知道为什么选择这种方法吗?这种行为对我来说是意外的(我今天被它咬了一口)。@Heisenberg我想根据Hadley的说法,大多数人都不希望在过滤时得到任何NAs。但这是开发者/维护者Hadley的问题。
filter(dat, coalesce( var1 != 1, TRUE))