@evilking
2017-10-15T10:37:46.000000Z
字数 4998
阅读 1174
R基础篇
数据框同样是R中非常重要也是最常用的数据结构之一,一般可以用来操作数据表
从直观上看,数据框类似于矩阵,有行和列两个维度,与矩阵不同的是,数据框的每列可以具有不同的模式(mode),例如一列是数值型数据,另一列是字符型数据
从技术层面而言,数据框是每个组件长度都相等的列表,按列排列存储
> id <- c(1:5)
> name <- c("Tom","Jack","Rose","Ketty","Hello")
> salary <- seq(from=2000,to=6000,by=1000)
> (x <- data.frame(id,name,salary,stringsAsFactors = FALSE))
id name salary
1 1 Tom 2000
2 2 Jack 3000
3 3 Rose 4000
4 4 Ketty 5000
5 5 Hello 6000
> names(x)
[1] "id" "name" "salary"
>
实例代码的前三句好理解,就是分别生成了三个长度为5的向量,最后一句就是利用data.frame()
来生成数据框
该函数的前面三个参数表示三个向量,作为数据源来填充数据框,按列排列,每个向量在数据框中就成了一个字段,字段名即为向量对象的字符串名
最后一个stringsAsFactors=FALSE
参数就表示不将字符串自动转换为“因子”(factor),保留字符串的属性,该参数默认去TRUE,表示会自动将字符串转换为“因子”
关于因子的概念我们在后面篇幅中专门讲解
一般使用read.table()
等函数从文件中读取数据,读取的结果也是一个数据框,例如我们在R的工作空间中创建一个文件my_data_frame.txt,内容为:
"id" "name" "salary"
1 "Tom" 2000
2 "Jack" 3000
3 "Rose" 4000
4 "Ketty" 5000
5 "Hello" 6000
则用R代码去读取这个文件:
> y <- read.table("my_data_frame.txt",header = TRUE)
> y
id name salary
1 1 Tom 2000
2 2 Jack 3000
3 3 Rose 4000
4 4 Ketty 5000
5 5 Hello 6000
> class(y) #查看读取数据后的结果对象的类型
[1] "data.frame"
>
对象y的第一列显示的是行索引,第一行表示的是列的字段名,查看对象y的数据类型为"data.frame",可知读取文件数据的结果创建了一个数据框
这里使用的read.table()函数部分,在后面的基础篇之文件数据的存储于读取的文章中会详细讲解,现在可以暂时不用过多理会
访问数据框
> x #使用的数据框
id name salary
1 1 Tom 2000
2 2 Jack 3000
3 3 Rose 4000
4 4 Ketty 5000
5 5 Hello 6000
> x[[1]] #按数字索引的方式访问数据框字段
[1] 1 2 3 4 5
> x[["name"]] #按字段名的方式访问数据框
[1] "Tom" "Jack" "Rose" "Ketty" "Hello"
> x$salary #用$符合访问字段
[1] 2000 3000 4000 5000 6000
> x[,1] #使用类似于访问矩阵的方式访问数据框
[1] 1 2 3 4 5
> class(x[,1])
[1] "integer"
> x[2:4,2] #用类似于矩阵的方式提取子数据框
[1] "Jack" "Rose" "Ketty"
> mode(x[2:4,2]) #自动降维成向量
[1] "character"
> x[2:4,2,drop = FALSE] #使用drop =FALSE参数保持数据框属性
name
2 Jack
3 Rose
4 Ketty
> class(x[2:4,2,drop = FALSE])
[1] "data.frame"
>
> x[2:4,2:3] #子数据框自动变成了列表
name salary
2 Jack 3000
3 Rose 4000
4 Ketty 5000
> mode(x[2:4,2:3])
[1] "list"
> x[1:2] #类似于列表,以单括号的方式访问数据框,结果为子数据框
id name
1 1 Tom
2 2 Jack
3 3 Rose
4 4 Ketty
5 5 Hello
> class(x[["name"]]) #查看字段的类型
[1] "character"
> class(x[1]) #单括号索引访问结果为子数据框
[1] "data.frame"
> str(x) #使用str()函数查看对象的内部结构
'data.frame': 5 obs. of 3 variables:
$ id : int 1 2 3 4 5
$ name : chr "Tom" "Jack" "Rose" "Ketty" ...
$ salary: num 2000 3000 4000 5000 6000
>
上述实例代码展示了四种访问数据框的方法,可以使用[[1]]
数字索引访问第几列元素,使用[["name"]]
字段名索引访问指定列元素,使用$salary
$符合的方式访问指定列元素,以及使用类似于[2:4,2]
矩阵取值操作的方式访问数据框元素,这也是提取子数据框的方法
其中x[1:2]
的用法类似于列表,可以提取序列索引对应的列,结果的数据类型为数据框
str()函数很重要,它可以方便的查看R中所以对象的内部结构,包括多少行数据、多少个字段、字段名、每个字段的值是什么,都可以从中清楚的获知。当我们在用别人的库时,函数调用返回的对象不知道有哪些变量,就可以使用该函数查看
向数据框中添加列或行
> x
id name salary
1 1 Tom 2000
2 2 Jack 3000
3 3 Rose 4000
4 4 Ketty 5000
5 5 Hello 6000
> (x <- rbind(x,list(6,"World",7000))) #行绑定,向数据框中添加新行
id name salary
1 1 Tom 2000
2 2 Jack 3000
3 3 Rose 4000
4 4 Ketty 5000
5 5 Hello 6000
6 6 World 7000
> (x <- cbind(x,flag = TRUE,new = x$id)) #列绑定,向数据框中添加新列,这里还用到了循环补齐
id name salary flag new
1 1 Tom 2000 TRUE 1
2 2 Jack 3000 TRUE 2
3 3 Rose 4000 TRUE 3
4 4 Ketty 5000 TRUE 4
5 5 Hello 6000 TRUE 5
6 6 World 7000 TRUE 6
> x[4:5] <- NULL #删除序列索引指定的列
> x
id name salary
1 1 Tom 2000
2 2 Jack 3000
3 3 Rose 4000
4 4 Ketty 5000
5 5 Hello 6000
6 6 World 7000
>
类似于矩阵的添加行或列,数据框也是使用的rbind()函数添加新行,使用cbind()函数添加新列;当要删除列时,可将对应的列设为NULL即可
————————————————————————————————————
修改列名
> x
id name salary
1 1 Tom 2000
2 2 Jack 3000
3 3 Rose 4000
4 4 Ketty 5000
5 5 Hello 6000
6 6 World 7000
> names(x) <- c(names(x)[1:2],"old_salary") #修改第三列字段的字段名
> x
id name old_salary
1 1 Tom 2000
2 2 Jack 3000
3 3 Rose 4000
4 4 Ketty 5000
5 5 Hello 6000
6 6 World 7000
> names(x) <- NULL #删除字段名
> x
1 1 Tom 2000
2 2 Jack 3000
3 3 Rose 4000
4 4 Ketty 5000
5 5 Hello 6000
6 6 World 7000
>
数据框也可以用names()函数来查看和修改字段名,若要删除字段名,只需要将names(x)
设为NULL即可
> x
1 1 Tom 2000
2 2 Jack 3000
3 3 Rose 4000
4 4 Ketty 5000
5 5 Hello 6000
6 6 World 7000
> apply(x,2,max) #对每一列使用max()函数
[1] "6" "World" "7000"
> (y <- lapply(x,sort)) #对每列使用sort()函数
[[1]]
[1] 1 2 3 4 5 6
[[2]]
[1] "Hello" "Jack" "Ketty" "Rose" "Tom" "World"
[[3]]
[1] 2000 3000 4000 5000 6000 7000
> (z <- sapply(x,sort))
[,1] [,2] [,3]
[1,] "1" "Hello" "2000"
[2,] "2" "Jack" "3000"
[3,] "3" "Ketty" "4000"
[4,] "4" "Rose" "5000"
[5,] "5" "Tom" "6000"
[6,] "6" "World" "7000"
>
数据框是列表的特例,数据框的列构成了列表的组件,所以也可以在数据框的每列上应用apply()函数和lapply()函数,包括sapply()函数
> x
id name salary
1 1 Tom 2000
2 2 Jack 3000
3 3 Rose 4000
4 4 Ketty 5000
5 5 Hello 6000
6 6 World 7000
> y
id
1 3
2 4
3 5
4 6
5 7
6 8
> merge(x,y) #按照x和y中共有的字段的值相等来做合并
id name salary
1 3 Rose 4000
2 4 Ketty 5000
3 5 Hello 6000
4 6 World 7000
在关系型数据库中经常会需要合并,即将两张表根据某个共同变量的值相等来组合到一起,join操作;在R中可以用 merge()来实现。比如上例,将x和y按照id字段的相等值合并
> names(y) <- "old_id"
> y
old_id
1 3
2 4
3 5
4 6
5 7
6 8
> merge(x,y)
id name salary old_id
1 1 Tom 2000 3
2 2 Jack 3000 3
3 3 Rose 4000 3
4 4 Ketty 5000 3
5 5 Hello 6000 3
6 6 World 7000 3
7 1 Tom 2000 4
8 2 Jack 3000 4
9 3 Rose 4000 4
10 4 Ketty 5000 4
11 5 Hello 6000 4
12 6 World 7000 4
13 1 Tom 2000 5
14 2 Jack 3000 5
15 3 Rose 4000 5
16 4 Ketty 5000 5
17 5 Hello 6000 5
18 6 World 7000 5
19 1 Tom 2000 6
20 2 Jack 3000 6
21 3 Rose 4000 6
22 4 Ketty 5000 6
23 5 Hello 6000 6
24 6 World 7000 6
25 1 Tom 2000 7
26 2 Jack 3000 7
27 3 Rose 4000 7
28 4 Ketty 5000 7
29 5 Hello 6000 7
30 6 World 7000 7
31 1 Tom 2000 8
32 2 Jack 3000 8
33 3 Rose 4000 8
34 4 Ketty 5000 8
35 5 Hello 6000 8
36 6 World 7000 8
> merge(x,y, by.x = "id", by.y = "old_id")
id name salary
1 3 Rose 4000
2 4 Ketty 5000
3 5 Hello 6000
4 6 World 7000
>
当merge()函数中没有共同的字段时,结果就是全连接操作,也就是两个表做笛卡尔积;如果想按指定的列的值相等做合并操作,可以设置by.x
和by.y
参数
> x
id name salary
1 1 Tom 2000
2 2 Jack 3000
3 3 Rose 4000
4 4 Ketty 5000
5 5 Hello 6000
6 6 World 7000
> x[3:4,3] <- NA
> x #假设数据框中有缺失值存在
id name salary
1 1 Tom 2000
2 2 Jack 3000
3 3 Rose NA
4 4 Ketty NA
5 5 Hello 6000
6 6 World 7000
> complete.cases(x) #可以用该函数查看某行是否不存在缺失值
[1] TRUE TRUE FALSE FALSE TRUE TRUE
> (w <- x[complete.cases(x),]) #提取没有缺失值的行
id name salary
1 1 Tom 2000
2 2 Jack 3000
5 5 Hello 6000
6 6 World 7000
>
若假设数据框中存在缺失值,则可以用complete.cases()函数检查某行是否不存在缺失值,结果是一个boolean型向量,每个元素指示对应的行是否不存在缺失值;若存在,则对应行的值为FALSE,不存在则为TRUE;得到这个指示的索引向量后,便可以提取数据框中不存在缺失值的行