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 )↩