R的数据结构
R拥有许多用于存储数据的对象类型,包括标量、向量、矩阵、数组、数据框和列表。
向量
向量是用于存储数值型、字符型或逻辑型数据的一维数组。执行组合功能的函数c()可用来创建向量。单个向量中的数据必须拥有相同的类型或模式。
> a <- c(1,2,3,4)
> a[3]
[1] 3
矩阵
矩阵是一个二维数组,只是每个元素都拥有相同的模式(数值型、字符型或逻辑型。可通过函数matrix创建矩阵。一般使用格式为:
vector 包含了矩阵的元素
nrow 和 ncol 用以指定行和列的维数
dimnames 包含了可选的、以字符型向量表示的行名和列名
byrow 则表明矩阵应当按行填充(byrow=TRUE)还是按 列填充( byrow=FALSE ),默认情况下按列填充。
> x <- matrix(a,2)
> x[,2]
[1] 3 4
> x[2,]
[1] 2 4
> x[2,2]
[1] 4
在R语言的语法中,无论是从矩阵还是向量中提取元素,均采用[ ]的形式。
数组
数组(array)与矩阵类似,但是维度可以大于2。数组可通过array函数创建,形式如下:
vector 包含了数组中的数据;
dimensions 是一个数值型向量,给出了各个维度下标的最大
dimnames 是可选的、各维度名称标签的列表。
dim1 <- c("A1","A2")
dim2 <- c("B1","B2","B3")
dim3 <- c("C1","C2","C3","C4")
my_array <- array(1:24,c(2,3,4),dimnames = list(dim1,dim2,dim3))
> my_array #下面这个是一个三维向量,三个维度分别是dim1, dim2, dim3
, , 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
数据框(生信分析中最重要的数据结构)
由于不同的列可以包含不同模式(数值型、字符型等)的数据,数据框的概念较矩阵来说更为一般。数据框的使用格式:
其中的列向量col1, col2, col3,… 可为任何类型(如字符型、数值型或逻辑型)。
每一列的名称可由函数names指定。
names函数与python中的dictionary相似,可以对比理解,下面有一个例子:
b <- c("AA","AT","TA")
names(b) <- c("geno1","geno2","geno3")
> names(b)[1] #查看b的名字
[1] "geno1"
> b["geno1"] #当起名成功后,可以通过名字直接找到他
geno1
"AA"
当然,在R中命名的函数不止names一个,下面是常用的几个函数的对比,防止混淆:
> PatientID <- c(1,2,3,4)
> Age <- c(23,46,54,43)
> diabetes <- c("Type1","Type2","Type1","Type2")
> status <- c("Poor","Excellent","Poor","Poor")
> patientdata_frame <- data.frame(PatientID,Age,diabetes,status)
> patientdata_frame
PatientID Age diabetes status
1 1 23 Type1 Poor
2 2 46 Type2 Excellent
3 3 54 Type1 Poor
4 4 43 Type2 Poor
> patientdata_frame[1:2] #通过列序号提取数据列
PatientID Age
1 1 23
2 2 46
3 3 54
4 4 43
> patientdata_frame[c("PatientID","Age")] #通过列名提取数据列
PatientID Age
1 1 23
2 2 46
3 3 54
4 4 43
> patientdata_frame$Age #选取一个给定数据框中的某个特定变量。
[1] 23 46 54 43
当我们想要从数据框列联表时,使用table函数,例如我们想要研究Age和status的相互作用,需要将这两列提取出来,如下:
> new_table <- table(patientdata_frame$Age,patientdata_frame$status)
> new_table
Excellent Poor
23 0 1
43 0 1
46 1 0
54 0 1
我们顺便来学习以下table函数,table 函数对应的就是统计学中的列联表,是一种记录频数的方法,对于统计来说有非常重要的应用。
> ct <- data.frame(
+ Vote.for.X = factor(c("Yes", "Yes", "No", "Not Sure", "No"), levels = c("Yes", "No", "Not Sure")),
+ Vote.for.X.Last.Time = factor(c("Yes", "No", "No", "Yes", "No"), levels = c("Yes", "No"))
+ )
> ct
Vote.for.X Vote.for.X.Last.Time
1 Yes Yes
2 Yes No
3 No No
4 Not Sure Yes
5 No No
> cttab <-table(ct)
> cttab
Vote.for.X.Last.Time
Vote.for.X Yes No
Yes 1 1
No 0 2
Not Sure 1 0
在病例数据中,PatientID 用于区分数据集中不同的个体。在R中,实例标识符(case identifier)可通过数据框操作函数中的rowname选项指定。例如,语句:
patientdata_frame <- data.frame(PatientID,Age,diabetes,status,row.names = PatientID)
因子
变量可归结为名义型、有序型或连续型变量。名义型变量是没有顺序之分的类别变量。有序型变量表示一种顺序关系,而非数量关系。类别(名义型)变量和有序类别(有序型)变量在R中称为因子(factor)。函数factor()以一个整数向量的形式存储类别值,我们可以理解为将因子与整数1、2、3等建立映射,1、2、3分别代表哪个与因子的首字母有关,但是当我们处理有序型变量或者我们相对顺序进行规定时,可以通过指定levels选项来覆盖默认排序。
> PatientID <- c(1,2,3,4)
> Age <- c(23,46,54,43)
> diabetes <- c("Type1","Type2","Type1","Type2")
> status <- c("Poor","Excellent","Poor","Poor")
> diabetes <- factor(diabetes)
> status <- factor(status,ordered = TRUE,levels = c("Poor","Excellent"))
> patientdata_frame <- data.frame(PatientID,Age,diabetes,status)
> str(patientdata_frame) #str函数用于查看对象的信息
'data.frame': 4 obs. of 4 variables:
$ PatientID: num 1 2 3 4
$ Age : num 23 46 54 43
$ diabetes : Factor w/ 2 levels "Type1","Type2": 1 2 1 2 #diabetes是因子
$ status : Ord.factor w/ 2 levels "Poor"<"Excellent": 1 2 1 1 #status是有序因子,且符合我们预设的Poor数字小,Excellent数字大
列表
列表(list)是R的数据类型中最为复杂的一种。
一般来说,列表就是一些对象(或成分,component)的有序集合。
创建列表使用list()函数:
# 新建一个列表
> list_name = "My Personal Information"
> age = 23
> stu = TRUE
> my_list = list(list_name,age,stu)
> print(my_list)
[[1]]
[1] "My Personal Information"
[[2]]
[1] 23
[[3]]
[1] TRUE
#给列表中的元素命名,用前文提过的namae函数
> names(my_list) <- c("listname","age","student")
> print(my_list)
$listname
[1] "My Personal Information"
$age
[1] 23
$student
[1] TRUE
# 利用数字和名字查找列表中元素
> print(my_list[1])
$listname
[1] "My Personal Information"
> print(my_list["listname"])
$listname
[1] "My Personal Information"
在实际操作中,列表需要被转换为一个向量,以便能用于进一步操纵向量的元素。所有关于向量的算术运算可以在列表被转换为矢量之后被应用。要做到这一点转换,使用unlist() 函数。它以列表作为输入,并产生一个向量。
# 将两个列表转化为向量,并对向量进行计算
> list1 = list(1:10)
> list2 = list(46:55)
> print(list1)
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
> print(list2)
[[1]]
[1] 46 47 48 49 50 51 52 53 54 55
> v1 = unlist(list1)
> v2 = unlist(list2)
> print(v1)
[1] 1 2 3 4 5 6 7 8 9 10
> print(v2)
[1] 46 47 48 49 50 51 52 53 54 55
> sum = v1 + v2
> print(sum)
[1] 47 49 51 53 55 57 59 61 63 65
最后我们来来简要总结一下实用的数据对象处理函数: