第 1 章 R 基础

第 1 章 R 基础

1.1 下载软件

首先需要下载免费的 R 软件,并安装在你的计算机上。启动计算机,打开 Web 浏览器,通过网址 http://www.r-project.org 访问统计计算的 R 项目(R Project for Statistical Computing)。点击 download R,然后选一个距离你所在地理位置较近的镜像站点。(R 软件存储在世界各地的许多计算机上,而不是一台计算机上。因为它们都包含相同的文件,看起来一样,所以被称为“镜像”网站。你可以选择其中任何一台计算机。)点击网站地址,将打开一个页面,可以根据你的操作系统选择 R 的版本。如果你的计算机可以运行最新版本的 R——3.0 或更高版本——那再好不过了。然而,如果你的计算机用了几年了,不能运行最新的版本,那就选计算机可以运行的最新版本。也许会和本书中的例子有一些小的差异,但应该可运行大多数例子。

按照说明,在短时间内就可安装好 R。这是基础 R(base R),但 R 有数千个(这不是夸张)插件“包”。完成 R 的基础安装后,你可以免费下载插件来扩展 R 的功能。根据你的需要,也可能不需要添加任何插件,但是你可能会很惊奇地发现一些你想象不到但必须拥有的功能。

1.2 尝试一些简单的任务

若你使用的是 Windows 或 OS X 系统,单击桌面上的“R”图标即可启动 R。若使用的是 Linux 或 OS X 系统,在终端窗口输入命令 R 可打开控制台(console)。在控制台窗口输入命令,可看到许多命令的结果,尽管在大多数情况下,创建图形的命令将打开一个新窗口来展示结果图。R 可接受命令时,会显示一个大于符号(>)作为提示符。R 最简单的应用是计算器。在提示符后,输入一个你想要获得答案的数学表达式:

>12/4
[1] 3
>

此处,我们请求“12 除以 4”。R 返回“3”,然后显示另一个提示符“>”,表明可以输入下一个命令。返回值前的 [1] 是一个索引(index),在本例中,它只是表明返回值从向量(vector)中的第一个数开始。本例中只有一个值,但有时会有多个值,所以了解数据集合从哪里开始会有帮助。如果你不理解索引,现在也不用担心;看到更多的例子后,你将更清楚。除法符号(/)叫作操作符(operator)。表 1-1 给出了标准算术运算符的符号。

表1-1:R算术运算符

运算符

运算

举例

+

加法

3 + 4 = 73+4(即无空格)

-

减法

5 - 2 = 3

*

乘法

100*2.5=250

/

除法2

0/5= 4

^**

3^2 = 93**2 = 9

%%

取余

5%%2 = 15/2=21

%/%

除法,向下取整

5%/% = 25/2=2.5,向下取整等于2

你可以像在普通算术中那样使用括号,以表明操作的执行顺序:

> (4/2)+1
[1] 3
> 4/(2+1)
[1] 1.333333

尝试另一个例子:

> sqrt(57)
[1] 7.549834

这次通过函数(function)来完成运算,本例用的是 sqrt() 函数。表 1-2 列出了一些常用的算术函数。

表1-2:常用的R数学函数

函数

运算

cos()

余弦

sin()

正弦

tan()

正切

sqrt()

平方根

log()

对数

exp()

指数函数

sum()

求和

mean()

均值

median()

中间值

min()

最小值

max()

最大值

var()

方差

sd()

标准差

调用函数时可带参数(argument)。参数是一种修饰符,与函数一起使用时可以用更多特殊的方式请求R。因此,可能会请求计算特定数字的和,而不是单单请求sum函数;或者,你可以使用参数来指定线的颜色或宽度,而不是简单地在图上画一条线。单个或多个参数,必须在函数名后用括号括起来。当使用函数或任何R命令时,如果需要帮助,可使用如下方式寻求帮助:

> help(sum)

R 将打开一个新窗口,显示要查找的指定函数及其参数的信息。如下命令是一个快捷方式,可得到完全相同的响应:

> ?sum

请注意,R 是区分大小写的,所以“help”和“Help”是不同的!然而,空格无关紧要,因此上面的命令也可写为:

> ? sum

有时,函数中只有一个参数,比如 sqrt() 的示例。其他情况下,一个函数作用于一组数字,称为向量,如下所示:

> sum(3,2,1,4)
[1] 10

本例使用 sum() 函数计算 3、2、1、4 的和。但不可能总是像这个例子一样,把所有的值写入函数表达式。因此,通常需要先创建向量,如下所示:

> x1 <- c(1,2,3,4)

输入这个命令后,什么也没发生!你确实看到什么也没有发生。一旦出现由“<”和“-”两个符号组成的特殊操作符,操作符右边的值就会赋给左边的变量。(R 的较新版本允许使用“=”号来完成赋值。第 1 章以后,我们也将使用这种较简单的形式。)在这种情况下,创建一个新的向量,用户称其为 x1。R 是一种面向对象语言(object-oriented language),向量 x1 是工作区中的一个对象(object)。

什么是“对象”

将对象想象为一个盒子,其中装满了彼此关联的项。这些项可以是简单的数字、名称、统计分析的结果、这些项或其他项的组合。对象有助于以结构化的方式组织事物,将彼此相关的东西封装在同一个盒子里,无关的东西封装在其他盒子里;对象可以告诉R在其中有哪些项,以便 R 合理地操作特定对象中的项。向量是一类包含相同类型数据(都是数字或者都是字母)的对象。对象可以包含其他对象。毕竟,你可以把一个盒子放入一个更大的盒子里。因此,可以把一个或多个向量放入一个数据框(data frame),数据框是另一种类型的对象。输入命令 ls(),可以查看当前工作区有哪些对象。

创建一个新的向量,需要在向量数据的括号前输入字母“c”。创建后输入以下命令看看会发生什么:

> x1

已经用 x1 为名保存了一组数字 1、2、3、4。输入向量的名字就可打印出 x1 的值。你可以随时请求 R 对该向量执行各种操作。例如,输入如下命令:

> mean(x1)

返回(return)向量 x1 中数字的均值,打印到屏幕上。利用表 1 - 2 中的其他运算符可以了解 R 可以做的其他事情。

创建另一个对象,这次创建仅有一个数字的对象:

> pt <- 3.14

任何时候想获得当前工作区中所有对象的列表,可使用如下命令:

> ls()

并且,在新的计算中可以使用任何一个或所有对象:

> newvar <- pi*x1

这样就又定义了一个名为 newvar 的对象。

1.3 用户界面

目前为止看到的示例都是命令行指令(command-line instruction),也就是说直接输入命令告诉 R 做什么。这不是与 R 交互的唯一方法,R 的基础安装也具备图形用户界面(graphical user interface,GUI)功能。GUI 指的是点击式的图形界面,你很可能已在其他应用程序中见过。但问题是,安装的每类操作系统——Windows、OS X 和 Linux——的 GUI 功能是存在差别的。相比其他系统,OS X 的 GUI 更友好一点,也许你很快就能知道,也更喜欢以这种方式发出很多命令。无论使用哪款操作系统,控制台窗口的顶部均有一个菜单。在输入重要的数据之前,可以简单试一下,看看有哪些点击式操作可用。

由于三种操作系统(Windows、OS X 和 Linux)的 R 命令行界面是相同的,因而本书使用命令行界面(command line interface)。这样只需一种解释,你就可以轻松地从一台计算机转移到另一台。列举代码(code),即一系列命令行,比试图解释每一个选择按钮和鼠标点击要容易得多。此外,使用命令行学习 R,有助于你更好地理解软件的逻辑。最后,命令语言比界面点击更精确,并能给予用户更强的操控力。

1.4 安装包:GUI界面

无论你使用的是什么操作系统,都可以下载一个免费的“前端”(frontend)程序,它将提供一个 GUI。有几个可用的“前端”程序。在对 R 有了更多的了解,并欣赏了其强大的用途之后,你可能就会尝试一个 GUI 接口了。例如,早些时候我提到有大量包可用,你可以将其添加到 R,其中一个设计不错的 GUI 名为 R Commander。在联网的情况下,用下面的命令:

> install.packages("Rcmdr", dependencies=TRUE)

R 会下载这个包及 R Commander 正常运行所依赖的其他包。包将永久保存在你的计算机上,所以不需要再重新安装。每次要使用 R Commander,都需要按如下方式加载(load)包:

> library(Rcmdr)

每个人的喜好不同。有些人认为命令语言很好;另一些人则不喜欢 R 的命令行界面,觉得正是 R Commander 使 R 成为他们最喜欢的计算机工具。使用 R Commander 能生成本书中的许多图,但不能生成所有的图。如果你想尝试 R Commander,可在附录 C 中找到更多信息。

检索所有可用的包,可使用如下命令:

> available.packages()

在 CRAN 任务视图中,你可以学到更多关于这些包的主题,地址为:http://cran.r-project.org/web/views/

访问 http://cran.r-project.org/web/packages/available_packages_by_name.html,可以看到所有按包名排列的包的列表。

获得刚刚下载的包的帮助,可输入以下命令:

> library(help=Rcmdr)

错误信息

当输入一个错误命令时,将不会看到预期的结果,而是看到一条错误信息,它不一定能提供帮助!附录 G 就如何处理最可能出现的错误类型提供了指导。

1.5 数据结构

你可以把数据写入各种结构的对象。我们已经使用过向量这一类型的结构。可以把向量看作一维的一行元素或一列元素。向量可以包含任意多的元素,计算机的内存可以容纳多少,向量就可容纳多少。向量中的元素类型可以是数值型(numeric),或者包含字母、数字和特殊字符的字符型(character),或者包含 TRUE(真)或 FALSE(假)值的逻辑型(logical)。向量的所有元素必须是相同的类型。下面是一些创建向量的例子:

> x <- c(14,6,7,5.1,-8)  # 数值型
> name <- c("Lou", "Mary", "Rhoda", "Ted")   # 字符型/需要引号
> test <- c(TRUE, TRUE, TRUE, FALSE, TRUE)   # 逻辑型/需要大写

 符号 # 后面是注释,供我们阅读的信息或注意事项,但 R 会忽视这些注释(作为一名音乐家,我更喜欢称这个符号为升半音号)。给代码写注释是一个好习惯,以后回头再看代码时,这有助于你想起为什么做某一件事,并帮你解决问题或根据一个好主意来扩展代码。阅读本书中 R 示例代码的注释,也是个不错的主意。

数据框(data frame)是我们将使用的主要结构。它是一个二维的对象,有行和列。你可以把它视为其中有列向量的盒子,或一个有行和列的矩形数据集(rectangular dataset)。为了更好地理解,参见下一节的样本数据集及把二氧化碳排放数据读取到 R 的练习。数据框可以包含所有相同类型的列向量或任何类型的组合。

R 还有其他数据结构,比如矩阵、数组、列表,这里不做讨论。

可以使用 str() 方法查看给定对象的结构(structure):

> str(x)
 num [1:4] 14  6.7  5.1  -8

> str(name)
 chr [1:4] "Lou" "Mary" "Rhoda" "Ted"

> str(test)
 logi [1:5] TRUE TRUE TRUE FALSE TRUE

1.6 样本数据集

基础 R 包含一些样本数据集,这将有助于我们通过实例去了解图形工具。要想知道你的计算机上有哪些可用数据集,可输入如下命令查看:

> data()

确保空括号放在命令之后,否则你将得不到预期的结果。还有很多可用的数据集。几乎所有附加包均有样本数据集。只需使用帮助命令,就可以查看基础 R 包或者已经下载的包中特定数据集的描述。例如,要获得 airquality 数据集的信息——简介、来源、参考文献等,可输入以下命令:

> ?airquality

通过使用如下命令,可查看数据集中前 6 组观测值:

> head(airquality)

  Ozone Solar.R Wind Temp Month Day
1    41     190  7.4   67     5   1
2    36     118  8.0   72     5   2
3    12     149 12.6   74     5   3
4    18     313 11.5   62     5   4
5    NA      NA 14.3   56     5   5
6    28      NA 14.9   66     5   6

该数据集是个数据框,有 153 行数据,每行代表了一天中空气质量的测量值(臭氧、R 太阳能和风力等)。head() 命令默认打印出变量名及前 6 行数据,以便我们可以查看数据情况。若要查看不同行数的数据,比如 25 行,可使用如下方式:

> head(airquality,25)

若要查看数据集的最后 4 行数据,可输入如下命令:

> tail(airquality,4)

每行数据有行号和 6 个变量的值,这些值是一天的测量值。第一行或者说第一天的值,有 1411907.46751。第一个变量是臭氧,前 6 天的值为 41361218NA28。这是一个关于矩形数据集或者平面文件(flat file)的例子。大多数统计分析程序需要这种格式的数据。

注意,在数据集的数据中,你可能会看到 NANA 是标准的 R 符号,表示“不可用”或“丢失”。可以用多种方式处理这些值,一种方式是删除存在一个或多个缺失值的行,并和其他所有行做计算;另一种方式是不做计算,并返回一条错误信息。一些程序可以让用户指定使用哪种方式。也可以为缺失值插补(impute),即估值,并在计算中使用估值。处理缺失值是一个复杂且有争议的话题,不能掉以轻心。关于如何处理 R 的缺失值,Kabacoff(2011)中有一章做了很好的介绍。

有两种访问数据的方式。第一种方法是使用 attach() 命令,输入一些带变量名的命令,然后输入 detach() 命令,如下例所示:

> attach(airquality)
> table (Temp)              # 获得Temp值的数量
> mean (Temp)               # 寻找Temp的均值
> plot(Wind,Temp)           # 绘制Wind和Temp的散点图
> detach(airquality)

这种方法的优点是,如果要执行多个步骤,没有必要一遍又一遍地输入数据集名。第二种方法是用数据集名和变量名的组合,并用美元符号($)分隔,来指定任何你想做的分析。例如,如果想执行如下命令:

> attach(airquality)
> plot(Wind,Temp)
> detach(airquality)

就可以执行如下的等效代码:

> plot(airquality$Wind,airquality$Temp)

这种方法的优点是,如果连续请求多个数据集,就不用使用多个 attachdetach 语句。

1.7 工作目录

使用 R 时,经常需要把数据从文件读到 R,或者将 R 数据写入文件。例如,你可能有些数据是由电子表格、SAS 和 SPSS 等统计软件包或文本编辑器创建的,想要用 R 分析。或者你常会创建一个 R 数据集,保存并再次使用它。这些文件必须存储在计算机的文件结构中。对于每个读写操作,可以指定一个明确(通常很长)的路径,指向包含你想要读取的数据的文件或你想要写入数据的地方。这样可能比较麻烦,因此 R 有工作目录(working directory),即文件的默认位置。换句话说,如果不告诉 R 在哪里找某个特定的文件,它会默认在工作目录中查找。同样,如果不指定保存数据的位置,R 将自动写到工作目录。可以用如下命令查看当前工作目录:

> getwd()

假设获得的返回结果如下(当然实际结果是完全不同的):

[1] "/Users/yourname/Desktop/"

若不指定其他位置,R 则会在一长串名称的最后一个文件夹(即右边最后一个名字)查找文件和写入文件。使用 setwd() 命令,可以改变工作目录。为使用 R,或者专门为了本书的练习,你可能想创建一个新文件夹,其名字要清楚表明目的,如 R folder 或 R graphical data。假设你已经在 Desktop 目录内创建了一个名为 R things 的文件夹,可以输入以下命令:

> setwd("/Users/yourname/Desktop/R things")

这样,R 将把 R things 目录作为你的工作目录,直到下次使用 setwd() 命令,或输入 q()(quit)关闭 R。如果不想每次启动 R 时都设置工作目录,在 1.9 节中学习如何实现这一点。

1.8 将数据导入R

现在,你已经知道怎么使用各种 R 包的样例数据集了。这是学习使用 R 的丰富资源,但是,你学习 R 是因为想对自己的数据做图形分析。选择哪种方法把数据导入 R,取决于以下几个因素:

  • 数据集有多大

  • 数据是否已经以某种数据文件的形式存在

  • 使用 R 之外的其他工具的舒适度

  • 你得在数据输入上投入多少时间

  • 自身的痛苦阈值

初学者注意

接下来三节展示了多种输入数据的方法。如果你是一个初学者,觉得这几节内容太难,可以先读1.8.1 节,然后尝试解决一个简单的输入数据的问题,如本章最后的练习 1-4;稍后再返回到“使用数据编辑器”(1.8.2 节)和“从外部文件读取”(1.8.3 节)。事实上,做完练习 1-4 之后,可以直接进入第 3 章,然后当需要相关信息时,再开始阅读 1.8.2 节,直到读完第 2 章。

如果你对数据输入不是特别感兴趣,而是希望使用已经创建好的数据集,比如电子表格、统计软件包数据集、ASCII 文件或其他类型的数据文件,可以略过本节余下部分,直接参考附录 E 来查阅你感兴趣的数据文件类型。

1.8.1 命令行输入

将数据输入 R 的最直接的方法,是从命令行输入表达式,如前文操作过的——创建向量。如果你需要的是分析一个或几个特别短的向量,这种方法最简单。

练习1-1

Backblaze 是一家数据备份公司,运行着大约 25 000 个磁盘驱动器并报告硬盘存活率(单位为 %)。下列数据显示了驱动器的年度存活率(数据来源于 https://www.backblaze.com/blog/how-long-do-disk-drives-last/):

year  rate
1   94    # (比如,一年之后,94%的驱动仍在工作)
2   92
3   90
4   80

使用如下命令创建两个向量:

> year <- c(1,2,3,4)
> rate <- c(94,92,90,80)

确保以正确的顺序输入数字。例如,如果 1year 向量的第一个值,那么 94 必须是 rate 向量的第一个值,以此类推。可使用下面这个命令分析这两个向量之间的关系:

> plot(year,rate)

大多数图形命令会打开一个新窗口。如果你开启多个应用程序,可能会丢失当前的命令并被迫去寻找它。

上面代码片段中的 plot 语句调用 plot() 函数,令其对 yearrate 两个参数进行分析。刚刚绘制的是一个简单的图表,但用 R 也可制作非常复杂精美的图表。图 1-1 中的右图展示了一些自定义基础图的方法。在本书中我们将介绍许多这样的选项。输入 ?plot 命令,查看可用的选项列表。

{%}

图 1-1:左图表示磁盘驱动器存活率与使用年数,是由简单的命令 plot(year,rate) 生成的。右图是自定义的,需要很多的选择。你发现了多少差异?

可以把 yearrate 两个向量合并到一个新的数据框 mydata,如下所示:

> mydata <- data.frame(year, rate)

1.8.2 使用数据编辑器

如果数据只是稍微复杂或者数据量稍大,可以使用 R 控制台中简单的数据编辑器。即使不使用这种方式录入数据,了解一下编辑器也不错,因为有朝一日你可能需要解决 R 工作区中的临时问题数据点。我认为,对大多数人来说,努力尝试使用数据编辑器输入数据是不必要的。阅读本节了解一些术语,并看一下如何保存文件即可。你可能更愿意使用最喜欢的电子表格来录入数据,但是如果没有电子表格,可能就需要使用编辑器。阅读 1.8.3 节来了解如何从电子表格读取数据到 R。

练习1-2

表 1-3 中给出的数据(来自美国能源信息管理局)是近 8 年间全球二氧化碳的排放量。你将使用 R 内置的数据编辑器将它输入 R。先来看看这个数据集的内容。

表1-3:按世界地区划分,从能源使用角度的二氧化碳人均排放量(以人均二氧化碳吨数计)

年份

北美

中南美

欧洲

欧亚大陆

中东

非洲

亚洲/大洋洲

2004

16.2

2.4

7.9

8.5

7.1

1.1

2.7

2005

16.2

2.5

7.9

8.5

7.6

1.2

2.9

2006

15.9

2.5

7.9

8.7

7.7

1.1

3.1

2007

15.9

2.6

7.8

8.6

7.6

1.1

3.2

2008

15.4

2.6

7.7

8.9

7.9

1.2

3.3

2009

14.2

2.6

7.1

8

8.3

1.1

3.5

2010

14.5

2.7

7.2

8.4

8.4

1.1

3.6

(来源:http://1.usa.gov/1R6sj99

表 1-3 中第一行是标题(header)信息,命名记录的每个变量。每行包含一年中收集到的所有信息。每一行被称为一个统计单元(statistical unit)。社会学家通常把一行称作一个实例(case),而自然科学家的一行很多时候指的是观测(observation)。计算机专业人士通常把一行称为一条记录(record)。每一列为一个变量,在计算机科学中为一个字段(field)。排放数据集有 7 行(观测值),共 8 个变量:年份及所研究的 7 个地区各自的排放总量。

编辑器看起来像电子表格,并拥有一些良好的电子表格的特性,但不如 Excel 或 Numbers 使用方便,而且一不小心很容易丢失变更信息。一开始,需要选择对象名称,用该名称定义一个新的数据框。实现这一点有几种方法。我觉得最安全的方法是为每个变量命名、确定其类型并指定行数。代码如下:

> emissions <- data.frame(Year=numeric(7),N_Amer = numeric(7),
CS_Amer=numeric(7), Europe=numeric(7),Eurasia=numeric(7),
Mid_East=numeric(7),Africa=numeric(7), Asia_Oceania=numeric(7))

以上代码创建了一个名为 emissions 的空数据框。调用 edit() 函数,指定一个对象来保存空数据框,这样就打开了编辑器,命令如下:

> emissions <- edit(emissions)

请记住,emissions 是空的。通过调用前面命令中的 emissions 对象,告诉 R 用你输入的任何编辑过的数据覆盖空数据框。双击你想输入 / 编辑数据的单元格,输入数据。完成编辑后,在 OS X 系统中点击电子表格左上角或在 Windows 系统中点击右上角的“X”。不要点击 Stop,OS X 系统中的 Stop 在编辑窗口,Windows 系统的 Stop 在屏幕的顶部。一旦点击 Stop,将丢失所做的全部修改。输入数据后,仔细检查以确保没有错误。如果发现错误,就双击想要修改的单元格,然后输入正确的数据。如果有必要的话,可以使用前面的命令再次回到编辑器来修改。为了以后不需要重新输入,就可以再次使用数据框,可使用下面的命令保存这个数据框:

> save (emissions,file="emiss.rda")

这行命令把 emissions 数据框写入工作目录中的 emiss.rda 文件。假设你仍在同一工作目录中,可以使用以下命令读取数据:

> load("emiss.rda")

1.8.3 从外部文件读取

你可能已经有一个最喜欢的输入数据的工具了,对许多人来说,这个工具可以是电子表格程序,也可以是文本编辑器。我喜欢 Mac 上的 Numbers,当然 Excel 或者其他电子表格也不错。通常的做法是,在电子表格程序中创建文件,并将其保存到工作目录。文件存在工作目录以后,就可以将其读取到 R 并进行分析。

练习1-3

多产的英国作曲家爱德华 · 埃尔加(1857—1934)有两个(也许是)最著名的作品:一个是 Pomp and Circumstance(《威风堂堂进行曲》),它是无数毕业典礼上播放的进行曲;另一个是交响乐 Enigma Variations(《谜语变奏曲》)。虽然完整的 Enigma Variations 是交响乐演出中受欢迎的部分,但非常优美的第 9 首 Nimrod 变奏曲通常单独演奏,不仅由管弦乐队,还由其他的合奏者(音乐团体)或独奏者演奏。

在演奏音乐作品之前,一定要问的一个最基本的问题是:“节奏应该是什么样的?”换句话说:“应该以多快的速度演奏?”虽然作曲家通常会给出指示,但是一些作品已经得到了广泛的解释,甚至在最德高望重的音乐家之中,解释也不一样。学习其他音乐家如何演奏这一作品,对策划个人表演是很有指导意义的。表 1-4 中呈现的 Nimrod 节拍数据来自很多表演记录,我是 2013 年 11 月 9 日在 YouTube 上找到的这些表演。

表1-4:不同团体演奏Nimrod的时间

表演者

媒介

时间

水准

Barenboim-Chicago SO

so

240

p

Solti-London Phil

so

204

p

Davis

so

270

p

Remembrance2009

cb

236

p

Belcher

org

254

p

Bish

org

232

p

ColdstrGuards

cb

239

p

Pallhuber-3 Lions BB

bb

257

a

Bernstein-BBC

so

315

p

Dudamel-SBolivarSym

so

239

p

John

org

252

p

Sunshine Brass

bb

186

a

Mahidol Sym Band

cb

173

a

Hills

org

240

p

Grimethorpe CollB

bb

200

p

Barbirolli_Halle O

so

200

p

Stokowski

so

244

p

Boult-London SO

so

211

p

Kindl-Marktoberdorfer BB

bb

238

a

Carter-Charlotte CB

cb

196

a

Cord-IndianaU

bb

188

a

Mack-SUNYFredonia CB

cb

160

a

U Akron CB

cb

193

a

Akron Youth Sym

so

188

a

BP-Ostwestfalen

cb

198

a

Santarsola-MoldovaPO

so

320

p

Klumpp_NWD PO

so

187

p

Burke-MancunianWinds

cb

257

a

US Army Field Band

cb

235

p

EE-Phonograph

so

186

p

Niemczyk-NWC O

so

169

a

Allentoff-Brockport SO

so

200

a

Nimrod 数据集有 32 行(实例 / 观测值)和 4 列(变量)。此数据将成为 R 的数据框。

Nimrod码本

除了最简单的数据集外,所有数据集都需要一个“码本”,它解释了变量的每个值的含义。Nimrod 数据集的码本如下:

performer表演者

  若有,为指挥和乐团的名字。必须至少纳入一个可用的名字以供研究。

medium媒介

  bb 铜管乐队(brass band)

  cb 管乐队(concert band)

  org 管风琴独奏(organ solo)

  so 交响乐团(symphony orchestra)

time时间

  从第一个音符到最后一个音符的表演时间,以秒为单位,去掉预告、调音、鼓掌等时间。可替代的测量节奏的办法,即假定自始至终节奏相同。

level/proficiency level of the performers水平/表演者的水平

  a 业余(或学生)

  p 专业

time 变量是一个定量变量(quantitative variable);也就是说,它是总数的度量。算术中可以使用定量变量,所以可以计算 time 变量的总和或平均值。这些是 R 的数值向量,正如 1.5 节讨论的那样。这个数据集中的其他变量都是分类变量(categorical variable),即分成类的观测值。有些人将分类变量称为定性(qualitative)或名义(nominal)变量。这些是 R 的字符向量。由于 bbcb 等不是数字,所以我们不能计算 medium 的平均值,计算甚至没有意义。但是,关于分类变量,有一些事情我们可以做,比如找出 bbcb频率(frequency)。我们也可以使用分类变量的值来分组。例如,根据 level 变量的值把数据集分成很多部分,从而比较业余组和专业组的平均时间。

可以用下列方式中的任意一种来输入数据:

  • 把数据输入到你最喜欢的电子表格程序中,并以 .csv 文件格式将电子表格保存(导出)到你的工作目录,命名为 Nimrod.Tempo.csv。R 可以读其他文件类型,但 .csv 格式文件最简单,也最不容易出错。然后打开 R 并输入如下命令:

    > Nimrod <- read.csv("Nimrod.Tempo.csv",header=TRUE)
    
    

    若要读取没有标题的文件,则使用 header=FALSE

  • 如果想读取 Excel 文件而不将其转换为 .csv 文件,有一个名为 XLConnect 的包可用。Xlconnect 可以执行很多其他任务,如编辑电子表格,以及把 R 数据写到 Excel 文件。如果你用的是旧版本的 R(3.0 之前的版本),那么无法使用这个包。下面的代码演示了当 Nimrod 数据被保存为 Excel 文件格式并以 Nimrod.xls 命名时,如何读取 Nimrod 数据:

    >install.packages ("XLConnect")
    >library (XLConnect)
    >Nimrod2 <-readWorksheetFromFile("Nimrod.xls",
     sheet = 1, header = TRUE)
    
    

    如果命令的长度超过一行怎么办

    如果需要执行的命令太长(如上例中的命令),以至于超出了控制台中的一行,只需继续输入,R 会自动将其余的文本放在下一行。输入完命令之前,不要按 Return 或 Enter 键。如果在输完命令前按 Return 键,R 不明白你的请求,可能会返回一个含糊的错误信息。

    实际上,不需要在计算机上安装 Excel 来使用这个软件包。有许多数据集可以从政府机构和其他各种来源自由获取,你可以下载 Excel 格式的。关于这个主题的更多信息,请参见附录 E。通过 Xlconnect,可以复制这些文件并读取到 R,用于自己的数据分析。这个包可以读或写 .xls 或较新的 .xlsx 格式。访问 http://cran.r-project.org/web/packages/XLConnect/XLConnect.pdf,可以找到完整的文档。

  • 使用文档编辑器或者文字处理器创建名为 Nimrod.Tempo.txt 的文本文件,使用空格作为值与值之间的分隔符。文件可以如下方式读取:

    > Nimrod <-read.table("Nimrod.Tempo.txt", sep = "",
      header=TRUE)
    
    

如果前面讨论的把数据放到 R 中的方法都不适用于你所处的情况,请咨询 R 帮助文件中的“R 数据导入 / 导出”部分。在“R 帮助”中包含该文件,“R 帮助”是基础安装的一部分。使用上述任何一种方法读取数据到 R 之后,使用下列方法之一查看并确认是否起作用:

> Nimrod # 打印出整个数据集

> head(Nimrod) # 打印出前6行

> fix(Nimrod)  # 在编辑器中打开Nimrod数据

最后一种方式将打开编辑器(见图 1-2),让你在必要时检查数据或改变数据的值。

你也可以给出 R 命令,以多种方式分析数据,如下所示:

> mean(Nimrod$time)
[1] 222.0938
> table(Nimrod$medium)              # 获取每个medium的数量
  bb  cb org  so
  5   9   4  14

还可以创建一些酷酷的图表,在适当的时候我们会学到这些图表。

{%}

图 1-2:R 数据编辑器中的 Nimrod 数据。可以使用该编辑器查看数据和改变特定的值

你可以请求 R 以便获得关于 Nimrod 数据集的一些一般信息:

> summary(Nimrod)
                    performer medium       time      level
 Akron Youth Sym       : 1    bb : 5  Min.   :160.0  a:13
 Allentoff-Brockport SO: 1    cb : 9  1st Qu.:191.8  p:19
 Barbirolli_Halle O    : 1    org: 4  Median :221.5
 Barenboim-ChicagoSO   : 1    so :14  Mean   :222.1
 Belcher               : 1            3rd Qu.:241.0
 Bernstein-BBC         : 1            Max  . :320.0
 (Other)               :26

使用与保存 emissions 数据集一样的方式保存 Nimrod 数据框(当然要用不同的文件名),因为在后面的练习中需要重新检索并获取这个数据框。命令如下:

> save (Nimrod,file="Nimrod.rda")

使用 load() 命令可以重新加载,如下所示:

> load("Nimrod.rda")

关于如何读取和导入外部文件,详见附录 E。

1.9 获取脚本

到目前为止,我们已经输入了单行命令。大多数时候,运行良好。但是有时候你可能想要执行一系列命令,并重复执行整个命令序列。如果序列很长或要重复很多次,这个过程就会变得很乏味。幸运的是,R 可以使用脚本(script)。脚本是一系列命令,按你想要执行的顺序排列。你可以使用文本编辑器创建脚本并将其保存到文件;然后获取脚本(source the script),即读取脚本并执行保存的命令。

下面来看一下具体的过程。假设你在不断地更新 Nimrod 数据,时不时在 Excel 电子表格中添加一些新的观测数据,并且想用 R 做一些分析,看看最新数据的情况。接下来要用一系列命令来做分析,这需要事先安装两三个包。如果你不确定计算机上安装了哪些包,可以使用如下命令查找:

> installed.packages()

如果没有 gmodelsXLConnect,那么使用如下命令进行安装:

> install.packages("gmodels")
> install.packages("XLConnect")

现在,你可以使用如下的一系列命令来实现数据分析。请注意,当使用命令块时,通常不会在每行命令前加 R 提示符(>1

1余下的许多示例代码将会写成脚本,在每一行的开始没有提示符(>)。此外,为便于阅读,长命令(如这个例子中的 CrossTable() 命令)往往被分成多行来写。

# 下面一组命令是一个脚本
library(gmodels) # 需要使用CrossTable命令
library (XLConnect) # 必须已经安装XLConnect
Nimrod2 <- readWorksheetFromFile("Nimrod.xls",sheet=1,
  header=TRUE)
attach(Nimrod2)
CrossTable(medium,level,
  prop.r=FALSE,
  prop.c=FALSE,
  prop.t=FALSE,
  prop.chisq=FALSE)
# 以上命令打印出一张表,其中每一个单元格都有计数,
# 但没有百分号
perf_time <- summary(time)    # 保存summary的输出
title  = "Summary of performance times:"
cat(title,"\n", "\n")         # 打印标题和两个空行
print(perf_time)              # 打印summary(time)的结果
detach(Nimrod2)

每次想查看结果时,用键盘输入这些相同的命令有点麻烦,所以建议你使用编辑器创建一个文件来保存上面的命令。R 提供了一个文本编辑器。在大多数 R 的版本中,可以从 R 控制台左上角的“文件”(File)菜单中访问文本编辑器。选择“新建文档”(New Document)或“新建脚本”(New Script)来打开一个文本窗口,并输入命令。在工作目录中保存编辑好的脚本,本例中命名为 NimTotals.R。然后,使用以下命令执行文件中的所有命令:

> source("NimTotals.R")


  Cell Contents
|-------------------------|
|                       N |
|-------------------------|


Total Observations in Table:  32


             | level
      medium |          a |         p | Row Total |
----- -------|---------- -|-----------|-----------|
          bb |          4 |         1 |         5 |
-------------|------------|-----------|-----------|
          cb |          6 |         3 |         9 |
-------------|------------|-----------|-----------|
         org |          0 |         4 |         4 |
-------------|------------|-----------|-----------|
          so |          3 |        11 |        14 |
-------------|------ -----|-----------|-----------|
Column Total |         13 |        19 |        32 |
-------------|------------|-----------|-----------|


Summary of performance times:

   Min.  1st  Qu.   Median    Mean  3rd  Qu.    Max.
  160.0    191.8     221.5   222.1     241.0   320.0

脚本中的 CrossTable() 命令创建了一个列联表(contingency table)或交叉制表(cross tabulation)。表的顶部是标题行,包括变量 level 的值。左列给出了变量 medium 值的名称。标题下的第一行显示了“bb”(铜管乐队)的信息。有四个铜管乐队是“a”(业余团体),一个是“p”(专业人士)。右列和底部的行为各行或各列的总数。例如,Row Total 列显示各种铜管乐队共有五个。统计学家称这些总数为临界值(marginal value)或临界(marginal)。

表的下面是变量 time 的概要信息——表演时间。我们看到最短(minimum)时间为 160 秒,最长(maximum)时间为 320 秒。时间分布的中心有两个量:一个是均值(mean)或者平均值,即用所有数字相加之和除以数字的总个数;另一个是中位数(median),有一半的数字比它大,一半的数字比它小。最后,有第一个四分位数(first quartile)191.8(即高于四分之一的数字的点),以及第三个四分位数(third quartile)241(即高于四分之三的数字的点)。

你也可能会发现,编写一个包含 library()setwd() 命令的脚本,可以方便地使用一条命令执行许多条这样的命令,否则你可能需要单独输入这些命令。如果你已经下载了几个经常使用的包,最好一次性加载所有的包,而不是记住何时需要哪个包。虽然每次启动 R 时发出 source() 命令不是特别不方便,但有些人更喜欢让 R 自动获得脚本。这是有可能的,但对于不同的平台,这个方法有点不同。在 OS X 操作系统中,打开屏幕顶部的 R 菜单并选择“首选项”(Preferences),可以指定工作目录,以便每次启动 R 时应用该工作目录。配置工作目录,以便通过拖放包含启动时将要获取的脚本文件来启动 R。在 Windows 中,需要找到 .Rprofile 或 Rprofile.site 文件并编辑它,使之包括在启动时要执行的命令。输入以下命令来看一个例子:

> ?Startup

1.10 用户自定义函数

当需要准确地重复一系列命令的时候,获取脚本是一个很好的工具。然而,有时你可能想重复执行一些程序,但不总是用相同的变量或相同的参数。如果你想使用上一节所创建的脚本,但不总用在同一文件中,那么可以编写自己的函数来选择要检索和分析的文件。

用户自定义函数的一般格式如下:

name <- function (argument1, argument2,...){
    commands
}

假设你把自己的函数命名为 update,让它获取一个 Excel 文件,每次使用函数时都要命名该文件。下面这段与前一节的脚本几乎是相同的代码,可以完成该操作。参数 fn 出现在函数语句以及 Nimrod2 的语句中,表明当 R 执行命令时,无论用户在函数调用中提供什么样的参数,都将在 Nimrod2 命令中被取代:

# 用户自定义函数,且命名为update
update <- function (fn){
library(gmodels)
library (XLConnect)
Nimrod2<-readWorksheetFromFile(fn,sheet=1,header=TRUE)
attach(Nimrod2)
CrossTable(medium,level,
  prop.r=FALSE,
  prop.c=FALSE,
  prop.t=FALSE,
  prop.chisq=FALSE)
 # 以上命令打印出一张表,其中每一个单元格都有计数,但没有百分号
perf_time = summary(time)  # 保存summary的输出
title = "Summary of performance times:"
cat(title,"\n", "\n")  # 打印标题和两空行
print(perf_time)
detach(Nimrod2)
}

为使用此函数,首先必须如保存任意 R 脚本那样将其保存,然后加载或获取它。在准备按如下方式调用函数之前,可以发出任意多的命令,其中 myfile.xls 是你要分析的 Excel 文件的名字:

>update("myfile.xls") # 文件名在引号中是因为myfile.xls是字符型变量的值

当然,下一次你可能想要分析不同的文件,只需将文件名替换为新文件的名字即可。你还可以创建简单的数学函数或相当复杂的程序,例如用来生成一种特殊类型的图,后面我们会看到这些图。

1.11 开始令人享受的事

图 1-3 展示了几张基于 Nimrod 数据集生成的图。本书后面几章将讨论所有这些类型的图,当你读完本书,应该能够生成任意一种或更多的图。

{%}

图 1-3:基于 Nimrod 数据集生成的几种类型的图

练习1-4

在练习 1-2 或者练习 1-3 中,如果输入数据时遇到问题,按照如下两种方法,试着输入练习 1-1 中简单的数据集。首先,数据如下:

存活率

使用年数

1

94

2

92

3

90

4

80

方法1:电子表格

打开电子表格,输入 5 行(包括标题)2 列的数据,如下所示。把文件以 .csv 格式导出到工作目录(详见 1.7 节),并命名为 simple1.csv。然后,创建新的数据框 mydata。代码如下:

> mydata = read.csv("simple1.csv",header=TRUE)
> mydata

  year rate
1    1   94
2    2   92
3    3   90
4    4   80
5   NA   NA

本例的电子表格中有一行空白,因此R数据框的最后一行存在缺失值。可以使用参数 nrows,只读入指定的几行数据来处理缺失值。代码如下:

> mydata= read.csv("simple1.csv",header=TRUE,nrows=4)
> mydata

  year rate
1    1   94
2    2   92
3    3   90
4    4   80

如果在标题前有其他(空白)行,结果可能如下所示:

> mydata

   X  X.1  X.2 X.3
1 NA year rate  NA
2 NA    1   94  NA
3 NA    2   92  NA
4 NA    3   90  NA
5 NA    4   80  NA

可以使用参数 skip 忽略第一行,代码如下:

>mydata= read.csv("simple1a.csv",header=TRUE,skip=1, nrows=4)
> mydata

   X year rate X.1
1 NA    1   94  NA
2 NA    2   92  NA
3 NA    3   90  NA
4 NA    4   80  NA

在最后一个例子中,有额外的列。这不是一个大问题,忽略即可。重要的是两个向量 yearrate 有正确的行数。如果想删除其中一个无用的列,可按如下方式处理:

>mydata$X = NULL
>mydata

  year rate X.1
1    1   94  NA
2    2   92  NA
3    3   90  NA
4    4   80  NA

方法2:文本

打开文字处理器或者文本编辑器。输入数据,每一行中输入的两个数字之间用空格分开,并在每行结尾回车,如下所示:

year rate
1    94
2    92
3    90
4    80

多余的空格无关紧要,但是数据应该被保存为纯文本,而不是富文本。如果你的文字处理器允许保存为 .txt 文件,使用“另存为”命令将文件保存到工作目录,并命名为 simple2.txt。否则,需要使用导出命令导出文件,同样命名为 simple2.txt。将数据读入 R,并使用如下命令创建新数据框 newdata

> newdata = read.table("simple2.txt",sep="",header=TRUE)
> newdata

  year rate
1    1   94
2    2   92
3    3   90
4    4   80

目录

  • 版权声明
  • O'Reilly Media, Inc. 介绍
  • 前言
  • 第一部分 开始使用 R
  • 第 1 章 R 基础
  • 第 2 章 R 图概述
  • 第二部分 单变量图
  • 第 3 章 带状图
  • 第 4 章 点图
  • 第 5 章 箱线图
  • 第 6 章 茎叶图
  • 第 7 章 直方图
  • 第 8 章 核密度图
  • 第 9 章 条形图
  • 第 10 章 饼图
  • 第 11 章 地毯图
  • 第三部分 双变量图
  • 第 12 章 散点图和折线图
  • 第 13 章 高密度图
  • 第 14 章 Bland-Altman 图
  • 第 15 章 QQ 图
  • 第四部分 多变量图
  • 第 16 章 散点图矩阵和相关性分析图
  • 第 17 章 三维图
  • 第 18 章 协同图
  • 第 19 章 聚类分析:树状图和热图
  • 第 20 章 马赛克图
  • 第五部分 现在该做些什么
  • 第 21 章 拓展图形化知识和 R 技能的资源
  • 附录 A 参考文献
  • 附录 B R 的颜色
  • 附录 C R Commander 图形用户界面
  • 附录 D 使用 / 引用的包
  • 附录 E 从 R 的外部导入数据
  • 附录 F 章节练习解答
  • 附录 G 故障排查:为什么我的代码不工作
  • 附录 H 本书介绍的 R 函数
  • 关于作者
  • 关于封面