前言
学习数据结构是了解一门编程语言的基础,以此你可以了解数据是如何被存储、管理以及分析的。R语言作为一门统计分析语言,具有丰富的数据结构,熟悉这些数据结构将十分有助于了解R的工作方式。
数据结构
向量
向量是用于存储数值型、字符型或逻辑型数据的一维数组。
函数 c() 可用来创建向量;通过在方括号中给定元素所处位置的数值来访问向量中的元素。
示例
> a <- c("k","j","h","a","b","c","m")
> a[3]
[1] "h"
> a[c(1,3,5)]
[1] "k" "h" "b"
> a[2:6]
[1] "j" "h" "a" "b" "c"
矩阵
矩阵可看作二维数组,类似于向量,矩阵也只能存储数值型、字符型或逻辑型数据中的一种。矩阵可通过函数 matrix() 来创建。
一般使用格式为
mymatrix <- matrix(data , nrow, ncol, byrow = FALSE, dimnames)
# nrow 和 ncol 用来指定矩阵的行数与列数;byrow 用来指明矩阵是按行填充还是按列填充,默认为按列填充;dimnames 用来指明矩阵的行名与列名。
示例
> cells <- c(1,26,24,68)
> rnames <- c("R1","R2")
> cnames <- c("c1","c2")
> mymatrix <- matrix(cells,nrow = 2,ncol = 2,byrow = F,dimnames = c(rnames,cnames))
Error in matrix(cells, nrow = 2, ncol = 2, byrow = F, dimnames = c(rnames, : 'dimnames' must be a list
# 此处程序报错是因为参数 dimnames 应为 list,不能用函数 c() 创建
> mymatrix <- matrix(cells,nrow = 2,ncol = 2,byrow = F,dimnames = list(rnames,cnames))
> mymatrix
c1 c2
R1 1 24
R2 26 68
矩阵的访问同样可以使用下标和方括号的方式,选择多行多列时,下标 i 和 j 可为数值型向量。
> x <- matrix(1:10,nrow = 2)
> x
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 5 7 9
[2,] 2 4 6 8 10
> x[2,]
[1] 2 4 6 8 10
> x[1,c(4,5)]
[1] 7 9
数组
数组与矩阵类似,但是维度可以大于2。数组通过array()函数创建。形式如下
array(data, dim = length(data), dimnames)
# data包含了数组中的数据,dim是一个数值型向量,给出了各个维度下标的最大值,dimnames是可选的、各维度名称标签的列表。
示例
> dim1 <- c("A1","A2")
> dim2 <- c("B1","B2","B3")
> dim3 <- c("C1","C2","C3","C4")
> z <- array(1:24,c(2,3,4),dimnames = list(dim1.dim2,dim3))
Error in array(1:24, c(2, 3, 4), dimnames = list(dim1.dim2, dim3)) :
object 'dim1.dim2' not found
> z <- array(1:24,c(2,3,4),dimnames = list(dim1,dim2,dim3))
> z
, , C1
B1 B2 B3
A1 1 3 5
A2 2 4 6
, , C2
B1 B2 B3
A1 7 9 11
A2 8 10 12
, , C3
B1 B2 B3
A1 13 15 17
A2 14 16 18
, , C4
B1 B2 B3
A1 19 21 23
A2 20 22 24
像矩阵一样,数组中的数据也只能拥有一种模式,数组元素的选取方式和矩阵相同,使用下标和方括号的方式。
数据框
数据框是R中最常使用的数据结构,不同于之前介绍的向量、矩阵和数值,数据框中的数据可以具有多种模式(如数值型、字符型或逻辑型)。
数据框可通过data.frame()函数创建,一般形式如下
data.frame(col1,col2,col3,..., row.names = NULL, check.rows = FALSE,
check.names = TRUE, fix.empty.names = TRUE,
stringsAsFactors = default.stringsAsFactors())
# 其中的列向量col1,col2,col3等可为人和类型(如数值型、字符型或逻辑型),每一列的名称可由函数names指定。
示例
> patientID <- c(1,2,3,4)
> age <- c(25,34,35,54)
> diabetes <- c("Type1","Type2","Type1","Type2")
> status <- c("Poor","Improved","Excellent","Poor")
> patientdata <- data.frame(patientID,age,diabetes,status)
> patientdata
patientID age diabetes status
1 1 25 Type1 Poor
2 2 34 Type2 Improved
3 3 35 Type1 Excellent
4 4 54 Type2 Poor
选取数据框中元素的方式有若干种,可以使用前述(如矩阵中的)下标记号,亦可直接指定列名,也可使用记号$来选定给定数据框中的某个特定变量(列)。
> patientdata[1:2]
patientID age
1 1 25
2 2 34
3 3 35
4 4 54
> patientdata[1,c(3,4)]
diabetes status
1 Type1 Poor
> patientdata[c("diabetes","status")]
diabetes status
1 Type1 Poor
2 Type2 Improved
3 Type1 Excellent
4 Type2 Poor
> patientdata$diabetes
[1] Type1 Type2 Type1 Type2
Levels: Type1 Type2
除此之外,可以联合使用函数attach()和detach()或单独使用函数with()来选取元素,这里不再介绍。
因子
在R中,变量可归结为名义型、有序型和连续型变量。
名义型变量 是没有顺序之分的类别型变量。糖尿病类型Diabetes(Type1、Type2)是名义型的一例,即使在数据中Type1编码为1,Type2编码为2,也并不意味着二者是有序的。
有序型变量,顾名思义表示一种顺序关系,而非数量关系。如病情status(Poor、Improved、Excellent)就是一个很好的例子,病情为Poor的病人状态不如病情为Excellent的病人,但我们不知道具体相差多少。
连续型变量 可以呈现为某个范围内的任意值,同时表示了顺序和数。如年龄age就是一个连续型变量,它能够表示像14.6或23.4这样的值及其间的其他任意值。很清楚,15岁的人比14岁的人年长一岁。
类别(名义)型变量或有序类别(有序)型变量在R中被称为因子,它们被特殊地存储和处理。
函数factor()以一个整数向量的形式存储类别值,整数的取值范围是[1...k](其中k是名义型变量中唯一值的个数,也即类别数),同时一个由字符串(原始值,即类别名)组成的内部向量将映射到这些整数上。
以上这段话看起来有点难以理解,简单点来说就是,R将变量分为两大类,类别型和非类别型(即连续型),类别型变量又分为有序和无序型(即名义型),它们在R中是用因子这一数据结构来存储管理的。这些变量为字符型向量,但在存储时是以整数向量的形式来存储的,R以一定的方式将每一个类别名都映射到一个整数上,并以整数形式存储。
对于名义型变量,具体赋值根据字母顺序而定
> diabetes <- c("Type1","Type2","Type1","Type1") #新建一个字符型向量
> diabetes
[1] "Type1" "Type2" "Type1" "Type1"
> daibetes <- factor(diabetes) #将该向量转变为因子
> daibetes
[1] Type1 Type2 Type1 Type1
Levels: Type1 Type2
#语句daibetes <- factor(diabetes) 将此向量存储为(1,2,1,1),并在内部将其关联为1=Type1,2=Type2(由字母顺序而定,并不是出现的先后顺序)
对于有序型变量,需要为函数factor()指定参数ordered=TRUE。给定向量:
> status <- c("Poor","Improved","Excellent","Poor")
> status
[1] "Poor" "Improved" "Excellent" "Poor"
> status <- factor(status, ordered = T)
> status
[1] Poor Improved Excellent Poor
Levels: Excellent < Improved < Poor
对于字符型向量,因子的水平默认按字母顺序创建。此外,也可以通过指定levels选项来覆盖默认排序。数值型变量也可以用levels和labels参数来编码成因子。例如:
> status <- factor(status,ordered = T,levels=c("Poor","Improved","Excellent")) #需要保证指定的水平与数据值的真实值相匹配
> status
[1] Poor Improved Excellent Poor
Levels: Poor < Improved < Excellent
列表
列表是R的数据类型中最为复杂的一种。一般来说,列表就是一些对象(或成分)的有序集合,某个列表中可能是若干向量、矩阵、数据库,甚至其他列表的组合。
可以使用函数list()创建列表:
> g <- "My First List"
> h <- c(25,26,39,40)
> j <- matrix(1:10,nrow = 5)
> k <- c("one","two","three")
> mylist <- list(title=g,ages=h,j,k)
> mylist
$title
[1] "My First List"
$ages
[1] 25 26 39 40
[[3]]
[,1] [,2]
[1,] 1 6
[2,] 2 7
[3,] 3 8
[4,] 4 9
[5,] 5 10
[[4]]
[1] "one" "two" "three"
可以通过在双重方括号中指明代表某个成分的数字或名称来访问列表中的元素
> mylist[[2]]
[1] 25 26 39 40
> mylist[["ages"]]
[1] 25 26 39 40
一些注意事项
- R不提供多行注释或块注释功能。你必须以#作为多行注释每行的开始。
- R中没有标量。标量以单元素向量的形式出现。
- R中的下标不从0开始,而从1开始。这点与很多语言都不相同。
- 变量无法被声明。它们在首次赋值时被生成。
参考资料
R语言实战(第2版)
网友评论