2.6 逻辑
2.6.1 逻辑值
逻辑值有三个。TRUE
, FALSE
和NA
.
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
有时候,你可能不需要向量化的计算,只需要一个TRUE
或FALSE
. 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 | NA
为NA
。原因一样(因为NA
的不确定性)。
尽量避免直接对浮点数进行比较。COS版主都要被逼疯了(https://d.cosx.org/d/106794-106794/3 )↩