点击上方"蓝字"
关注我们吧!
0前言
上一篇我们介绍了R语言及RStudio的基本知识:
R语言教程(1)—— 基本知识
这一节话不多说,这一期直接进入主题,开始介绍R中的数据结构。这是学习R语言强大的统计分析功能的基础。R中自带了大量的数据集供大家在学习中联系。在开始介绍数据结构之前,先简单介绍以下如何查看及使用这些数据集,之后在介绍数据结构时,也会大量使用到这些数据集。
1 内置数据集
help(package='datasets')
:查看内置数据集
data()
:查看datasets包中所包含的数据集 可以通过数据集名字直接显示数据集数据:
也可以通过help()
函数,查看数据集具体内容:help("mtcars")
。
data(package="包名"
)可以查看包中的数据集。
data(package=.packages(all.available = TRUE))
可以显示R中所有可用的数据集。
2数据结构
2.1 数据类型
在介绍数据之前,需要简单了解以下常见的数据类型。数据类型主要包括:
- 数值型:可直接计算,加减乘除
- 字符串型:可以进行连接、转换、提取等
- 逻辑型:判断真假(TURE,FALSE)
- 日期型
一般编程语言中的数据结构:
- 向量
- 标量
- 列表
- 数组
- 多维数组
2.2 R中的对象(数据结构)
R中也有很多数据结构,统称为对象。对象,是指可以赋值给变量的任何事物,包括常量、数据结构、函数、甚至图形。 对象都拥有某种模式,描述了此对象是如何储存的,以及某个类。 R中的数据结构:
- 向量、标量
- 矩阵
- 数组
- 列表
- 数据框
- 因子
- 时间序列 ······
接下来我们将一一介绍这些对象的概念、以及如何创建、访问、修改并运算这些对象。
3 向量、标量
向量是R中最重要的概念,构成其他数据结构的基础。与数学中的向量概念不同。R中的向量类似于数学上集合的概念,由一个或多个元素构成。 向量适用于存储数值型、字符型或者逻辑型数据的一维数组。
3.1 向量基本概念
用函数c()
来创建向量。c代表concatenate,连接,也可以理解为收集collect.
x <- c(1,2,3,4,5)
y <- c("one","two")
z <- c(TRUE,FALSE)
注意:R中字符串一定要加引号,之前搜索包的时候,包名需加引号,否则就会将字符串当作对象(变量或者函数)在R中搜索,就会提示找不到。
代码语言:javascript复制c(1:100) # 快捷生成向量
seq(from=1,to=100) # 生成等差数列
seq(from=1,to=100,by=2) # 设置等差数列,d=2
seq(from=1,to=100,length.out=10) # length.out 设置个数为10个
rep(2,5) # 生成重复序列,生成5次2
rep(x,5)
rep(x,each=5) # each函数控制每个函数重复的次数
rep(x,each=5,times=2) # each和times重复使用,每个元素重复的次数就是二者的乘积
rep(x,c(2,1,3,4,5)) # 可以控制x中每个元素重复的次数
注意:向量中所有元素须为同一类型,方便计算。
mode()
函数可以查看向量的类型.
如果向量中只有一个元素可以直接赋值,如a = 1
,这种称为标量。
向量化编程与其他类型的编程言相比。在运算方面有着独有的优势:
> x <- c(1,2,3,4,5)
> b <- c(6,7,8,9,10)
> x*2 b
[1] 8 11 14 17 20
在R中可以直接进行x*2 b
这样的运算,在其他语言中则需要for循环才能实现。
3.2 向量索引
- 正(负)整数索引
- 逻辑向量索引
- 名称索引
这些索引方式同样可以应用于其他数据结构。
- 正整数索引
根据元素在集合中的位置索引,R中元素位置从1开始
代码语言:javascript复制x <- c(1:100)
length(x)
x[1] # 输出结果为1
x[-19] # 输出除了第19个元素外其他元素
x[c(4:18)] # R的向量化操作,输出4-18个元素
x[c(-2,3,4)] # 逻辑有无,报错
- 逻辑索引
y <- c(1:10)
y[c(T,F,T,T,F,T,F)] # 返回对应元素为TRUE的元素
y[c(T)] # 循环使用 只有一个逻辑值,会判断所有元素
y[c(F)] # 无结果
y[c(T,F)] # 输出奇数位置的元素
y[y>5] # 只输出大于5的元素
y[y>5 & y<9]
- 字符串索引
z <- c("one","two","three","four")
"one" %in% z # 输出为TRUE
z %in% c("one","two")
k <- z %in% c("one","two")
z[k] # 输出为"one" "two"
- 名称索引
names(y) <- c("one","two","three","four","five","six","seven","eight","nine","ten")
y["one"]
3.3 修改向量
- 添加元素
x[101] <- 101
## 批量添加
v <- 1:3
v[c(4,5,6)] <- c(4,5,6)
# 在向量中间插入一个元素
v[20] <- 4 # 未赋值元素部分都为NA
append(x=v,values = 99,after = 0) # 在v向量头部加入99的元素
- 删除元素
rm(v) # 删除整个向量
## 删除向量中某个元素
y <- y[-c(1:3)] # 删除y向量中1-3的元素
- 修改元素
v <- c(1:6)
v[2] <- 15 # 新的值会直接保存到原来的向量中
## 若赋值的元素为字符串,则向量将变为一个字符型向量
3.4 向量的运算
3.4.1 基本运算
- 向量内运算
> x <- 1:10
> x
[1] 1 2 3 4 5 6 7 8 9 10
> x 1
[1] 2 3 4 5 6 7 8 9 10 11
> x-3
[1] -2 -1 0 1 2 3 4 5 6 7
# 加减乘除同理
在R中是进行运算对向量中每一个元素进行操作,这就是向量化编程。
- 向量与向量运算——对应元素进行运算
> y <- seq(1,100,length.out= 10)
> y
[1] 1 12 23 34 45 56 67 78 89 100
> x y
[1] 3 15 27 39 51 63 75 87 99 111
> x*y
[1] 2 36 92 170 270 392 536 702 890 1100
> x**y # 求幂
[1] 2.000000e 00 5.314410e 05 7.036874e 13 5.820766e 23 1.039456e 35
[6] 2.115876e 47 3.213876e 60 2.697216e 74 1.000000e 89 1.378061e 104
> y%%x # 取余
[1] 1 0 3 4 3 0 3 6 9 1
> y %/% x # 整除
[1] 0 4 5 6 7 8 8 8 8 9
上述为元素个数相等情况,以下为元素不等情况
代码语言:javascript复制> x
[1] 2 3 4 5 6 7 8 9 10 11
> z <- c(1,2)
> x z
[1] 3 5 5 7 7 9 9 11 11 13
当元素数量不相等时,较短向量被循环使用,但是两者元素个数必须成倍数。否则会报错,如下所示:
代码语言:javascript复制> z <- 1:3
> x z
[1] 3 5 7 6 8 10 9 11 13 12
Warning message:
In x z : longer object length is not a multiple of shorter object length
向量之间运算总结:对应位置进行运算,长向量元素个数必须为短向量元素个数的倍数,以便于循环。
- 逻辑运算
> x > 5
[1] FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE
> x
[1] 2 3 4 5 6 7 8 9 10 11
> y
[1] 1 12 23 34 45 56 67 78 89 100
> x>y
[1] TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## 包含运算符
> c(1,2,3) %in% c(1,2,2,4,5,6)
[1] TRUE TRUE FALSE
## 比较两个向量是否相等
> x
[1] 2 3 4 5 6 7 8 9 10 11
> y
[1] 1 12 23 34 45 56 67 78 89 100
> x == y
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
3.4.2 运算函数
- 数学函数
> x <- -5:5
> x
[1] -5 -4 -3 -2 -1 0 1 2 3 4 5
> abs(x) # 取绝对值
[1] 5 4 3 2 1 0 1 2 3 4 5
> sqrt(25) # 平方根
[1] 5
> log(16,base = 2) # 取对数,第一个参数为要求的值,第二个参数为底数
[1] 4
> log(16) # 不设置底数,默认为自然对数
[1] 2.772589
> log10(10) # log10()函数可以直接求以10为底的对数
[1] 1
> exp(x) # 计算指数
[1] 6.737947e-03 1.831564e-02 4.978707e-02 1.353353e-01 3.678794e-01 1.000000e 00
[7] 2.718282e 00 7.389056e 00 2.008554e 01 5.459815e 01 1.484132e 02
> ceiling(c(-2.3,3.1415)) # 返回不小于元素的最大整数
[1] -2 4
> floor(c(-2.3,3.1415)) # 返回不大于元素的最大整数
[1] -3 3
> trunc(c(-2.3,3.1415))# 返回整数部分
[1] -2 3
> round(c(-2.3,3.1415),digits = 2) # 四舍五入,参数digits限制保留的位数
[1] -2.30 3.14
> signif(c(-2.3,3.1415),digits=2) # 与round类型,保留有效数字,参数digits设定有效数字的位数
[1] -2.3 3.1
- 统计函数
> vec <- 1:100
> sum(vec) # 求和
[1] 5050
> max(vec) # 最大值
[1] 100
> min(vec) # 最小值
[1] 1
> range(vec) # 返回一个数值向量中的最小值和最大值
[1] 1 100
> mean(vec) # 均值
[1] 50.5
> var(vec) # 方差
[1] 841.6667
> round(var(vec))
[1] 842
> round(var(vec),digits=2)
[1] 841.67
> round(sd(vec),digits=2) # 标准差
[1] 29.01
> prod(vec) # 连乘
[1] 9.332622e 157
> median(vec) # 中位数
[1] 50.5
> quantile(vec) # 分位数
0% 25% 50% 75% 100%
1.00 25.75 50.50 75.25 100.00
> quantile(vec,c(0.4,0.5))
40% 50%
40.6 50.5
> t <- c(1,4,2,5,6,4,7,9)
> which.max(t) # 返回符合条件元素的位置
[1] 8
> which.min(t)
[1] 1
> which(t>5)
[1] 5 7 8
> t[which(t>5)]
[1] 6 7 9
4 矩阵
向量:一维
矩阵:2维,矩阵需要有行和列。 在R中,矩阵是指有维数的向量,矩阵元素可以是数值型、字符型或者逻辑型。但是矩阵中每个元素必须为同一类型。
4.1 创建矩阵
通过函数matrix()
可以创建矩阵
> x <- 1:20
> m <- matrix(x,nrow=4,ncol=5)
> m
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 9 13 17
[2,] 2 6 10 14 18
[3,] 3 7 11 15 19
[4,] 4 8 12 16 20
> n <- matrix(1:20, nrow = 4, ncol = 5)
> n
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 9 13 17
[2,] 2 6 10 14 18
[3,] 3 7 11 15 19
[4,] 4 8 12 16 20
行列数必须能让构造矩阵的数据合理分配,否则报错:
代码语言:javascript复制> n <- matrix(1:20, nrow = 4, ncol = 6)
Warning message:
In matrix(1:20, nrow = 4, ncol = 6) :
data length [20] is not a sub-multiple or multiple of the number of columns [6]
> n <- matrix(1:20, nrow = 4, ncol = 4)
> n
[,1] [,2] [,3] [,4]
[1,] 1 5 9 13
[2,] 2 6 10 14
[3,] 3 7 11 15
[4,] 4 8 12 16
> matrix(x, nrow = 3, ncol = 3)
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
Warning message:
In matrix(x, nrow = 3, ncol = 3) :
data length [20] is not a sub-multiple or multiple of the number of rows [3]
矩阵构造,数据默认按照列分配,可以通过参数byrow修改
代码语言:javascript复制> m <- matrix(1:20,4)
> m
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 9 13 17
[2,] 2 6 10 14 18
[3,] 3 7 11 15 19
[4,] 4 8 12 16 20
> m <- matrix(1:20,4,byrow = T)
> m
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 6 7 8 9 10
[3,] 11 12 13 14 15
[4,] 16 17 18 19 20
为行和列命名:
代码语言:javascript复制> rnames <- c("R1","R2","R3","R4")
> cnames <- c("C1","C2","C3","C4","C5")
> dimnames(m) <- list(rnames,cnames)
> m
C1 C2 C3 C4 C5
R1 1 5 9 13 17
R2 2 6 10 14 18
R3 3 7 11 15 19
R4 4 8 12 16 20
> dim(m) # dim函数可以列出向量的维数
[1] 4 5
dim(x) <- c(4,5) # 将向量变成矩阵
> x
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 9 13 17
[2,] 2 6 10 14 18
[3,] 3 7 11 15 19
[4,] 4 8 12 16 20
4.2 矩阵索引
代码语言:javascript复制> m <- matrix(1:20,4,5,byrow = T)
> m
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 6 7 8 9 10
[3,] 11 12 13 14 15
[4,] 16 17 18 19 20
> m[1,2]
[1] 2
> m[1,c(2,3,4,)]
Error in c(2, 3, 4, ) : argument 4 is empty
> m[1,c(2,3,4)]
[1] 2 3 4
> m[c(1,2),c(2,3)]
[,1] [,2]
[1,] 2 3
[2,] 7 8
> m[2,]
[1] 6 7 8 9 10
> m[,2]
[1] 2 7 12 17
> m[2]
[1] 6
> m[-1,2]
[1] 7 12 17
> dimnames(m) <- list(rnames,cnames)
> m
C1 C2 C3 C4 C5
R1 1 2 3 4 5
R2 6 7 8 9 10
R3 11 12 13 14 15
R4 16 17 18 19 20
> m["R1","C2"]
[1] 2
4.3 矩阵运算
矩阵的四则运算需要两个矩阵行列数一致。
代码语言:javascript复制> m
C1 C2 C3 C4 C5
R1 1 2 3 4 5
R2 6 7 8 9 10
R3 11 12 13 14 15
R4 16 17 18 19 20
> m 1
C1 C2 C3 C4 C5
R1 2 3 4 5 6
R2 7 8 9 10 11
R3 12 13 14 15 16
R4 17 18 19 20 21
> m*2
C1 C2 C3 C4 C5
R1 2 4 6 8 10
R2 12 14 16 18 20
R3 22 24 26 28 30
R4 32 34 36 38 40
> m m
C1 C2 C3 C4 C5
R1 2 4 6 8 10
R2 12 14 16 18 20
R3 22 24 26 28 30
R4 32 34 36 38 40
> n <- matrix(1:20,5,4)
> n
[,1] [,2] [,3] [,4]
[1,] 1 6 11 16
[2,] 2 7 12 17
[3,] 3 8 13 18
[4,] 4 9 14 19
[5,] 5 10 15 20
> m n
Error in m n : non-conformable arrays
矩阵运算函数
代码语言:javascript复制> m[1,]
C1 C2 C3 C4 C5
1 2 3 4 5
> t <- m[1,]
> sum(t)
[1] 15
> colSums(m) # 对列求和
C1 C2 C3 C4 C5
34 38 42 46 50
> rowSums(m) # 对行求和
R1 R2 R3 R4
15 40 65 90
> colMeans(m) # 对列求均值
C1 C2 C3 C4 C5
8.5 9.5 10.5 11.5 12.5
> n <- matrix(1:9,3,3)
> t <- matrix(2:10,3,3)
> n*t # 内积
[,1] [,2] [,3]
[1,] 2 20 56
[2,] 6 30 72
[3,] 12 42 90
> n %*% t # 外积
[,1] [,2] [,3]
[1,] 42 78 114
[2,] 51 96 141
[3,] 60 114 168
> diag(n) # 列出主对角线元素
[1] 1 5 9
> t(m) # 转置
R1 R2 R3 R4
C1 1 6 11 16
C2 2 7 12 17
C3 3 8 13 18
C4 4 9 14 19
C5 5 10 15 20
5数组
5.1 创建数组
代码语言:javascript复制> x <- 1:20
> dim(x) <- c(2,2,5)
> x
, , 1
[,1] [,2]
[1,] 1 3
[2,] 2 4
, , 2
[,1] [,2]
[1,] 5 7
[2,] 6 8
, , 3
[,1] [,2]
[1,] 9 11
[2,] 10 12
, , 4
[,1] [,2]
[1,] 13 15
[2,] 14 16
, , 5
[,1] [,2]
[1,] 17 19
[2,] 18 20
array()
函数创建数组:
> dim1 <- c("A1","A2")
> dim2 <- c("B1","B2","B2")
> dim3 <- c("C1","C2","C3","C4")
> z <- array(1:24,c(2,3,4),dimnames = list(dim1,dim2,dim3))
> z
, , C1
B1 B2 B2
A1 1 3 5
A2 2 4 6
, , C2
B1 B2 B2
A1 7 9 11
A2 8 10 12
, , C3
B1 B2 B2
A1 13 15 17
A2 14 16 18
, , C4
B1 B2 B2
A1 19 21 23
A2 20 22 24
6列表
列表是用来储存很多内容的一个集合,列表是R中最复杂的数据结构。 列表就是一些对象的有序集合。列表中可以寸处若干向量、矩阵、数据框,甚至是其他列表的组合。
向量与列表
- 在模式上与向量类似,都是一维数据集合
- 向量只能存储一种数据类型,列表中的对象可以是R中的任何数据结构,包括列表本身
6.1 创建列表
代码语言:javascript复制> a <- 1:20
> b <- matrix(1:20,4,5)
> c <- mtcars
> d <- "This is a list"
> mlist <- list(a,b,c,d)
6.2 访问列表
代码语言:javascript复制> mlist <- list(first=a,second=b,third=c,forth=d)
> mlist[1]
$first
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
> mlist[1,4]
Error in mlist[1, 4] : incorrect number of dimensions
> mlist[c(1,4)] # 一次访问列表多个元素,需要使用向量
$first
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
$forth
[1] "This is a list"
> mlist$first # 通过元素名访问列表中的元素
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
> mlist[1]
$first
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
> mlist[[1]] #
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
> class(mlist[1]) # 一个中括号,输出的是列表的子集,仍为列表,因为如果一次访问多个元素,列表中元素类型不同,故输出结果只能为列表
[1] "list"
> class(mlist[[1]]) # 两个中括号,输出的是元素本身的数据类型
[1] "integer"
6.3 修该列表
代码语言:javascript复制> mlist[[5]] <- iris
> mlist
## 删除列表中的元素
> mlist <- mlist[-5] # 将删除某元素后的列表赋值给原来的列表
> mlist[[5]] <- NULL # 或者使用null清空该元素的值
7数据框
- 概念
数据框是一种表格式的数据结构,数据框旨在模拟数据集,与其他统计软件中的数据集概念一致。数据集通常是有数据构成的一个矩形数组,行表示观测,列表示变量。
- 特点
数据框实际上是一个列表。列表中的元素是向量,这些向量构成数据框的列,每一列必须具有相同的长度,所以数据框是矩形结构,而且数据框的列必须命名。
通过data.frame()
创建数据框:
> state <- data.frame(state.name,state.abb,state.region,state.x77)
> state
7.1 访问数据框
代码语言:javascript复制# 通过索引访问
> state[1] # 输出数据框第一列
> state[c(2,4)] #输出2,4列
> state[-c(2,4)] # R中负数索引表示去掉该部分内容
> state[,"state.abb"] # 利用行名和列名索引可以取出对应行和列
> state$state.name # 最常用的索引方式,$列名
> women
height weight
1 58 115
2 59 117
3 60 120
4 61 123
5 62 126
6 63 129
7 64 132
8 65 135
9 66 139
10 67 142
11 68 146
12 69 150
13 70 154
14 71 159
15 72 164
> plot(women$height,women$weight) # 通过这种索引方式,绘图比较方便
> lm(weight~height,data = women)
Call:
lm(formula = weight ~ height, data = women)
Coefficients:
(Intercept) height
-87.52 3.45
attach加载数据框到R搜索目录中,加载完成后,直接输入列名 就可以输出结果,不必通过$
索引。
> attach(mtcars)
> mpg
[1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4 10.4
[17] 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7 15.0 21.4
# detach函数,取消加载
> detach(mtcars)
> mpg
Error: object 'mpg' not found
with函数与attach功能类似,使用方法略有不同:
代码语言:javascript复制> with(mtcars,{mpg})
[1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4 10.4
[17] 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7 15.0 21.4
> with(mtcars,{sum(mpg)})
[1] 642.9
直接使用$
进行索引,代码较为清晰,所以推荐大家推荐使用这种索引方式。
8因子
因子这个概念对于学习R至关重要,这是统计学中比较常用的概念,在介绍因子之前,需要了解一下常用的变量分类:
- 名义型变量(分类数据)
- 有序性变量(顺序数据)
- 连续型变量(数值型数据)
8.1 定义
因子,在R中名义型变量和有序型变量称为因子,factor。 分类型变量的可能值称为一个水平,level。 例如考试成绩分为三个等级:A、B、C,都称为一个level。 由这些水平构成的向量就称为因子,上例中的考试等级就是因子。
8.2 应用
因子在统计学中应用非常广泛,常见的有:
- 计算频数
- 独立性检验
- 相关性检验
- 方差分析
- 主成分分析
- 因子分析
……
代码语言:javascript复制> ?mtcars
> mtcars$cyl
[1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4
> table(mtcars$cyl) # table函数用来进行频数统计
4 6 8
11 7 14
# 定义因子 factor函数
> f <- factor(c("red","red","green","blue"))
> f
[1] red red green blue
Levels: blue green red
> week <- factor(c("Mon","Fri","Thu","Wed","Mon","Fri","Sun"),ordered = T,levels = c("Mon","Tue","Wed","Thu","Fri","Sat","Sun")) # 设置因子的顺序
> week
[1] Mon Fri Thu Wed Mon Fri Sun
Levels: Mon < Tue < Wed < Thu < Fri < Sat < Sun
使用plot()
绘图,如果是向量,则自动绘制散点图,如果是因子,则绘制条形图:
> fcyl <- factor(mtcars$cyl)
> fcyl
[1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4
Levels: 4 6 8
> plot(mtcars$cyl)
代码语言:javascript复制> plot(factor(mtcars$cyl))
R的内置数据集state.division
就是因子类型的数据集:
> class(state.division)
[1] "factor"
后续的文章中会更新因子的各种使用场景,包括方差分析、因子分析等。大家持续关注哦~
OK,本期关于R语言数据结构的内容就介绍到这里,内容比较多,如果是初学者,建议勤加练习。毕竟编程语言的学习有个法则叫做:一万行代码法则。多写多练,熟能生巧。