2.6 逻辑

2.6.1 逻辑值

逻辑值有三个。TRUE, FALSENA.

class(c(TRUE,FALSE,NA))
#> [1] "logical"

TRUE为真,FALSE为假,NA为未知(即真假难辨)。

2.6.2 关系运算符和简单的逻辑运算

R中常用的关系运算符有:

符号 描述
== equal to(等于)
!= equal to(不等于)
< less than(小于)
> more than(大于)
<= less than or equal to(小于等于)
>= more than or equal to(大于等于)

这些关系运算符只能用于(atomic) vectors, 不能用于其他类型的R对象;indentical()函数可以用于所有类型的对象,用来确认两者是否完全一致。

使用关系运算符进行计算,会产生逻辑值作为结果。比如:21

x <- 5
x != 3 #x等于5,所以“x不等于3”为真
#> [1] TRUE

有一些其他的运算符或函数也会返回逻辑值,比如

7 %in% c(1,4,5,6,7)
#> [1] TRUE

顾名思义,这个运算符是用来检测一个元素是否在另一个向量中。其它类型的运算符,我在需要用到的时候再讲。

有很多种运算会以NA作为计算结果,在此不一一列举。最重要的一个是:

NA == NA
#> [1] NA

这看起来像是一个bug,然而仔细想想才发现这个设计很巧妙。假设你问我是否知道我的一些朋友写完了暑假作业。我说我不知道张三是否写完了,也不知道李四是否写完了。你再问我“张三和李四的作业完成情况是一样的吗”?鬼才知道咧!

这意味着不能直接使用x == NA来判断x是否是NA,而要用is.na()函数:

x <- NA
is.na(x)
#> [1] TRUE

关系运算符具有的向量化的性质。也就是说,用于长度大于1的向量时,会返回一个同等长度的逻辑向量,且这种运算速度极快。

x <- c(2, 1, 6, 5, 4, 9, 7, 3, 10, 8)
x <= 5
#>  [1]  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE

像这样与某向量等长的逻辑向量可以用于那个向量的取子集:

x[c(TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE)]
#> [1] 2 1 5 4 3

更常见的用法是使用关系运算作为索引:

x[x <= 5]
#> [1] 2 1 5 4 3

有时候,你可能不需要向量化的计算,只需要一个TRUEFALSE. all()any()或许能帮到你。顾名思义,all()测试的是“是否全部为TRUE”,any()测试的是“是否至少有一个TRUE”:

all(x <= 5); any(x <= 5)
#> [1] FALSE
#> [1] TRUE

2.6.3 逻辑运算符

以下是最常用的三个逻辑运算符。

符号 描述
& AND(且)
| OR(或)
! 反义符号

2.6.3.1 反义符号(!

!使TRUE FALSE颠倒。一般,我们用小括号来包住一个逻辑运算,然后在它的前面加上一个!来反转结果,比如

!(3 < 4) # 这个例子很简单,反义符号意义不大。后面实操的时候才能领略到它的用处。
#> [1] FALSE

2.6.3.2 多个逻辑运算的组合(&(且)和|(或))

&|可以把多个逻辑运算的结果合并成一个逻辑值。

&判断是否两边运算结果都为TRUE。如果是,才会得到TRUE(即一真和一假得到假)。

|判断两边运算结果是否至少有一个 TRUE,如果是,就会得到TRUE

不用死记硬背!其实就是“且”和“或”的逻辑。

用脑子想一下以下三条运算的结果,然后复制代码到R console对答案。

1 == 1 & 1 == 2 & 3 == 3 #即:“1等于1且1等于2且3等于3”,是真还是假?
FALSE | FALSE | TRUE # FALSE/TRUE等价于一个运算结果
!(FALSE | TRUE) & TRUE # 注意反义符号

我们可以查看三个逻辑值所有两两通过&组和的计算结果(如果你不感兴趣,可以不关注方法。这里重点是结果):

vals <- c(TRUE, FALSE, NA) 
names(vals) <- paste('[',as.character(vals),']',sep = '')
outer(vals, vals, "&")
#>         [TRUE] [FALSE]  [NA]
#> [TRUE]    TRUE   FALSE    NA
#> [FALSE]  FALSE   FALSE FALSE
#> [NA]        NA   FALSE    NA

可以看到,FALSE与任何逻辑值组合,结果都是FALSE。这个好理解,因为一旦一个是FALSE,那么不可能两边都是TRUE. TRUE & NA之所以为NA(而不是FALSE),是因为NA的意思是“不能确定真假”,即有可能真也有可能假。因此TRUE & NA也无法辨真假。

再来看|的组合:

outer(vals, vals, "|")
#>         [TRUE] [FALSE] [NA]
#> [TRUE]    TRUE    TRUE TRUE
#> [FALSE]   TRUE   FALSE   NA
#> [NA]      TRUE      NA   NA

可以看到,TRUE与任何一个逻辑值组合,都是TRUE,而FALSE | NANA。原因一样(因为NA的不确定性)。


  1. 尽量避免直接对浮点数进行比较。COS版主都要被逼疯了(https://d.cosx.org/d/106794-106794/3