【问题标题】:R removes more observations than it should with dplyr or base subsetR 删除的观测值比使用 dplyr 或基本子集的观测值多
【发布时间】:2018-03-09 18:14:20
【问题描述】:

我有一个关于 dplyr 的 filter() 函数和/或 R 中的 base subset() 函数的问题。基本上,当我使用 filter() 或 subset() 时,我可以根据两个条件提取观察结果,这就是我需要的。 例如,这是我迄今为止一直在使用的:

df %>% filter(Axis_1_1 == "Diagnostic of function on axis1 postponed") %>% filter(is.na(diagnostic_code9))

这为我提供了同时满足这两个条件的适量观察,即总共 23992 个中的 92 个。

但是,当我使用否定符号不将这些观察结果包含在当前数据框中时,R 将删除大约 8000 个额外的观察结果。因此,最终结果是在用否定“!”过滤后剩下 15992 个观察值。使用的标志。示例:

df %>% filter(Axis_1_1 != "Diagnostic of function on axis1 postponed") %>% filter(!is.na(diagnostic_code9))

使用基于 R 的简单子集给我同样错误的最终结果,但它设法找到满足条件的正确 92 个观察值,如第一个示例中所述。

subset(df, df$Axis1_1 == "Diagnostic of function on axis1 postponed" & is.na(diagnostic_code9))

我的数据框在当前设置中包含 112 个变量和 23900 多个观察值。

因此,我的问题是:

  • 我正在使用的数据框会不会有什么奇怪的地方(很遗憾,我不能给你一个子集)
  • 第二,我的编码有问题吗?
  • 最后,R 在后台到底在做什么?因为它能够根据与字符串和 is.na() 函数匹配的确切条件过滤掉这些观察结果,同时在使用否定符号时完全做其他事情。

【问题讨论】:

  • 在逻辑上,你第一次是在做A AND B,第二次是(not A) AND (not B)。但not(A AND B) 实际上是(not A) OR (not B)。见deMorgan's Laws on wikipedia
  • 那么你第二次想要得到补码的是filter(Axis_1_1 != "Diagnostic of function on axis1 postponed" | !is.na(diagnostic_code9))
  • 或者,如果你第一次使用单个filterfilter(A & B),你可以用括号filter(!(A & B)) 否定它

标签: r dplyr subset


【解决方案1】:

在这种情况下,您的逻辑不引用工作。执行两个后续过滤语句有点像执行 AND 操作。考虑下面的例子

df <- data.frame(a=c(1,1,1,1,2,2,2, 2), 
                 b=c(NA,NA,5,5,5,5,5,NA))    

df %>% filter(a==1) %>% filter(is.na(b))
#   a  b
# 1 1 NA
# 2 1 NA
df %>% filter(a!=1) %>% filter(!is.na(b))
#   a b
# 1 2 5
# 2 2 5
# 3 2 5

注意带有 a=1, b=5 的行即使不在第一个输出中也不会返回,因为您的第一个过滤器 (filter(!=1)) 会消除它们。

因此,如果您将两个过滤器视为 A 和 B,则在第一种情况下,您正在执行 A 和 B。它与

df %>% filter(a==1 & is.na(b))
#   a  b
# 1 1 NA
# 2 1 NA

但是在第二个中,您执行的是 NOT A 和 NOT B。它们不等价。根据DeMorgan's Law,你不需要A或NOT B。所以试试

df %>% filter(a!=1 | !is.na(b))
#   a  b
# 1 1  5
# 2 1  5
# 3 2  5
# 4 2  5
# 5 2  5
# 6 2 NA

或等效(注意括号将 NOT (!) 应用于整个表达式)

df %>% filter(!(a==1 & is.na(b)))

【讨论】:

  • 不错的答案 ;) 可能值得为此寻找/制作一个规范的骗局。
  • @Gregor 是的。我看到你的 cmets 有很多重叠 :) 如果你发现其他类似的问题,结合起来是有意义的。
  • Not as many hits as I thought。我不是很彻底,但是在看了一对夫妇之后,我最喜欢这个答案。我可能会开始关闭其他人作为这个人的欺骗。
  • 发布的解决方案都有效。感谢 DeMorgans 定律的澄清,这是我没有深入思考的问题。但是,在 NOT A OR NOT B 的情况下,我假设它始终是 NOT A AND NOT B 的情况,因为我想过滤掉两列都满足某个值(无论是 NA 还是字符串)的行同一时间。
猜你喜欢
  • 2015-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-11
  • 2016-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多