每种语言都有自己的数据结构,这些数据结构多多少少会有些相似之处,利用这些相似之处大部分时候都能提高我们的学习效率。由于初学编程时学的是Python,因此这里很多地方多会与Python进行比较以方便理解记忆。
R语言数据结构依据存放类型类型可分为两类,一类是用来存放同类型数据的(如int,character,bool等其中的一种类型,称为同质),另一类则是可以用来存放不同类型的数据,可称为异质。
维度 | 同质 | 异质 |
---|---|---|
1维 | 原子向量(Atomic vector) | List |
2维 | 矩阵(Matrix) | Data frame |
多维 | Array |
1、向量(Atomic Vectors)
向量是用于储存int、character、bool等数据的一维数据结构,单个向量中的数据必须拥有相同类型。使用函数c()
来创建向量。R中的向量可以看作是Python中具有相同数据结构的非嵌套列表。
> v <- c(1:3,'a','b'); v
[1] "1" "2" "3" "a" "b"
这里尝试在一个向量中存储数值型和字符型数据,可以发现输出结果中所有数据都被转换成了字符型数据。
当不同类型的数据使用c()函数创建atomic vector时,因为atomic vector的元素都必须是同质的,所以系统会依照character, double, integer, logical的优先顺序对数据类型进行转换。
2、列表(List)
R中的列表类似于Python中的字典,可以存放各种不同的数据结构和嵌套数据结构,R中列表可以人为的给予其赋予名字(相当于Python字典中的键,也可看做数据框中的列名)未赋予名字时,系统会按索引给R列表中各个数据赋予名字。使用list()
创建列表。使用names()
可以给列表中的各个元素命名。
#列表一般创建方式
mylist <- list(obj1, obj2, ...)
#也可以创建时对列表元素命名
mylist <- list(name1=obj1, name2=obj2, ...)
> l <- list(c(1:3),c(T,F)); l
[[1]]
[1] 1 2 3
[[2]]
[1] TRUE FALSE
> names(l) <- c('num','bool'); l
$num
[1] 1 2 3
$bool
[1] TRUE FALSE
> l$num
[1] 1 2 3
3、矩阵(Matrix)
矩阵是一个二维数组,其所有数值类型相同(int,character,bool)。可通过matrix()
创建矩阵。matrix可使用下标或行列名来获取元素,但不支持$name
的索引方式。可使用dimnames()
或rownames()
、colnames()
对其进行matrix的行列进行重命名。
#matrix一般创建方式
mymatrix <- matrix(vector, nrow, ncol, byrow, dimnames)
> m <- matrix(letters[1:12],nrow=3,ncol=4,byrow=TRUE);m
[,1] [,2] [,3] [,4]
[1,] "a" "b" "c" "d"
[2,] "e" "f" "g" "h"
[3,] "i" "j" "k" "l"
> dimnames(m) <- list(c('one','two','three'),c('J','K','L','V')); m
J K L V
one "a" "b" "c" "d"
two "e" "f" "g" "h"
three "i" "j" "k" "l"
> m['one','J']; m[1,1]
[1] "a"
[1] "a"
> m$'one'
Error in m$one : $ operator is invalid for atomic vectors
从上面可以看出matrix属于atomic vector。
4、数组(Array)
数组与矩阵类似,都为同质型的数据结构,但是维度大于2。数组通过array创建。
> dim1 <- c(letters[1:2]); dim2 <- c(letters[3:5]); dim3 <- c(letters[6:9])
> arr <- array(c(1:24),c(2,3,4),dimnames=list(dim1,dim2,dim3)); arr
, , f
c d e
a 1 3 5
b 2 4 6
, , g
c d e
a 7 9 11
b 8 10 12
, , h
c d e
a 13 15 17
b 14 16 18
, , i
c d e
a 19 21 23
b 20 22 24
> arr[1,2,3]
[1] 15
5、数据框(data.frame)
数据框在形式上与矩阵较为类似,但是它每一列的数据类型可以不同,为异质型数据结构。数据框可以使用data.frame()
函数来创建,使用colnames()
和rownames()
来对行列重命名。数据框与python三方库pandas中的DataFrame基本是一样的。
数据框选取元素的方式较为多样,既可以通过下标进行选取,也可以通过列名称来进行选取df$name
。同时,在创建数据框时可通过row.names
参数指定用来作为行名称的列。
> s <- c(85:90); a <- rep(c(15,16),3); g <- rep(c('A','B'),3)
> df <- data.frame(s,a,g)
> df
s a g
1 85 15 A
2 86 16 B
3 87 15 A
4 88 16 B
5 89 15 A
6 90 16 B
> colnames(df)<-c('score','age','grade'); df
score age grade
1 85 15 A
2 86 16 B
3 87 15 A
4 88 16 B
5 89 15 A
6 90 16 B
> df[1]
score
1 85
2 86
3 87
4 88
5 89
6 90
> df[1,2]
[1] 15
> df$score
[1] 85 86 87 88 89 90
> df[c(1,2)]
score age
1 85 15
2 86 16
3 87 15
4 88 16
5 89 15
6 90 16
> df[c('score','age')]
score age
1 85 15
2 86 16
3 87 15
4 88 16
5 89 15
6 90 16
若需要多次选取数据框中的某列数据,可使用attach()
、detach()
、或with()
来简化代码。
> attach(df)
> age
[1] 15 16 15 16 15 16
> detach(df)
> age
Error: object 'age' not found
> with(df,{print(age)})
[1] 15 16 15 16 15 16
各种数据结构的元素命名方式如下表:
数据类型 | 函数 | 接受的参数类型 |
---|---|---|
向量和列表 | names | 向量 |
矩阵和数组 | dimnames | 列表 |
矩阵和数据框 | rowname, colname | 向量 |
6、因子(factors)
因子比较难以理解,可以将它看作是Python中的set(list)
,即对向量进行分类计算,每一个唯一值算一个一个分类。他有levels()
方法,可以得到一个factor中的所有水平(也即去重后的集合)。他的创建分为三步:(1)将输入的数据转换成character类型;(2)对所有水平进行排序(若未指定排序则自然排序);(3)使用levels中的水平序号重新编码输入的元素。
> grade <- factor(df$grade);grade
[1] A B A B A B
Levels: A B
> grade <- factor(df$grade, levels=c('B','A'));grade
[1] A B A B A B
Levels: B A
>levels(grade)
[1] "B" "A"
在构建data.frame时,列元素为character的列经常会自动被转换为factors,这常常不是我们想看到的。通过指定stringsAsFactors=FALSE
参数可保留原本的character属性。
> s <- c(85:90); a <- rep(c(15,16),3); g <- rep(c('A','B'),3)
> df <- data.frame(s,a,g)
> str(df)
'data.frame': 6 obs. of 3 variables:
$ s: int 85 86 87 88 89 90
$ a: num 15 16 15 16 15 16
$ g: Factor w/ 2 levels "A","B": 1 2 1 2 1 2
> s <- c(85:90); a <- rep(c(15,16),3); g <- rep(c('A','B'),3)
> df <- data.frame(s,a,g,stringsAsFactors=FALSE)
> str(df)
'data.frame': 6 obs. of 3 variables:
$ s: int 85 86 87 88 89 90
$ a: num 15 16 15 16 15 16
$ g: chr "A" "B" "A" "B" ...
处理数据的一些实用函数
函数 | 作用 |
---|---|
length | 显示对象中元素的数量 |
dim | 显示某个对象的维度 |
str | 查看某个对象的结构 |
class | 查看某个对象的类型 |
mode | 查看某个对象的模式 |
names | 查看某个对象中各个成分的名称 |
cbind | 按列合并兑现 |
rbind | 按行合并对象 |
head | 查看某个对象的开始部分 |
tail | 查看某个对象的结尾部分 |
ls | 显示当前的变量列表 |
rm | 删除一个或更多对象。语句rm(list=ls())将删除当前工作环境的所有对象(隐藏对象除外) |
> df
s a g
1 85 15 A
2 86 16 B
3 87 15 A
4 88 16 B
5 89 15 A
6 90 16 B
> length(df)
[1] 3
> dim(df)
[1] 6 3
> class(df)
[1] "data.frame"
> mode(df)
[1] "list"
> names(df)
[1] "s" "a" "g"
> gender<-rep(c('male','female'),3);df<-cbind(df,gender=gender);df
s a g gender
1 85 15 A male
2 86 16 B female
3 87 15 A male
4 88 16 B female
5 89 15 A male
6 90 16 B female
> df<-rbind(df,c(100,10,'A','female'));df
s a g gender
1 85 15 A male
2 86 16 B female
3 87 15 A male
4 88 16 B female
5 89 15 A male
6 90 16 B female
7 100 10 A female
> ls()
[1] "a" "arr" "d" "depth_dist" "df" "dim1"
[7] "dim2" "dim3" "g" "gender" "grade" "i39"
[13] "l" "m" "model" "mpg2" "norm" "oplot"
[19] "p" "plot" "s" "sleep" "v"