问题 为什么dplyr的滤波器会从因子变量中删除NA值?


我用的时候 filter 来自 dplyr 包下降一个因子变量的水平, 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

这似乎并不理想 - 我只想把行放在哪里 var1 == 1

它似乎正在发生,因为任何 与...比较 NA 回报 NA, 哪一个 filter 然后下降。所以,例如, filter(dat, !(var1 %in% 1)) 产生正确的结果。但有没有办法告诉你 filter 不要放弃 NA 值?


8439
2017-10-02 13:45


起源

@akrun由于某种原因,我没有得到这个通知:P。好吧,我认为OP已经知道了这一点,正如他所提到的那样 filter(dat, !(var1 %in% 1)) 这是相似的,但我认为这将是唯一的方法 dplyr::filter。 - LyzandeR
我认为没有办法明确说出来 filter 不要掉下来 NA 但是通常,可以使用基础直观地处理逻辑NA查询 %in% 运算符和它的否定,定义为 %ni% <- Negate('%in%')。因此,你可以使用 filter(dat, var1 %ni% 1) 哪个会奏效。看到 stackoverflow.com/a/11303276/4269699 和 stackoverflow.com/a/27015823/4269699 - wjchulme
是的,我确实知道这种方法和@LyzandeR用于答案的方法。看起来过滤器没有“保持NA”的明确选项,所以这些变通方法会很好。谢谢你的帮助。 - Jake Fisher
唉这发生在我身上,我疯狂地试图理解为什么我输了这么多数据。同意这似乎不太理想...... - Arthur Yip


答案:


你可以用这个:

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

它不会。

也只是为了完成,丢弃NA是预期的行为 filter 正如您从以下所示:

test_that("filter discards NA", {
  temp <- data.frame(
    i = 1:5,
    x = c(NA, 1L, 1L, 0L, 0L)
  )
  res <- filter(temp, x == 1)
  expect_equal(nrow(res), 2L)
})

以上测试取自测试 filter 从 github上


16
2017-10-02 13:58



冒险进入基于意见的领域,您是否知道为什么这是选择的方法?这种行为对我来说意外(我今天被它咬了)。 - Heisenberg
@Heisenberg我假设根据Hadley的说法,大多数人在过滤时都不想获得任何NAs。但这对开发者/维护者来说是一个问题,即哈德利。 - LyzandeR