逻辑运算符:和表达喜欢的OR

时间:2017-11-06 20:06:21

标签: r

当我使用filter中的dplyr时,我很难理解R如何处理AND和OR运算符。

以下是一个例子:

library(dplyr)
xy <- data.frame(x=1:6, y=c("a", "b"), z= c(rep("d",3), rep("g",3)))

> xy
  x y z
1 1 a d
2 2 b d
3 3 a d
4 4 b g
5 5 a g
6 6 b g

使用filter我想删除x==1 z==d的所有行。这会让我相信我想使用AND运算符:&

> filter(xy, x != 1 & z != "d")
  x y z
1 4 b g
2 5 a g
3 6 b g

但这会删除所有包含x==1 z==d的行。更令人困惑的是,当我使用OR运算符时,|我得到了所需的结果:

> filter(xy, x != 1 | z != "d")
  x y z
1 2 b d
2 3 a d
3 4 b g
4 5 a g
5 6 b g

此外,这确实有效,但如果我在同一个条件评估中将==!=串在一起,则不是很理想。

> filter(xy, !(x == 1 & z == "d"))
  x y z
1 2 b d
2 3 a d
3 4 b g
4 5 a g
5 6 b g

有人可以解释我错过的内容吗?

4 个答案:

答案 0 :(得分:6)

这是布尔代数的问题。逻辑表达式!(x == 1 & z == d)等同于x != 1 | z != d,与-(x + y)相同,等同于-x - y。取消括号后,您将所有==更改为!=,将所有&更改为|,反之亦然。这导致了

的事实
!(x == 1 & z == "d")

不同
x != 1 & z != "d"

而是

x != 1 | z != "d"

答案 1 :(得分:2)

一些不适合评论的提示:

  1. 如果您无法理解R中的某些内容是如何工作的,我强烈建议您运行每个单独的操作。使用dplyr,可以轻松跟踪中间步骤并显示所有步骤:

    mutate(xy,
             A = x != 1,
             B = z != 'd',
             A_and_B = A & B,
             A_or_B = A | B
             )
    #   x y z     A     B A_and_B A_or_B
    # 1 1 a d FALSE FALSE   FALSE  FALSE
    # 2 2 b d  TRUE FALSE   FALSE   TRUE
    # 3 3 a d  TRUE FALSE   FALSE   TRUE
    # 4 4 b g  TRUE  TRUE    TRUE   TRUE
    # 5 5 a g  TRUE  TRUE    TRUE   TRUE
    # 6 6 b g  TRUE  TRUE    TRUE   TRUE
    

    我认为,如果你看一下每一列的定义,它的价值就会非常有意义。然后,在一步一步之后,希望结果也是有意义的。

  2. 正如其他人已经以各种方式陈述的那样,你从一开始就为自己做好准备

      

    使用过滤器我想要消除x == 1和z == d

    的所有行

    不要将filter视为消除行,将其视为保留行。如果您在心理上将您的目标反转为“将所有行保留在哪里......”,您就可以自行设置单词到代码的直接翻译。

答案 2 :(得分:1)

filter的结果是行,其中指定的条件为真

x != 1 & z != "d"为例。这种情况属实的行是什么?你得到的输出。其他行已被删除,因为这些行的条件不正确。

在此示例中,您的真实目的是消除x == 1 and z == "d"中的行。 换句话说,您希望保留条件x == 1 and z == "d"为假的行。 将其放入代码成为filter(xy, !(x == 1 and z == "d"))。 具有讽刺意味的是,这看起来很像你的意图,与你实际尝试写的非常不同。

如果你忘记filter的逻辑, 您可以通过一个更简单的实验提醒自己,filter(xy, TRUE)将返回所有行,filter(xy, FALSE)将返回任何行。

答案 3 :(得分:1)

# x != 1 & z != "d" evaluates to a single TRUE/FALSE vector which subsets the data

# note how & and | behave in isolation:
TRUE & TRUE  # T AND T = T
## [1] TRUE
TRUE & FALSE # T AND F = F
## [1] FALSE
FALSE & FALSE # F AND F = F
## [1] FALSE
TRUE | TRUE   # T OR T = T
## [1] TRUE
TRUE | FALSE  # T OR F = T
## [1] TRUE
FALSE | FALSE # F OR F = F
## [1] FALSE
# Apply over vectors

(x1 <- xy$x != 1)
## [1] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
(z1 <- xy$z != "d")
## [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE
x1 & z1  # you get last 3 rows
## [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE
x1 | z1 # you get all but 1st row (which contains 1 and d)
## [1] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE