首页 > > > 【R语言】:数据结构入门(2)
《从零学会数据分析:数据结构入门》学习笔记,参考《R语言实战(第2版)》
一、数据结构的类型
向量、矩阵、数组、数据框、列表、因子。其中,因子这种类型最为特殊,之后会有涉及,本文将主要讲述前五种数据结构,如题图或下图。
主要把握两点:第一,如果定义一种数据结构?第二,如何使用一种数据结构?
二、向量
1、向量的定义:用于存储相同类型数据的一维数组(容器),数据的类型可以分为数值型(1,2,3等)、字符型(任何用引号“”或‘’引用的内容)和逻辑型(TRUE或FALSE,R语言中全部为大写)。所以,单个向量的数据必须拥有相同的数据类型。

#创建向量name来存储姓名这一列
name <- c("赵四", "李同", "王五", "张三")2、如何使用向量:
获取向量长度,使用函数length(),以向量name为例
length(name)
[1] 4
通过在方括号中给定元素所处位置的数值,例如name[1]为访问name向量第一个元素“赵四”。
name[1]
[1] "赵四"
还可以同时确定多个元素,例如name[c(1, 3)]就是访问name向量第一个元素“赵四”和第三个元素“王五”。
name[c(1, 3)]
[1] "赵四" "王五"
甚至可以利用英文冒号“:”和所处首尾位置的数值在原有向量基础上生成新的连续序列,例如name[2:4]生成"李同" "王五" "张三",即原有向量第二到第四个元素。
name[2:4]
[1] "李同" "王五" "张三"
三、矩阵
1、矩阵的定义:用于存储相同类型数据的二维数组(容器),矩阵中每个元素都拥有相同的模式(数值型、字符型或逻辑型)。所以,矩阵和向量的相同点在于数据必须拥有相同的数据类型,不同点在于向量是一维的,矩阵是二维的。
R语言中用函数matrix(vector, nrow = number_of_rows, ncol = number_of_columns, byrow = logical_value, dimnames = list(char_vector_rownames, char_vector_colnames))来创建一个矩阵,其中vector指包含的矩阵元素;nrow和ncol用来指定行和列的维度;用逻辑型字符定义byrow,为TRUE表示按照行填充(先从左到右再从上到下),为FALSE表示按照列填充(先从上到下再从左到右),默认情况(在代码中不写出来)按列填充;dimnames指用户可以自己定义行名和列名(用字符型向量表示)。
下面例子将数字从1到6按照行来填充成一个2X3(2行3列)的矩阵。
#矩阵的元素,数字1-6
mydata <- c(1, 2, 3, 4, 5, 6)
#行名,用字符型向量表示
rnames <- c("H1", "H2")
#列名,用字符型向量表示
cnames <- c("L1", "L2", "L3")
mymatrix <- matrix(data = mydata, nrow = 2, ncol = 3, byrow = TRUE, dimnames = list(rnames, cnames))
#这还有另外一种确定矩阵元素的方法
mymatrix <- matrix(1:6, nrow = 2, ncol = 3, byrow = TRUE, dimnames = list(rnames, cnames))

2、如何使用矩阵:
第一,如何访问矩阵中的元素。
输入a[i,]获取矩阵a的第i行,输入a[,j]获取矩阵a的第j列,输入a[i,j]获取矩阵a的第i行第j列。
咱们还是以上面的矩阵mymatrix为例,下面是代码
#获取第2行
mymatrix[2,]
#获取第3列
mymatrix[,3]
#获取第2行第3列,即数字6
mymatrix[2,3]在Mac版RStudio运行代码后,运行结果如下图

可以绘制柱状图
还是以开头的病例数据为例。用每个病人的具体姓名做行名,病人年龄的英文age做列名,定义一个4行*1列的矩阵。
#定义4行*1列的矩阵
#矩阵的数据:病人的年龄,将具体的病人年龄赋值给向量age
age <- c(29, 34, 28, 52)
#行名:每个病人的具体姓名
rnames <- c('赵四', '李同', '王五', '张三')
#列名:病人的年龄age
cnames <- c('age')
#定义矩阵
age_mytrix <- matrix(age, nrow = 4, ncol = 1, byrow = TRUE, dimnames = list(rnames, cnames))
运行代码,获得下面的矩阵

利用R语言中的函数barplot绘制柱状图(这里仅作举例,如何用R语言绘图将在以后系统性的学习),横轴用姓名表示,纵轴年龄表示,具体代码如下:
barplot(age_mytrix[,"age"], main = "病人年龄分布", ylab = "姓名", col = c("lightblue"), border = NA, cex.lab = 1.5, las =2)运行代码可得到下图(比较粗糙,主要用来说明矩阵用途)

与矩阵的定义非常相似,区别在于数组是多维,矩阵是二维。所以我们很容易可以发现:向量、矩阵、数组的数据必须拥有相同的数据类型,但向量是一维的,矩阵是二维的,数组是多维的。
R语言中用函数array(vector, dimensions, dimnames)创建一个数组,其中vector是指包含的数组元素,dimensions是一个数值型向量,给出了各个维度的最大值(可以这样理解:假设一个简单的数组有三个维度,分别是x、y、z,如果定义dimensions为数值向量c(2, 3, 4),这就意味着x最多包含2个元素,y最多包含3个元素,z最多包含4个元素,下面将举例说明),dimnames指用户可以自己定义各维度名称标签的列表(数据结构的一种)。
下面例子是将数字从1到24填充成一个由“4个2行3列的矩阵”组成的三维数组。
#定义一个由“4个2行3列的矩阵”组成的三维数组
#数组中的元素
my_array_data <- 1:24
#每个维度的名称
dim_x <- c("X1", "X2")
dim_y <- c("Y1", "Y2", "Y3")
dim_z <- c("Z1", "Z2", "Z3", "Z4")
#定义三维数组
myarray <- array(my_array_data, c(2, 3, 4), dimnames = list(dim_x, dim_y, dim_z))
#查看三维数组myarray
myarray运行代码,可以看到三维数组如下图。

五、数据框
咳咳咳!敲黑板!划重点!
仔细阅读了以上内容的读者在我的加粗提醒下都应该能发现,向量、矩阵、数组这三种数据结构都有一个重大的缺陷——数据必须拥有相同的数据类型。但在实际工作或应用场景中,数据几乎不可能只有一种数据类型的,比如最开始的病例数据,病人编号、年龄是数值型,病人姓名、编号、病情都是字符型。所以接下来的这个数据结构——数据框,能够存储不同类型的数据,是实践中(也是R语言中)最常处理的数据结构,所以数据框才是数据结构的重中之重。
1、数据框的定义
数据框是R语言里中的一种数据结构,其内部可以由多种数据类型,每一列是一个变量,每行是一个观测记录。数据框的每一列数据的模式必须唯一,但可以将多个类型的不同列放到一起组成数据框。
R语言中用函数data.frame(col1, col2, col3, ...)创建一个数据框,其中col1、col2、col3等等可以使任何类型(字符型、数值型、逻辑型)的列向量。
开头的病例数据可以作为一个非常合适的例子用来演示如何在R语言中创建数据框。
#创建数据框:病例数据
#病人编号
patientID <- c(1, 2, 3, 4)
#姓名
name <- c('赵四', '李同', '王五', '张三')
#病人年龄
age <- c(29, 34, 28, 52)
#糖尿病类型
diabetes <- c("1型糖尿病", "2型糖尿病", "1型糖尿病", "2型糖尿病")
#病情
status <- c("较差", "好转", "显著好转", "较差")
patientdata <- data.frame(patientID, name, age, diabetes, status, stringsAsFactors = FALSE)*注:代码中stringsAsFactors=FALSE 是必需的,这样可以避免将字符串解释为因子(详细内容将来在涉及因子的内容会详细阐述)。
运行代码,将用R语言将病例数据存入数据框patientdata。

如何查找数据框中的数据?用符号$和数据框中的列名(列向量名称)来查找选取数据框中的某一列。
#查找
age1 <- patientdata$age运行代码后,选取病例数据框中年龄这一列
#选取其中一部分数据
subdata <- patientdata[c("diabetes", "status")]
运行代码,选取病例数据框中的糖尿病类型与病情。

#统计有多少位病人
patientnum <- nrow(patientdata)运行代码,统计病人数量。

第一步,需要先查找到某一列,然后用==选中这一列中的某个具体数据,字符型一定要加双引号""或单引号'' 。
#查找“1型糖尿病”的病人
type1 <- patientdata[patientdata$diabetes == "1型糖尿病"]运行代码,得到一个新的数据框type1。

第二步,利用“计数功能”统计新数据框type1有多少行数据。
#统计“1型糖尿病”病人数量
type1_num <- nrow(type1)运行代码后得到

第一步,把需要增加的新数据按照现有数据框的数据构成格式增加一条新的数据框。
#病人编号
patientID <- c(5)
#病人姓名
name <- "刘能"
#病人年龄
age <- c(30)
#糖尿病类型
diabetes <- c("1型糖尿病")
#病情
status <- c("较差")
newpatientdata <- data.frame(patientID, name, age, diabetes, status, stringsAsFactors = FALSE)运行代码,可以得到一个新的数据框newpatientdata,该数据框包含了所要增加的一行病人数据。

#利用rbind函数增加数据
patientdata <- rbind(patientdata, newpatientdata)
运行代码,数据框patientdata增加了一行新数据。

第一步,增加一个列数据(向量)。
#入院时间
inTime <- c("2015-03-01", "2014-12-31", "2015-10-01", "2015-05-01", "2016-12-31")运行代码可得到入院时间的列向量inTime。

#cbind函数增加列向量
patientdata <- cbind(patientdata, inTime)
运行代码,数据框patientdata增加一个列向量,数据构成改变

kpi <- list(diabetestype1 = type1, num = patientnum)
#数字1表示第1个元素--数据框type1
listdataframe <- kpi[[1]]

#创建列表时命名了数据框的名称为“diabetestype1”
listdataframe2 <- kpi[["diabetestype1"]]

八、实践练习
1、读取病例数据xlsx。
2、获取病人数量(见上文)
3、患1型糖尿病的病人数量(见上文)
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31537575/viewspace-3143037/ ,如需转载,请注明出处,否则将追究法律责任。