在dplyr中使用单个负逻辑标准过滤多个变量

时间:2017-01-20 12:01:24

标签: r dplyr

我刚刚开始使用dplyr并且已经完成了小插图并且它没有符合我要求的示例。我无法弄清楚如何filter()数据框中的多个变量,其语句等效于'删除所有其中columnX等于' i'或列Y等于' ii' 。假设我们有这个数据帧。

df <- data.frame(n = rep(1:4,4), l = rep(letters[1:4], each = 4))

我想删除所有n = 1或l =&#34; a&#34;的情况。我可以使用此命令使用标准子集进行此操作。

df[-which(df$n == 1 | df$l == "a"),]

使用filter我可以用

删除所有1#
filter(df, !n == 1) 

filter(df, n != 1)

和&#34; a&#34; s

相同

但如果我尝试将它们组合起来

filter(df, !n == 1 | !l == "a")

filter(df, n != 1 | l != "a")

filter(df, !n == 1 | l == "a")

似乎是&#39;或&#39;函数|在dplyr中的工作方式不同。

或许我只是错过了一些非常明显的事情。

任何帮助表示感谢。

2 个答案:

答案 0 :(得分:4)

如果你不想要两种情况发生,你必须这样写:

df %>% filter(!(n == 1 | l == "a"))

//

至于你的例子,

df %>% filter(n != 1 | l != "a")

相当于

df %>% filter(!n == 1 | !l == "a")

,使用De Morgan定律(!(a & b)) = (!a | !b),与:

相同
df %>% filter(! (n == 1 & l == "a"))

并过滤掉同时满足两个条件的所有行。

的例子
df %>% filter(!n == 1 | l == "a")

仅禁止n == 1l != "a"出现在同一行的情况,因此(1,b);数据帧中缺少(1,c)和(1,d)。 (符号:(n,l))

答案 1 :(得分:1)

您可以使用df[(df$n != 1 | df$l !="a"),]进行子集化,这样可以有效地删除示例中的第一行,为您留下15行。

如果你对dplyr使用相同的,它会返回相同数量的记录,可以用

检查
   df %>% 
    filter(n != 1 | l != "a") %>% 
    dim() %>% 
    assertthat::are_equal(dim(df[(df$n != 1 | df$l !="a"),]))

这消除了两个条件都为真的所有行。

另一方面,如果要排除任何条件为真的情况,可以使用df %>% filter(!(n == 1 | l == "a")),它返回9行,排除任何一个条件为真的所有行。

重新访问De Morgan's Law可能会有所帮助。