
2.2 数据操作
2.2.1 基本数据类型
在R语言里操作或接触的所有东西都称作对象。对象有很多种类,可以包含各种类型的数据。R语言中常见的数据类型有:字符型(character)、数值型(numeric)、整型(integer)、复数型(complex)、因子型(factor)以及逻辑型(logical)。R语言里最常见的基本对象是向量(vector),一个向量可以包含同一类型的多个对象,用命令c()构造一个向量。
(1)数值型(numeric):一般数字形式的数据都为数值型(实数或者小数),从传统的数据分类方式来看,即指定量变量。例如:

(2)整型(integer):仅含有整数,且设定数据类型为integer,否则一般为数值型。例如:

(3)复数型(complex):取值可以扩展到虚数。例如:

其中,i是个特殊符号,代表复数的虚部。
(4)逻辑型(logical):取TRUE和FALSE两个固定值,用于指示判断结果。例如:

(5)字符型(character):指向量中每个元素都是一个字符或字符串,即一般的数据分类方式中所说的定性变量。例如:

(6)因子型(factor):因子是一种特殊的向量类型,通常用来记录分类数据。因子有两种类型:有序的以及无序的。无序因子可以认为是用来标记那些有标签有类别但是又没有顺序的数据,比如说男性和女性。有序因子可以用来标记那些有先后次序的数据,这些数据可以不是数值型的,但却是有序的。例如,大学的助教、讲师、副教授以及正教授,这就是一种有序的分类。所以可以把有序因子当作是一个整型向量,其中每个整数都有一个标签。例如,一个由1、2、3组成的向量,1代表较高的值,2代表一个中等的值,3代表一个较低的值。这三个变量将会有三个标签,分别是高、中、低,在R当中分别用1、2、3来表示。可以使用factor()函数来创建因子,命令如下。

创建一个含有两个level(yes和no)的简单因子,命令如下:

一个向量可以包含单一类型的多个对象,因此可以有实数向量或整数向量。但是一个标准的向量不能包含不同类型的对象,同一个向量里的所有对象都必须是同一类型的。如果一个向量中包含两种不同类型的对象,那么R会创建最低级公共类型的向量。此时R不会报错,而是将向量强制转换成为二者的最低级公共类型。例如:

若想强制转换对象的类型,可以使用as.numeric()、as.logical()、as.charcater()函数进行强制转换,例如:

强制转换也不一定总能成功,如果它失败了就会返回NA值。所有无意义的强制转换就会导致NA值。

2.2.2 数据结构
R语言中的数据结构主要包括向量、矩阵、列表、数组和数据框。
1.向量
最简单的数据结构就是由一串有序数值构成的数值向量。假如要创建一个含有5个数值的向量x,且这5个值分别为1,3,5,7和9,则R语言中的命令为:

2.矩阵
矩阵是R语言里的一类特殊向量,它们不是一种单一的数据类型,而是有维度属性的向量。维度属性是一个整型向量,它的长度为2。其中,第一个数字是矩阵的行数,第二个数字是矩阵的列数。

矩阵是按列生成的,可以把这个过程想象成把一个向量里的所有数按列填入矩阵中,先填第一列,填完第一列最后一行的数字后再填第二列,然后是第三列等。
例如,使用1~6的数列创建一个矩阵,指定这个矩阵有两行三列,输入命令如下。

还有一种创建矩阵的方法就是使用cbind()或rbind()函数通过绑定行或者列来创建,例如:

3.列表
可以包含多种类型的对象的向量叫作列表,列表是一个由多个对象组成的序列,只是其中每个对象的类型可以各不相同。比方说一个列表可以包含字符型、数值型和逻辑型的对象,也可以包含一个列表。列表的每个元素可以是不同类型的对象,这就让列表可以轻松存放各种类型的数据。在R语言中列表是非常有用而且常用的对象,尤其是在和其他我们即将学到的函数类型一起使用时。例如,使用list()函数创建一个列表x,第一个元素是数值对象1,第二个元素是字符“a”,第三个是逻辑值TRUE,第四个是复数,命令如下。

在输出结果中,列表的元素用[[]]里面的数字进行索引,所以第一个元素是向量1,第二个元素是向量“a”,第三个元素是向量TRUE,第四个元素是复数向量1+4i。
列表元素由[[]]包围,其他向量的元素则只有[],这是把列表和其他类型的向量区分开的一种方法。
列表中的元素还可以是数据框。所以组成列表的元素可以是任何类型的对象,这也是列表会这么有用的原因。数据框可以理解成一个松散的数据集。它可以是由不同类型的列(数字、因子、字符等)组成的类矩阵。
4.数组
数组与矩阵类似,但是维度可以大于2。数组可通过array函数创建,形式如下:

例如:

5.数据框
数据框是R语言中最常处理的数据结构。R语言中的数据框由行和列组成,与矩阵不同的是,数据框中的每个列可以是不同的数据类型。数据框的每一列都有列名,每一行也可以指定行名。如果不指定行名,则用从1开始自增的序列来标识每一行。
使用data.frame()函数来初始化一个数据框。例如要定义一个student数据框,其中包括ID和Name,还有Gender以及Birthdate,则代码为:

与矩阵一样,使用[行Index,列Index]的格式可以访问数据框的具体元素。
比如访问第一行:student[1,];
访问第二列:student[,2];
使用列的Index或者列名可以选取要访问的那些列。比如要访问ID和Name,则代码为:

如果只访问某一列,返回的是Vector类型的,则可以使用[[或者$来访问。比如要取得所有student的Name列,则代码为:

2.2.3 数据读写
1.读数据
对R语言的初学者来讲,面对一片空白的命令行窗口,第一道真正的难关也许就是数据的读入。数据来源有很多途径,例如从网页抓取、公共数据源获得、文本文件导入。R语言的数据读取函数主要有read.table()、scan()、read.fwf()、readLines()等。下面给出几种常用的数据读入方法。
1)使用read.table()读文件
read.table()函数的格式为:

例如,用read.table()读c:\data下的文件houses.dat。

如果明确数据第一行作表头,则使用header选项,例如:

read.table()的变形有read.csv()、read.csv2()、read.delim()、read.delim2()。前两个读取逗号分割的数据,后两个读取其他分隔符数据。
2)使用scan()函数读文件
除了read.table()这类读取文本文档的函数,还可以用scan()函数读入数据。不同的是它的返回值为列表或者向量。用scan()读文件比read.table()更灵活,但要指定变量类型。例如,C:\data\data.dat的文件内容如下。

用scan()读取该文件:

3)用read.fwf()读取文件中一些固定宽度数据
read.fwf()函数的格式为:

例如,C:\data\data.txt的文件内容如下。

用read.fwf()读取该文件:

4)使用剪贴板读数据
如果已经有一个打开的表格,可以复制其中的内容,然后用readClipboard()或者read.table()等函数导入数据。
例如,对于一个打开的Excel文件,选择要读取的数据,然后使用Ctrl+C键复制,在R中输入如下命令便可读入数据:

2.写数据
写数据即将数据导出到某种格式的文件中。R语言提供了write.table()、cat()等函数来导出数据。不过值得指出的是,R语言能够导出的数据格式是有限的,比如在基本包中,我们能够导出数据的格式只有txt和csv。现在介绍一下两个函数的用法。
1)write.table()函数
write.table()函数的格式为:

write.csv(),write.csv2()可以看作write.table()的变体,write.csv()与参数sep=“,”的write.table()是等效的。下面介绍几个常见的参数。
x:数据集。
file:文件的路径,包括文件名如“D:/R/data/data1.csv”。
quote:数据在写入文件中时常用引号将其隔开,当参数为F时,文件中的数据不再用引号修饰。
append:是否追加,如果文件名已存在而没有选择追加,那么文件将会被覆盖。(覆盖时是没有提示的,所以命名时需要注意。)
例如:
创建数据框d:

将数据框d保存为简单文本:

将数据框保存为逗号分隔文本:

2)cat()函数
cat()函数的格式为:

cat()作为一个输出函数与DOS命令差不多,也是将数据集或数据写入文件中,常用参数和write.table()类似。cat()函数用来输出,可以把多个参数连接起来再输出(具有paste()的功能)。例如:

还可以指定一个参数file,即给定一个文件名,把结果写到该指定的文件中,例如:

如果指定的文件已经存在则原来内容被覆盖。加上一个append=TRUE参数可以不覆盖原文件而是在文件末尾附加,这很适用于运行中的结果记录。cat()的用法比较丰富,也可以用来查看文件,与format合用控制输出格式等。
2.2.4 数据的描述性统计
描述性统计是一种从大量数据中压缩提取信息的工具,最常用的就是summary命令,该命令对于数值变量计算了5个分位点和均值,对于分类变量则计算了频数。例如:

描述性统计通过计算统计量等方法来描述数据的分布特征,常用的统计量包括均值、众数、中位数、百分位数等,计算这些统计量的常用函数如表2-1所示。
表2-1 常用的统计量计算函数
