顺序、循环和分支是编程的三大结构。上一篇说了循环,这一篇说说分支。啥是分支?分支就是你到了一个路口,向左向右向前看,要选择到底往哪个方向走。每时每刻我们都要做出选择:渴了,是喝咖啡还是茶?见了人,是上去打招呼还是悄悄躲开?这篇帖子,是关掉还是继续读下去?其实仔细想想,岂止是编程,那三大结构简直就是整个生活的基本结构:日出日落,月圆月缺,年尾年头,这是循环;上学还是就业,单身还是结婚,丁克还是生娃,这是分支;不管是循环还是分支,都嵌入在生老病死的时间轴上,这是顺序。所谓尽人事听天命,想来就是心平气和地接受顺序结构,小心翼翼地制订循环结构,在关键时刻控制好分支结构,就这样度过一生罢。
扯远了。简单来说,分支就是先判断再选择。
先判断。判断要用逻辑运算。我们先来做一套健脑操热热身:
3 > 2 # 3比2大吗?是的。
## [1] TRUE
1 > 2 # 1比2大吗?不是的。
## [1] FALSE
!(1 > 2) # 1不比2大吗?呃......
## [1] TRUE
3 > 2 & 1 > 2 # 3比2大,并且1比2大吗?不是的。
## [1] FALSE
3 > 2 | 1 > 2 # 3比2大,或者1比2大吗?是的。
## [1] TRUE
3 > 2 & !(1 > 2) # 3比2大,并且1不比2大吗?好像是吧......
## [1] TRUE
好了,热身完毕。包括上面出现的,常用的逻辑运算符有:大于 >, 小于 <, 等于 ==, 小于或等于 <=, 大于或等于 >=, 与 &, 非 !, 或|
。
逻辑运算符用在向量上:
x <- 1:3
x == 2
## [1] FALSE TRUE FALSE
x == 2 | x == 3
## [1] FALSE TRUE TRUE
y <- c(4, 1, 2)
x > y
## [1] FALSE TRUE TRUE
x > y & y > 1
## [1] FALSE FALSE TRUE
练习06.1 设 x <- 6:1,y <- c(3, 5, 7),判断 x 中的每个元素是否在y中出现。
上面这个练习可以用循环来完成。不过,由于 R 很照顾懒人,所以提供了更方便的方法:
x %in% y
## [1] TRUE TRUE FALSE
结合逻辑判断和下标系统,就可以挑出 x 中哪些元素出现在 y 中,以及出现的位置:
x[x %in% y]
## [1] 1 2
which(x %in% y)
## [1] 1 2
练习06.2 从 1:100 中挑出既能被 2 整除,又能被 3 整除的数(提示:判断整除的余数是否为零)。
下面,我们玩玩真实的观测数据。练习01.4 曾经提出个问题:PM2.5 一天中的最大值出现在几点钟?当时需要肉眼判断,现在可以交给机器了。
pm <- read.csv("c:\\R\\data\\dapengde_DummyR_PM25.csv")
pm$time[which(pm$h8 == max(pm$h8))]
## [1] 8 9 10
练习06.3 世界卫生组织制订的 PM2.5 指导标准中最宽松的标准是 24 小时均值 75 微克每立方米。请挑出北京一天内超出此标准的时段。
上面讲的是分支两部曲的第一步:判断。下面说说第二步:选择。
x <- 12
if (x < 99) print("x is less than 99") # 如果(),那么。
## [1] "x is less than 99"
x <- 12
if (x < 99) {
print("x is less than 99")
} else {
print("x is larger than 99")
} # 如果(),那么{},否则{}。
## [1] "x is less than 99"
x <- 12
ifelse(x < 99, "small", "large") # 等同于上一个例子,不同的是这里 x 的向量长度可以大于1,比如试试 x <- 98:100。
## [1] "small"
有了分支语句,就可以在很多地方派上用场了。继续以北京 PM2.5 日变化数据作图,把一天中的最大值重点标出来,然后把达标值用绿色区分出来:
plot(x = pm$time, y = pm$h8, xlab = "Time", ylab = "PM2.5", cex = ifelse(pm$h8 ==
max(pm$h8), 2, 1), pch = 16, type = "b", col = ifelse(pm$h8 > 75, "red",
"darkgreen"))
有用的信息:
– | – |
---|---|
逻辑运算 | > < == <= >= & ! |
分支命令 | if () {}, if () {} else {}, ifelse() |
( 连载中,待续 )