ITPub博客

首页 > > > 【R语言】:数据结构入门(2)

【R语言】:数据结构入门(2)

作者:浪花小雨滴 时间:2020-06-17 10:37:08 0 删除 编辑
《从零学会数据分析:数据结构入门》学习笔记,参考《R语言实战(第2版)》

R语言的数据结构

一、数据结构的类型

向量、矩阵、数组、数据框、列表、因子。其中,因子这种类型最为特殊,之后会有涉及,本文将主要讲述前五种数据结构,如题图或下图。

主要把握两点:第一,如果定义一种数据结构?第二,如何使用一种数据结构?

二、向量

1、向量的定义:用于存储相同类型数据的一维数组(容器),数据的类型可以分为数值型(1,2,3等)、字符型(任何用引号“”或‘’引用的内容)和逻辑型(TRUE或FALSE,R语言中全部为大写)。所以,单个向量的数据必须拥有相同的数据类型。

以上图的病例数据为例,Excel表格里的每一列都可以看做一个向量,例如姓名。在R语言中,可以用函数c()来创建向量,与Python一样,代码中#后面的内容无效,作为代码注释。

#创建向量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))
在Mac版RStudio运行代码后,下图为运行结果

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

运行代码,可以看到三维数组如下图。

从而,我们可以很容易的看出,1-24共二十四个数字,依次按列填充(还记得吗?默认按列填充,如果需要按行填充,需要输入代码"byrow = TRUE")成了一个由“4个2行3列的矩阵”组成的数组。

五、数据框

咳咳咳!敲黑板!划重点!
仔细阅读了以上内容的读者在我的加粗提醒下都应该能发现,向量、矩阵、数组这三种数据结构都有一个重大的缺陷——数据必须拥有相同的数据类型。但在实际工作或应用场景中,数据几乎不可能只有一种数据类型的,比如最开始的病例数据,病人编号、年龄是数值型,病人姓名、编号、病情都是字符型。所以接下来的这个数据结构——数据框,能够存储不同类型的数据,是实践中(也是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。

2、如何使用数据框

如何查找数据框中的数据?用符号$和数据框中的列名(列向量名称)来查找选取数据框中的某一列。

#查找
age1 <- patientdata$age

运行代码后,选取病例数据框中年龄这一列

如何选取数据框的其中一部分数据?给数据框中指定列名来确定需要选取的数据。

#选取其中一部分数据
subdata <- patientdata[c("diabetes", "status")]

运行代码,选取病例数据框中的糖尿病类型与病情。

如何快速获知数据框中某一列有多少条数据?即计数功能,快速统计数据框里某一列向量总共有多少行,比如统计病例数据框里有多少位病人。(注:空值/NULL/NA,也算一条数据)

#统计有多少位病人
patientnum <- nrow(patientdata)

运行代码,统计病人数量。

如何快速获知某一列数据中具有相同数据的数量是多少?即统计数据中某一特定元素的数量,比如统计病例数据中有多少位“1型糖尿病”的病人。

第一步,需要先查找到某一列,然后用==选中这一列中的某个具体数据,字符型一定要加双引号""或单引号'' 。

#查找“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将新的数据框newpatientdata增加到原有数据框patientdata中。

#利用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将新列向量inTime增加到原有数据框patientdata,数据框patientdata的数据构成改变。

#cbind函数增加列向量
patientdata <- cbind(patientdata, inTime)

运行代码,数据框patientdata增加一个列向量,数据构成改变



六、列表
1、列表的定义
列表是R语言中最为复杂的一种数据结构,是一些对象(或成分)的有序集合。因此,一个列表中可能是若干向量、矩阵、数组、数据框,甚至是其他列表的组合。列表是R语言中能够存储各种数据结构、包罗万象的容器。
R语言中用函数list(object1, object2, object3, ...)创建一个列表,其中object对象是R语言中的任何数据结构。此外,还可以给列表中的对象命名:list(name1=object1, name2=object2, name3=object3, ...),命名主要是为了用户方便查找。
在实际的数据分析中需要运用多种函数,函数返回结果调用数据的时候会涉及到各种数据结构,需要用列表存储函数返回的结果。
2、如何使用列表
列表用来存储各种业务指标(即传说中万恶的KPI),还是以病人数据为例,业务指标可以是有多少个病人(patientnum),也可以是患“1型糖尿病”的病人信息(type1)。
kpi <- list(diabetestype1 = type1, num = patientnum)
运行代码,得到列表kpi
如何查找列表中的数据?
通过双重方括号中指明代表某个成分的数字或名称来获取列表中的元素。
下面的代码是采用成分的数字来获取列表中的元素
#数字1表示第1个元素--数据框type1
listdataframe <- kpi[[1]]
运行代码,可以获取列表kpi的第一个元素——数据框type1。

或者采用成分的名称来获取列表中的元素
#创建列表时命名了数据框的名称为“diabetestype1”
listdataframe2 <- kpi[["diabetestype1"]]
运行代码,同样可以获取列表kpi的第一个元素——数据框type1。
七、总结
1、只能存储一种类型数据的数据结构
向量、矩阵、数组
2、能够存储多种数据类型的数据结构
数据框、列表
*注:查看题图更有助于理解

八、实践练习
1、读取病例数据xlsx。
2、获取病人数量(见上文)
3、患1型糖尿病的病人数量(见上文)

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31537575/viewspace-3143037/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2018-05-16

  • 博文量
    4259
  • 访问量
    40166