R语言数据可视化:科技图表绘制
上QQ阅读APP看书,第一时间看更新

1.4 数据结构

在R中分析数据或创建图形时,首先要提供参与分析或绘图的数据集(Data Set)。R可以处理的数据集类型包括向量(Vector)、矩阵(Matrix)、数组(Array)、数据框(Data Frame)、因子(Factor)、列表(List)等,它们的数据结构如图1-11所示。

图1-11 输出结果

1.4.1 数据类型

在R中,常见的数据类型有数值型(Numeric)、字符型(Character)、逻辑型(Logical)、复数型(Complex)或日期时间型(Data)等,其中数值型又分为整数型(Integer)和双精度型(Double)两种。数据类型的识别、判断以及类型之间的转换是数据分析中必不可少的内容。

在统计分析或运算过程中,可能需要对向量中的数据类型进行识别和判断。R中使用class()函数识别数据类型,使用is.*()函数判断是否为某个指定的数据类型,使用as.*()函数进行数据类型的转换。其中*为数据类型的英文表示。

另外,R语言中还包含几种常见的特殊值,如表1-1所示。

表1-1 特殊的数据类型

【例1-7】数据类型应用示例。

输入代码如下:

1.4.2 向量

向量是R语言中重要的数据结构,可以是数值数据、字符数据或逻辑值,很多情况下都会涉及向量的处理和运算。向量的创建可以通过手动输入、序列生成、重复生成和目标抽取(向量索引)等方法实现。

1.手动输入法

R语言允许用户通过手动方式将数据存储到向量中,例如将姓名存储到变量为Name的向量中,或将性别存储到变量为Gender的向量中。手动构建向量通过c()函数实现。

【例1-8】手动输入向量示例。将3个客户的姓名、性别、出生日期和收入保存到各自的变量中。

输入代码如下:

    > Name <- c('Jeff','Tom','Mary')
    > Gender <- c('男','男','女')
    > Birthday <- c('1985-6-18','1992-4-11','1986-12-8')
    > Income <- c(16000,8500,12500)

说明(1)代码中的“ <- ”符号表示赋值,即将符号右边的向量赋值给左边的变量,表示赋值的符号还可以使用“=”“->”,读者根据自己的习惯选择即可。

(2)对于字符型的值或日期时间型的值,必须用引号引起来(如前3个变量),而数值型的值则不需要。

2.序列生成法

利用符号“:”或函数seq()生成具有规律的数值型数据,这就是序列生成法。其中,英文状态下的冒号“:”用于生成步长为1或-1的连续数据,seq()函数用于生成指定步长或长度的等差数列。seq()函数的语法格式为:

其中,from指定等差数列的初始值;to指定等差数列的结束值;by指定等差数列的公差;length表示在公差未知的情况下,可以通过其设定等差数列的元素个数。

【例1-9】序列生成法输入向量示例。

输入代码如下:

3.重复生成法

重复生成法是利用rep()函数将某个对象进行指定次数的重复,进而减少人工输入的一种方法。rep()函数的语法格式为:

    rep(x,times)
    rep(x,each)

其中,x指定需要循环的对象,times指定x的循环次数(x的整体在循环),each指定x中元素的循环次数(依次将x的元素进行循环)。

【例1-10】通过重复生成法录入公司2020—2022年各季度的销售额。

输入代码如下:

创建的数据框对象如图1-12所示,读者应观察Year、Quarter两个向量创建的差异。

图1-12 创建数据框对象

4.目标抽取法(向量索引)

在介绍目标抽取前,先介绍一下向量索引。向量中的元素是按照顺序排列的,通过索引的方法可以将向量中的元素提取出来。在R语言中,索引使用方括号“[]”表示,包括位置索引与bool索引两种方法。

(1)位置索引是指在中括号内标明目标元素的下标,如向量第5个元素可以写为“[5]”,当取出向量中的多个元素时,需要将整数型的下标值写成向量的形式,如向量的第2、4、6个元素可以写为“[c(2,4,6)]”。

(2)bool索引是指方括号“[]”内的值不是整数型下标,而是TRUE或FALSE,索引时取出TRUE所对应的值。bool索引经常会与比较运算符(>、>=、<、<=、==、!=)配合使用,相比于位置索引,bool索引使用得更加频繁。

回到目标抽取法,它是指从已知向量中提取子集(由该向量的部分元素组成新的向量),或从矩阵中抽取一行或一列,或从数据框中抽取一列,进而得到数值型、字符型或日期时间型的向量。

矩阵或数据框的操作将在后文介绍。向量子集的提取通过方括号来实现,具体方式如下:

(1)通过在中括号中指定正整数来返回向量指定位置的元素组成的子向量(R语言中向量的元素起始位置为1)。

(2)通过在方括号中指定逻辑值向量来返回向量中对应的逻辑值为TRUE的元素组成的子向量。

(3)通过在方括号中指定负整数来返回向量除去指定位置的元素组成的子向量。方括号内不能同时包含正整数和负整数。

(4)如果向量已经命名,则可以通过在方括号中指定元素的名称来返回相应的子向量。

【例1-11】向量子集的提取示例。

输入代码如下:

1.4.3 矩阵与数组

前面介绍的向量实际上就是一个一维数组。而矩阵是一个二维数组,其中的每个元素都是相同的数据类型。

1.创建矩阵和数组

在R中,用matrix()函数可以创建矩阵,其语法格式为:

    matrix(data=NA,nrow=l,ncol=l,byrow=FALSE,dimnames=NULL)

其中,data指定一个用于构造矩阵的一维向量;nrow指定矩阵的行数(默认为1);ncol指定矩阵的列数(默认为1);byrow为布尔型的参数,指在矩阵构造过程中元素是按列填充(byrow=FALSE)还是按行填充(byrow=TRUE);dimnames用于设置矩阵的行和列的名称,需将行、列名称以列表的形式传递给该参数。

数组与矩阵类似,但数组的维数可以大于2。在R中,使用array()函数创建数组,其语法格式为:

    array(data=NA,dim=length(data),dimnames=NULL)

其中,data是一个包含数组中数据的向量;dim指定每个维度的最大长度;dimnames是各维度名称标签的一个列表。

另外,在R中通过as.matrix()函数可以将数据框强制转换为矩阵,其语法格式为:

    as.matrix(x,rownames.force=NA)

其中,x指定一个数据框,并将其强制转换为矩阵;rownames.force为布尔型参数,将x强制转换为矩阵后,矩阵是否包含字符型的列名称,默认为NA,表示矩阵列名称与数据框变量名称一致。

使用t()函数可以实现矩阵的转置,其语法格式为:

【例1-12】创建矩阵与数组示例。

输入代码如下:

2.提取子集(矩阵索引)

矩阵子集的抽取(索引)与向量子集的抽取(索引)相似,不同的是向量子集是基于一维数据提取的,而矩阵子集则是基于二维数据提取的。

矩阵子集的提取方法为[row_index,col_index],其中row_index控制矩阵提取的行,col_index控制矩阵要取的列。

【例1-13】矩阵子集的提取示例。

输入代码如下:

提示取出矩阵中的单行或单列时,应的col_index或row_index不需要设置。其中dim函数以向量形式返回矩阵的行数和列数,dim(Mat)[1]表示仅返回矩阵Mat的行数。

1.4.4 数据框

数据框即数据表,表中不同的字段可以是不同的数据类型,因此构成数据框的各字段可以是不同数据类型的向量。而向量和矩阵的元素不允许同时出现多种数据类型。

构造数据框可以利用data.frame()函数手动创建,或者利用as.data.frame()函数将矩阵或列表强制转换为数据框,也可以通过读取外部数据形成数据框。

函数data.frame()的语法格式为:

stringsAsFactors())

部分参数的含义如表1-2所示。

表1-2 参数含义

函数as.data.frame()的语法格式为:

    as.data.frame(x,row.names=NULL)

其中,x指定待转换为数据框的对象,可以是列表或矩阵。

【例1-14】数据框创建示例——手动构造学生信息的向量。

输入代码如下:

创建的数据框对象如图1-13所示。通过data.frame()函数方便将6个向量组合为一张数据表,并且表中的字段包含字符型、数值型和日期型。

图1-13 创建数据框对象

注意组合为数据框的向量元素个数必须相等,否则会返回错误信息。

当数据框中的行和列较多时,使用head()函数可以只显示数据框的前几行,使用tail()函数可以只显示数据框的后几行。

当数据量比较大时,使用str()函数可以只查看数据的结构。如查看数据框Stu_info的数据结构,可使用下面的代码:

结果显示,Stu_info是一个数据框,共有6个变量,每个变量又有6个观测值。

另外,还有其他函数可以查看数据框的类型、行数、列数等其他信息。

当需要对数据框中的特定变量进行分析或绘图时,使用“$”符号指定要分析的变量。

使用rbind()函数可以将不同的数据框按行合并,使用cbind()函数可以将不同的数据框按列合并。为保证有意义地合并,当按行合并时,数据框中的列变量必须相同;当按列合并时,数据框中的行变量必须相同。

1.4.5 列表

列表用以存储包括常数、向量、矩阵、数据框在内的任意一种数据对象,甚至可以嵌套列表。列表的元素可以是异质的,行数也可以不同。

1.构造列表

列表的构造使用list()函数,其语法格式为:

    list(…)

其中,…为常数、向量、矩阵、数据框在内的任意一种数据对象。

【例1-15】创建包含常数、字符型向量、矩阵和数据框4个元素的列表。

输入代码如下:

说明在构造列表时,第3个元素并没有将Mat传递给一个新的变量名,因此第3个元素的输出以“[[3]]”作为名称。

2.列表索引

列表的索引有单方括号“[]”、双方括号“[[]]”和美元符号“$”3种形式,区别在于返回的元素是列表型数据结构还是其本身的数据结构。

单括号索引方式返回的一定是列表型对象,而非元素的原始结构;双括号索引或美元符号索引方式返回的一定是元素的原始结构。

【例1-16】利用上例中创建的列表List_object演示列表的索引,检查返回列表中元素的数据结构。

输入代码如下:

如结果所示,第一个元素通过单中括号的索引方式返回列表型对象,第二个元素通过双中括号的索引方式返回字符型向量,第三个元素通过双中括号的索引方式返回矩阵型对象,第四个元素通过美元符号索引方式返回数据框对象。

注意在返回原始的数据结构时,若列表元素有名称(如List_object中的A、B和D),则可以使用双括号或美元符号;若列表元素没有名称(如List_object中的[[2]]),则只能使用双括号的索引方式。

1.4.6 因子

在数据分析中,变量或数据(变量的观测结果)基本可以分为类别变量(Categorical Variable)与数值变量(Metric Variable)两大类。

(1)类别变量是取值为对象属性或类别以及区间值(Interval Value)的变量,也称定性变量(Qualitative Variable)。例如性别可以分为“男”“女”两类,“性别”就是类别变量,当把成绩(满分100分)等级分为85~100(优)、75~84(良)、60~74(中)及60以下(差),“成绩等级”为数值区间,因而也属于类别变量,类别变量的观测值就是类别数据。

类别变量根据取值是否有序可分为无序类别变量和有序类别变量。无序类别变量的各类别间是不可以排序的,而有序类别变量的各类别间是有序的,如成绩分为“优”“良”“中”“差”就是有序的。取区间值的变量自然是有序类别变量。

(2)数值变量是取值为数字的变量,变量的观测结果称为数值数据(Metric Data)或定量数据(Quantitative Data)。数值变量根据其取值的不同可以分为离散变量和连续变量。离散变量是只能取有限个值的变量,其取值可以列举;连续变量是可以在一个或多个区间中取任何值的变量。

类别变量在R中称为因子(Factor),因子的取值称为水平(LEVEL),很多分析或绘图都可以按照因子的水平进行分类处理。使用factor()函数可以将向量编码为因子。

【例1-17】将向量编码为因子示例。

输入代码如下:

可以发现,上述因子是无序的。若将有序因子转换为数值,则需要将factor()函数中的参数设置为ordered=TRUE(默认ordered=FALSE)。