第1章 初见

    有些人从没听说过R,也照样过得无比快乐,而实际上我的工作之一就是把R交给他们。快乐不等于能力和效率。有些情况下,效率对一个人的好处,比短暂的快乐要强得多。

— Patrick Burns, April 2005

    世间所有的相遇,都是久别重逢。

— 电影《一代宗师》

1.1 结缘:下载安装

R 是跨平台的开源免费自由软件,Windows、Linux、macOS都有对应的安装文件可以下载。本书均以 Windows 系统为例作介绍。截至本书成稿时,R的最新版是3.4.1,安装程序文件只有75 M。我们去R的服务器CRAN8,点击Download R for Windows,在打开的新网页最上方点击base,就找到下载链接了。下载完毕后,一路“下一步”的傻瓜式安装即可。安装完毕之后,从开始菜单中找到R,运行就可以了。

R的默认界面是控制台窗口(图1.1),展示的是代码和运行结果。在这个窗口逐条输入下面的代码,每换一次行就会执行一条。

co2
summary(co2)

我们输入的R代码很简单。第一行展示了一个名叫co2的变量,内容是夏威夷Mauna Loa观测站的大气二氧化碳浓度数据,是R自带安装的。这个数据举世闻名,我们现在常说的全球变暖、节能减排,经常会拿这个数据来说事儿。第二行计算的是co2数据的统计量,依次是最小值、第一分位数、中值、平均值、第三分位数、最大值。敲几个字母就算出这么多结果,是不是很方便?这只是R牛刀小试而已。

需要注意的是,退出R之后,这个窗口的代码不会保存。想保存的话,可以点击菜单栏的File – New script,就会出现一个新的编辑窗口,这里可以输入代码。需要执行的话,光标移到代码所在行,按ctrl+r (表示同时按住ctrl键和r键。下同)即可。编辑窗口的代码可以保存成文本文件,方便以后重复使用。

裸奔的R默认界面.

图 1.1: 裸奔的R默认界面.

不出意料的话,新手对R的第一印象一定是:怎么这么简陋!

是的,此刻的R在裸奔,虽然能用,但不好看,而且不方便。我们可以给R穿上一件衣服遮遮羞,这只需再安装一个软件就行。

思考 1.1 你还见过哪些软件,界面简陋却功能强大?哪些软件界面花哨却功能差强人意?

R能穿的免费衣服很多,人们各有所爱。我们用过Notepad++、Tinn-R、 RKward,也用过Vim配合R插件,最后选定了 RStudio,因为有诸多好处,最明显的就是把 R 常用的界面整合到了一起(图1.2)。看吧,华丽丽堪比貂皮大衣。默认有四个面板:左上面板输入代码,左下面板查看代码的运行结果,右上面板展示工作环境,右下面板显示作图结果和帮助信息。我第一次用RStudio的时候一时惊为天人,就像《天龙八部》里的段誉看见了神仙姐姐的雕像,《神雕侠侣》里的郭襄看见了摘去面具的杨过,从此不可自拔。RStudio 还有很多好处,我们以后慢慢讲。将来会发现,RStudio岂止是件貂皮大衣,简直是一栋豪华别墅。

RStudio:R的豪宅.

图 1.2: RStudio:R的豪宅.

RStudio的安装很简单。上RStudio官网9,下载安装文件 运行即可。安装完毕后运行,然后选择菜单 File – New – R script ,或按快捷键 ctrl+shift+n,会新建一个.r文件。

以后我们只需运行RStudio就行了,它会自动调用R。那个裸奔的R界面,就让它像泰坦尼克号一样永远埋葬在电脑的深处。忘了它吧。

现在,我们正式开始 R 的奇幻之旅。

1.2 第一次畅谈:计算

R最简单的功能,是用作计算器。先在左上面板窗口输入以下代码,然后按窗口上方的运行(Run)按钮,或按快捷键 ctrl+回车(这个快捷键会经常用),就会运行光标所在行的整行代码:

3 * (2 + 2)
## [1] 12

上面第一行是输入的代码示例。第二行用两个# 号开头,表示是运行结果,默认显示在RStudio的左下面板。如不另作说明,本书都用这种格式来区分代码和运行结果。我们暂时不管#号后面的[1] 是什么,先来试试R的数学基本运算符:加+, 减-,乘*,除/,乘方 ^,整除的商 %/%,整除的余数%%

Example 1.1 计算365除以7得到的整除商和余数。

下面,我们开个平方。输入并运行

9 ^ 0.5 # 开平方
## [1] 3

或者

sqrt(9)  # 也是开平方
## [1] 3

上面两条语句的作用等同,只是形式不同。这里,sqrt()是开平方的函数,被开方的数必须放在圆括号里,这是 R 语法的基本规则之一。# 号后面一直到这一行的末尾是注释,注释部分不会被运行,这样是为了方便将来理解这句代码的用途。当然,我们可以用注释随便写点什么,比如说 “# 哇塞我的第1行代码太帅了”或者“# 今天心情不大好就写到这儿吧”等等。如果你乐意,那么完全可以在注释里偷偷写一部小说,就像《倚天屠龙记》里有人在《楞伽经》夹缝处写下《九阳真经》一样。

有人读到这里,可能会退缩了:sqrt,开玩笑,我怎么记得住啊!注意 R 入门第一秘诀: 不要被 R 吓住!现在,我们请出我们的第一位人气小助理:tab键。试试只输入 s,然后按 tab 键,就会看到RStudio给出的贴心提示,所有以 s 打头的函数和变量都列在里边了,用鼠标或箭头键选取就行了。在 s 后面接着输入q之后再按tab键试试。这个“tab小助理”我们以后天天时时分分秒秒都会用。

其实,常用的函数就那么几个,用几次就不需要贴心提示了。而且函数名称都很好记,sqrt 就是 square root 的缩写,顺便练了英文。实在记不住,那就用基本运算符来求乘方好了, 9 ^ 0.5 即可。将来学了自定义函数之后,你甚至可以把sqrt改名叫做kaipingfang。我们在后面的学习中,会经常针对同一个问题给出多个解决方案,条条道路通罗马,R很灵活的,随便挑一个你喜欢的方案拿去用就行了。

小贴士 1.1 R 菜鸟入门三大秘诀

第一秘诀:不要害怕!学R非难事,谁都可以R(Anyone can R)。

第二秘诀:能用就行!只要能完成工作,R代码写得漂亮与否并不重要。如果你有两个解决办法,那就选用你熟悉的那个。将来时间有富余的话再试另一个。

第三秘诀:与人分享!如果你的R 代码是一把刀,那么分享就是磨刀,越磨越快。

常用函数都可以顾名思义:四舍五入round(), 截取整数trunc(), 开平方sqrt(),求绝对值abs(),指数函数exp(),自然对数函数 log(),以10为底的对数函数log10(),三角函数 sin()cos()tan()asin()acos()atan()等等。

有些常数在R中已经定义好了,例如圆周率\(\pi\),只要输入pi并运行

pi
## [1] 3.141593

怎么只有这几位有效数字?我上幼儿园时就背下来了,精确度不够高啊。要提高精确度,需要用选项函数option()

options(digits = 22)  # 最大支持 22 位
pi
## [1] 3.1415926535897931

option()函数运行一次后,以后的数字都会是指定的位数,直到重新运行一次,或者退出R。下面我们把位数改为默认值,7位:

options(digits = 7) 
pi
## [1] 3.141593

位数就变回来了。

有的常数,虽然没有定义好,但很容易算出来,例如自然对数的底\(e\)

exp(1)  # 计算 e
## [1] 2.718282

可以像pi一样,我们自己定义一个名叫\(e\)的变量,把exp(1)的值保存在\(e\)里,方便以后调用:

e = exp(1) 

或者

e <- exp(1)  

两种办法的赋值效果完全等同。<- 是个箭头,表示把右边的值赋给左边。如果你去看别人写的代码,会发现有人爱用箭头,有人爱用等号,这完全取决于个人喜好。箭头的灵活之处在于,可以把左边的值赋给右边:

exp(1) -> e

本书的赋值符号统一用箭头。RStudio 中输入箭头有个快捷键:按alt + _ 就行了。

思考 1.2 箭头和等号的作用完全等同吗?什么情况下只能用等号,不能用箭头?上网搜搜答案。

好了,以后可以用\(e\)来代表自然对数的底了。查看\(e\)的值,可以看RStudio的右上面板,也可以在左上面板代码窗口输入变量名\(e\),然后 ctrl + 回车,

e
## [1] 2.718282

就会在左下面板的结果窗口出现\(e\)的值。\(e\)可以用来做后续计算,比如:

x <- round(e)^2
x
## [1] 9

注意, R中大小写字母是有区别的,\(E\)\(e\)是不同的两个变量名。这叫做“大小写敏感”。

小贴士 1.2 变量名的约定(三可三不可)

:) 可以是一个或多个字母,如 ‘e’, ‘x’, ‘mydata’;

:) 可以包括数字,如 ‘a1’, ‘a2’;

:) 可以包括句点和下划线,如 ‘temperature_air’, ‘humidity.max’。

:-( 不可以包含空格,如 ‘my data’;

:-( 不可以用数字或小数开头,如 ‘2x’,‘.3y’;

:-( 不可以用中文。

此外,你的变量名不能跟R的内置变量重名。这个倒是不必担心,遇见的时候R会自动发警告。一般来说,我们只要注意变量名不要加空格,不要用中文,就不会犯大错。

    不要给你的矩阵变量取名为“矩阵”。你会给你的狗狗起名字叫“狗狗”吗?

— Barry Rowlingson, October 2004

一个变量名可以存储很多数据。比如说,本市的月降水量从一月到十二月依次是:61, 45, 55, 46, 56, 79, 86, 57, 56, 56, 57, 71 mm。可以把这十二个数据赋值给一个变量 x,这种变量叫做向量:

x <- c(61, 45, 55, 46, 56, 79, 86, 57, 56, 56, 57, 71)
x
##  [1] 61 45 55 46 56 79 86 57 56 56 57 71

如果需要查看四月的降水量,就用方括号来指定“下标”。下面方括号中的4就是下标,表示调用 x 中的第四个数值。

x[4]
## [1] 46

再比如前面提到的二氧化碳数据,变量名就是co2,这一个变量里存的是多年二氧化碳的浓度。我们可以将它转存到另一个变量里:

y <- co2 # 转存
y[10] # 看看第十个数据
## [1] 313.18

R 支持向量运算。试试输入:

x + 100
##  [1] 161 145 155 146 156 179 186 157 156 156 157 171

x 里的每一个数都加上了 100 。这就是向量运算的好处:简单的代码,避免逐个计算。

现在我们可以回答RStudio左下方窗口里显示的结果开头那个[1]了,它表示的是这一行开头显示的是x的第一个值。如果显示的向量长,需要折行,那么下一行开头的方括号里显示的就是该行第一个元素在x中的位置,省得我们从头数。

1.3 第一张留影:作图

下面,让我们作出第一个图形来:Mauna Loa观测站的二氧化碳浓度时间序列。这是张全球闻名的明星图。承接前面的数据,我们只需敲7个键就行了(图1.3):

plot(y)  # 作图
Mauna Loa 二氧化碳浓度.

图 1.3: Mauna Loa 二氧化碳浓度.

是不是很简单?有没有很激动?简单的东西人见人爱。

本市的月降水量,也可以这样画出来:因为已经保存在变量x里了,所以plot(x)就可以了。

再进一步,我们来做统计运算,看看本市月降水量的平均值是多少。

(x[1] + x[2] + x[3] + x[4] + x[5] + x[6] + x[7] + x[8] + 
   x[9] + x[10] + x[11] + x[12]) / 12  # 计算平均值
## [1] 60.41667

这个式子很长,我们把这条指令强行写成了两行,R读完第一行发现指令不完整,就会自动读下一行。由于受版式的约束,本书的代码都会采用这种换行方式。实际写代码时不必这样换行。

x的12个元素逐个敲起来太麻烦了,可以用求和函数sum()以及求向量长度的函数length(),来简化代码:

sum(x)/length(x)
## [1] 60.41667

或者直接用平均值函数mean()

mean(x)
## [1] 60.41667

更厉害的是summary()函数:

summary(x)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   45.00   55.75   56.50   60.42   63.50   86.00

得到的六个数是最小值、25%分位数、中位数、均值、75%分位数和最大值。记住summary()这个明星函数吧,将来我们会反复享受使用这个函数的快乐。

上文我们用四种方法计算平均值,算出来的结果都一样,条条大路通罗马,想起哪个用哪个。

常用统计函数有:求和sum(),平均值mean(),最大值max(),最小值 min(),范围range(),中位数median(),分位数quantile(),标准差 sd(),方差var(),总结报告summary()。你可以把这些函数用在x上,看看结果都是什么。

Example 1.2 2003 年 8 月北京城区测得的 PM2.5 的质量浓度日变化10, 从 0 时到 23 时 依次是97, 80, 64, 91, 87, 100, 128, 144, 150, 150, 150, 106, 78, 68, 62, 46, 55, 68, 84, 92, 95, 108, 128, 138 微克每立方米 。做出北京PM2.5的日变化图。计算PM2.5出现的最大值、最小值、平均值。最大值出现在几点钟?

最后,请在RStudio菜单栏点击 File-Save,或按快捷键ctrl+s,把刚才输入的代码保存到一个扩展名为.r的文件里,下一节接着用。这个.r文件 其实就是文本文件,用windows记事本打开就能看,只不过里面放的是r代码罢了。如果装了RStudio,双击 .r 文件就会用RStudio打开。

好啦,以上就是 R 的基本操作和运算、作图、统计分析,你全都掌握了! R 就差不多学完了!喝一杯庆祝一下吧。

小贴士 1.3 新手学R第一步

项目 内容
安装 CRAN, RStudio
数学基本运算符 +, -, *, /, ^, %%, %/%
常用数学函数 round(), trunc(), sqrt(), abs(), exp(),
log(), log10(), sin(), asin()
常用统计函数 sum(), mean(), max(), min(), range(),
median(), sd(), var(), summary()
作图 plot()

1.4 课外活动:表白

经过了初步的相处,你对R的印象如何?有没有相见恨晚或者一见倾心的感觉?

R 给我的印象,说得文雅一点,那就是:

    关关雎鸠,在河之洲。窈窕淑女,君子好逑。
    参差荇菜,左右流之。窈窕淑女,寤寐求之。
    求之不得,寤寐思服。悠哉悠哉,辗转反侧。

— 《诗经·国风·周南·关雎》

说得通俗一点:我想和R在一起。

跟很多理科生一样,我本科论文中使用的是Excel,硕士论文使用的是OriginLab,但博士期间换用了 R之后,从此死心塌地跟R永结同心。

那么, R 窈窕在哪里?

仁者见仁,智者见智,一千个人心中有一千个哈姆雷。R是一个取之不尽用之不竭的宝藏,我们各取所需便是。比如我,贪图便宜,看上R是看上了它的 免费 和 随心所欲 。当然,盗版的Excel,OriginLab,Matlab 也免费,但盗版毕竟是见不得光的事儿,还是少干吧。

不光免费和灵活,还有R功能的强大,R社区的友好等等。从我的角度来说,如果没有学习R和使用R带来的乐趣,那么我的博士研究生活必定会枯燥很多。几年过去了,我依然记得当年为论文做出一张图(图1.4)时的兴奋。有前人定义好的函数,花了不到一分钟,只用了一个语句,就画出了7 个变量的直方图(对角线)、两两之间的散点图和loess拟合曲线(对角线左下半部分),并标出了两两之间的相关系数(对角线右上半部分,正负用数字的颜色区别,相关程度用字体的大小表示)。那种激动和快乐,至今历历在目。

我的论文插图之一

图 1.4: 我的论文插图之一

思考 1.3 如果使用你熟悉的作图软件,那么图1.4这种图该怎么做?

我们将在第9章学习这种图的作法。

不光是论文作图,R 还能很容易做出 3D 动画来演示。不光是枯燥的科技作图和演示,R 还可以娱乐。比如可以画一颗立体中国心(图1.5)。

R绘出的中国心

图 1.5: R绘出的中国心

当然可以很容易地把国旗换成别的。写本文时正值情人节,那就换成她或他的照片好啦。这种图的作法同样是在第9章。

总地来说,我学R的理由,说得文雅一点,那就是:

    桃之夭夭,灼灼其华。之子于归,宜其室家。
    桃之夭夭,有蕡其实。之子于归,宜其家室。
    桃之夭夭,其叶蓁蓁。之子于归,宜其家人。

— 《诗经·国风·周南·桃夭》

说得通俗一点:和R在一起真好。

下面轮到你了。请勇敢表白一下:你是为什么要学R呢?


  1. CRAN:https://cran.r-project.org/

  2. RStudio:https://www.rstudio.com/

  3. 数据来源:Chan et al., 2005. Atmospheric Environment 39 (28) : 5113-5124