R 菜鸟入门篇 第06篇 分支

顺序、循环和分支是编程的三大结构。上一篇说了循环,这一篇说说分支。啥是分支?分支就是你到了一个路口,向左向右向前看,要选择到底往哪个方向走。每时每刻我们都要做出选择:渴了,是喝咖啡还是茶?见了人,是上去打招呼还是悄悄躲开?这篇帖子,是关掉还是继续读下去?其实仔细想想,岂止是编程,那三大结构简直就是整个生活的基本结构:日出日落,月圆月缺,年尾年头,这是循环;上学还是就业,单身还是结婚,丁克还是生娃,这是分支;不管是循环还是分支,都嵌入在生老病死的时间轴上,这是顺序。所谓尽人事听天命,想来就是心平气和地接受顺序结构,小心翼翼地制订循环结构,在关键时刻控制好分支结构,就这样度过一生罢。

扯远了。简单来说,分支就是先判断再选择。

先判断。判断要用逻辑运算。我们先来做一套健脑操热热身:

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

plot of chunk unnamed-chunk-7

有用的信息:

逻辑运算 > < == <= >= & !
分支命令 if () {}, if () {} else {}, ifelse()

( 连载中,待续 )

原文链接

comments powered by Disqus