由于本人学习R语言之前是个小白,所以这些东西都是以零基础的视角出发写下来的,学习R语言很重要的一点是了解R的数据结构(即用于存储数据的对象类型)有哪些,先按照个人要求的格式创建含有研究信息的数据集,这样才可以更好的对数据进行处理与分析。
1、介绍
R里面有五种数据结构:向量(vector)、矩阵(matrix)、数组(array)、数据框(data frame)和列表(list)。五种数据结构中,又可以简单分为两类:(1)向量、矩阵、数组,这三种数据结构的相同点在于均只能包含同一种数据类型,即要么都是数值型,要么都是字符型或者其他的任意一种数据类型,而不同点在于维度(dim),向量是一维的,矩阵是二维(行、列)的,数组是二维及二维以上(行、列、层)的,其实这三种数据类型互相是一种包含关系,R语言最基本的数据类型就是向量,矩阵也是向量,只不过多了行row与列column的划分,矩阵同时也是一个特殊的数组,即第三个维度为1的数组。(2)数据框和列表,这两者相同的地方在于可以包含不止一种数据类型,不同点在于维度,数据框是二维的,列表是二维及二维以上的。即,数据框中不同的列可以是不同数据类型,而列表的不同层也可以是不同的数据类型。列表可以说是R中数据类型最为复杂的一种,列表可以是这五种数据结构的一个有序集合,列表的每一层可以是向量,可以是矩阵,可以是数组,可以是数据框,甚至是其他列表。
介绍完了五种数据结构,首先给出各个不同数据结构的示例,接下来讲讲这五种数据结构的常用操作的异同。
2、示例
向量:
[1] 1 2 3 4 5
矩阵:
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
数组:
, , 1
[,1] [,2]
[1,] 1 2
, , 2
[,1] [,2]
[1,] 3 4
, , 3
[,1] [,2]
[1,] 5 6
数据框:
patientID age diabetes status
1 1 25 Type1 Poor
2 2 34 Type2 Improved
3 3 28 Type1 Excellent
4 4 52 Type1 Poor
列表:
$title
[1] "My First List"
$ages
[1] 25 26 18 39
[[3]]
[,1] [,2]
[1,] 1 6
[2,] 2 7
[3,] 3 8
[4,] 4 9
[5,] 5 10
[[4]]
[1] "one" "two" "three"
3、创建
五种数据结构的创建都非常简单,而创建需要的函数其实就是名称本身(向量除外)。下面演示一下上面的例子是如何被创建出来的。
向量:向量的创建常用c函数,c函数是R中经常会使用到的一个函数
c(..., recursive = FALSE)
示例:
> a <- c(1,2,3,4,5)
矩阵:矩阵的创建常用matrix()函数
matrix(data = NA, nrow = 1, ncol = 1, byrow = FALSE,dimnames = NULL)
示例:
> b <- matrix(1:12,nrow=3,ncol=4)
数组:数组的创建常用array()函数
array(data = NA, dim = length(data), dimnames = NULL)
示例:
> z <- array(1:24,c(1,2,3))
数据框:数据框的创建常用data.frame()函数
data.frame(..., row.names = NULL, check.rows = FALSE, check.names = TRUE, fix.empty.names = TRUE, stringsAsFactors = default.stringsAsFactors())
示例:
> patientID <- c(1,2,3,4)
> age <- c(25,34,28,52)
> diabetes <- c("Type1","Type2","Type1","Type1")
> status <- c("Poor","Improved","Excellent","Poor")
> patientdata <- data.frame(patientID,age,diabetes,status)
列表:列表的创建常用list()函数
list(...)
示例:
> g <- "My First List"
> h <- c(25,26,18,39)
> j <- matrix(1:10,nrow=5)
> k <- c("one","two","three")
> mylist <- list(title=g,ages=h,j,k)
注:对于向量有一点需要注意的地方,在R中并没有标量之说,对于标量,在R中默认为一元向量。除了使用c函数,同样可以使用其名称vector()函数来创建。
vector(mode = "logical", length = 0)
示例:
> vector("character", 5)
[1] "" "" "" "" ""
使用vector函数时,创建了一个特定的数据类型和长度的向量,如果是数值型,默认填充数字0,如果是逻辑型,默认填充False,如果是字符型,默认为空。
此外,向量的创建还可以使用:冒号(colon operator)创建一个序列,sequences()函数用于生成等差序列,seq.int() 创建一个步长为赋予by的数值的等差序列,seq_along() 创建一个从从1开始,长度等于输入值长度的序列,seq_len()创建一个从从1开始,长度为输入值的序列
seq(from = 1, to = 1, by = ((to - from)/(length.out - 1)), length.out = NULL, along.with = NULL, ...)
seq.int(from, to, by, length.out, along.with, ...)
seq_along(along.with)
seq_len(length.out)
示例:
> 3.5:5.5
[1] 3.5 4.5 5.5
> c(1,1:3,c(5,8),13)
[1] 1 1 2 3 5 8 13
> seq_along(c(3,4))
[1] 1 2
对于矩阵也有需要注意的地方,当给矩阵赋值时,赋值默认按列而不是按行进行。
4、维度
向量:length(),返回的是其中的元素的个数,也可以通过该函数给向量重新赋予新的长度,不足的部分用NA补齐,超过的部分会被删除。对于向量nrow()、ncol()返回NULL,可以使用NROW()和NCOL(),前者返回向量元素个数,后者恒为1(因为向量默认是一列)
示例:
> a
[1] 1 2 3 4 5
> length(a)
[1] 5
> length(a) <- 7
> length(a)
[1] 7
> a
[1] 1 2 3 4 5 NA NA
> length(a) <- 3
> a
[1] 1 2 3
矩阵:length(),返回行与列的乘积,即其中包含的所有元素的个数
dim(),返回矩阵的维度,也可以通过dim函数给矩阵重新赋予不同的行列组合。
nrow()与ncol(),分别返回向量的行数与列数
数组:length()、dim()、nrow()、ncol()
示例:
> length(patientdata)
[1] 4
> nrow(patientdata)
[1] 4
> ncol(patientdata)
[1] 4
数据框:dim()、nrow(),但是length()与ncol()返回相同的值,因为数据框是不同列的组合
列表:length()返回第三个维度,即有多少层。但是对于列表来说,dim()、nrow()、ncol()这三者不再有意义,会返回NULL(此时如果使用NROW()和NCOL()函数,不会返回NULL,但是此时这两个函数将列表看成向量,NROW()返回的是层,NCOL()只会返回1,因为向量只有一列)。
示例:
> length(mylist)
[1] 4
5、命名
向量:names()函数可以对向量的中各个元素的名称进行查询,如果有,则返回对应的名称向量,如果没有,则返回NULL,而对于向量中各个元素的命名也是使用该函数。unname()可以去掉元素名
names(x)
names(x) <- value,
示例:
> names(a)
NULL
> names(a) <- c("one","two","three","four","five")
> a
one two three four five
1 2 3 4 5
矩阵:rownames()、colnames()、dimnames()可以对矩阵的行名、列名、所有名称进行查询,矩阵在定义时便有参数可以设置名称,dimnames=list(...)可以对矩阵的各行各列进行命名,也可以在矩阵创建之后再使用该函数命名或者修改
dimnames(x)
dimnames(x) <- value
rownames(x, do.NULL = TRUE, prefix = "row")
rownames(x) <- value
colnames(x, do.NULL = TRUE, prefix = "col")
colnames(x) <- value
数组:同上
数据框:当赋值给数据框的变量都有名称时,数据框会自动将变量名称赋给每一列的变量。如果不希望,可以使用参数row.names = NULL除去变量自带的名称。rownames()、colnames()、dimnames()则与矩阵相似,但是names()返回结果与colnames()相同。
示例:
> colnames(patientdata)
[1] "patientID" "age" "diabetes" "status"
列表:从技术上讲,列表就是向量(都是一列,拥有多行元素,虽然不同行元素类型不同),所以对于列表的命名与向量相同
names(x)
names(x) <- value,
6、索引与筛选
向量:向量索引有四种方法,(1)、给向量传递一个正数x(表示位置,即第x行),返回从1到x列的所有列(R中第一列为1而非0)。(2)、给向量传递一个负数,返回除去该行的所有列。(3)、给向量传递逻辑值,返回所有逻辑值为TRUE的列。(4)、利用向量各个元素的名称进行索引。
索引符号为中括号[ ]
示例:
> a[2]
two
2
> a["two"]
two
2
> a[["two"]]
[1] 2
当向量各元素有名称时,按数字索引和名称索引都会使得输出结果带有名称,而如果希望输出结果不带名称时,可以使用双重中括号[[]]
使用上述方法,a[2:4]、a[-1]、a[c(FALSE,TRUE,TRUE,TRUE)]、a["two"]返回的结果相同。
此外,也可以利用条件对向量进行筛选,有三种方法:使用[]、which()函数和subset()函数,[]返回逻辑值,which()返回的是满足条件的元素所处位置,而subset()是截取出符合条件的元素
> x <- c((1:5)^2,NA)
> x
[1] 1 4 9 16 25 NA
> x>5
[1] FALSE FALSE TRUE TRUE TRUE NA
> x[x>5]
[1] 9 16 25 NA
> which(x>5)
[1] 3 4 5
> subset(x,x>5)
[1] 9 16 25
可以看到使用[]和另两种方法的区别在与对NA的处理不同
也可以利用[]对向量中的元素进行重新赋值(R中的向量实际是连续存储的,不能插入也不能删除元素,向量的大小在创建时已经确定,更改的时候实际上是重新定义一个新的向量,然后再覆盖原向量)
> x[x>5] <- 0
> x
[1] 1 4 0 0 0 NA
矩阵:矩阵同样有上述四种索引方式,区别在于矩阵具有行列的属性,在索引时需要表现出行和列
> b[1,3]
[1] 7
> b[2,]
[1] 2 5 8 11
矩阵的筛选操作与向量相同,但是which()函数返回的并不是矩阵,而是满足某一条件的所有元素组成的向量,而[]和subset函数返回的依然是筛选出来的子矩阵(对于所有数据结构而言,如果返回的是一行元素会被R默认当作向量处理,使用drop=FALSE参数可以防止返回向量)。
也可以利用与向量相同的筛选的方式对某一个元素、某一行、某一列或者满足条件的所有元素进行重新赋值。
> b[b>7]
[1] 8 9 10 11 12
> b[b>7]<-0
> b
[,1] [,2] [,3] [,4]
[1,] 1 4 7 0
[2,] 2 5 0 0
[3,] 3 6 0 0
> b[,2]>4
[1] FALSE TRUE TRUE
> b[b[,2]>4,]
[,1] [,2] [,3] [,4]
[1,] 2 5 8 11
[2,] 3 6 9 12
> which(b>3)
[1] 4 5 6 7 8 9 10 11 12
> subset(b,select=1,drop=FALSE)
[,1]
[1,] 1
[2,] 2
[3,] 3
需要注意的是,使用于向量的运算也都适用于矩阵,因为矩阵也是向量
数组:subset()函数不能用于数组,[]和which的操作与矩阵相同
数据框:适用于向量的索引方式同样适用于数据框,此外,如果希望输出不带名称的结果,可以适用双重中括号[[]]或者美元符号$,而对于筛选方式(中括号[]、which()函数、subset()函数),不仅需要注意行与列,同时也应该注意数据框可能含有多种数据类型,当按条件进行筛选时最好指定到相应的列
> patientdata$age
[1] 25 34 28 52
patientdata$a、patientdata[["age"]]可以返回相同的结果。
> which(patientdata$age>26)
[1] 2 3 4
列表:适用于向量的索引方式同样适用于数据框,此外,如果希望输出不带名称的结果,可以适用双重中括号[[]]或者美元符号$,与向量不同的是列表可以进行嵌套索引
> mylist[1:2]
$title
[1] "My First List"
$ages
[1] 25 26 18 39
mylist[c(-3,-4)]、mylist[c("title","ages")]、mylist[c("TRUE","TRUE","FALSE","FALSE")]这三者与上述返回结果相同
> mylist[[4]][[1]]
[1] "one"
> mylist$title
[1] "My First List"
等价于mylist[[1]]、mylist[["title"]]、mylist$t
值得注意的是,当索引列表中不存在的一项元素时,适用双重中括号直接索引会返回error,其他索引方式返回NULL
> mylist["fi"]
$<NA>
NULL
> mylist[[5]]
Error in mylist[[5]] : 下标出界
7、运算
(之后会详细讲数据分析,所以在此只略讲)
R中的运算符有:
算术运算符 | 含义 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
^ | 幂 |
** | 幂 |
x%%y | 余数 |
x%/%y | 整除 |
逻辑运算符 | 含义 |
---|---|
< | 小于 |
> | 大于 |
<= | 小于等于 |
>= | 大于等于 |
== | 严格等于 |
!= | 不等于 |
!x | 非x |
x&y | x和y |
x&$y | x和y (针对标量) |
isTRUE(x) | 测试x是否为TRUE |
向量:向量的算术运算实际上两个向量间两两对应元素的运算,当两向量长度相同时,一一对应即可,长度不同时,如果两者长度为整数倍,则较短的向量自动扩展
> a
one two three four five
1 2 3 4 5
> m <- c(3,4)
> a+m
one two three four five
4 6 6 8 8
Warning message:
In a + m : 长的对象长度不是短的对象长度的整倍数
> m <- c(3)
> a+m
one two three four five
4 5 6 7 8
矩阵:矩阵与向量相加只需要为整数倍,向量会自动扩展。如果两矩阵相加则要求维度相同
数组:与矩阵相同
数据框:略
列表:略
8、其他
any()函数和all()函数分别报告其参数是否至少有一个或者全部为TRUE
当直接对向量适用比较运算符时返回的是布尔逻辑向量
c()函数可以直接合并两个不同维度的矩阵、矩阵和向量并返回一个向量,也可以合并列表和向量,返回列表(其中向量中每个元素被转换成列表),也可以合并列表和矩阵,返回列表(其中矩阵中的每个元素都被转换成列表)
as.list()可以把向量转换成列表
unlist()把列表转换成向量
rep()函数用重复的元素创造向量,times参数表示重复的次数,length.out参数表示输出长度,each参数表示每一个元素重复的次数
rep(x, ...)
rep.int(x, times)
rep_len(x, length.out)
> rep(1:5)
[1] 1 2 3 4 5
> rep(1:5,3)
[1] 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
> rep(1:5,each=3)
[1] 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5
> rep.int(1:5,3)
[1] 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
> rep_len(1:5,3)
[1] 1 2 3
声明:该学习笔记的内容参考了《R in action》、《R语言编程艺术》、《Learning R》这三本书,是本人一点一点总结、一点一点敲出来的。写下这个学习笔记是为了督促自己更好的学习、总结与巩固,也希望可以帮到需要帮助的人
网友评论