前言:近段时间学习R语言用到最多的数据格式就是data.frame,现对data.frame常用操作进行总结,其中函数大部分来自dplyr包,该包由Hadley Wickham所作,主要用于数据的清洗和整理。
一、创建
data.frame创建较为容易,调用data.frame函数即可。本文创建一个关于学生成绩的数据框,接下来大部分操作都对该数据框进行,其中学生成绩随机产生
1
2
3
4
5
6
7
8
9
10
11
|
> library(dplyr) #导入dplyr包 > options(digits = 0) #保留整数 > set .seed(1) #设置种子函数 > df <- data.frame(ID = 1:12, #ID + Class = rep(c(1,2,3),4), #班级 + Chinese = runif(12,min = 0,max = 100), #语文 + Math = runif(12,min = 0,max = 100), #数学 + English = runif(12,min = 0,max = 100)) #英语 > for (i in 1:ncol( df )) { + df [,i] <- as.integer( df [,i]) #将每列类型变为integer型 + } |
df结果如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
> df ID Class Chinese Math English 1 1 1 26 68 26 2 2 2 37 38 38 3 3 3 57 76 1 4 4 1 90 49 38 5 5 2 20 71 86 6 6 3 89 99 34 7 7 1 94 38 48 8 8 2 66 77 59 9 9 3 62 93 49 10 10 1 6 21 18 11 11 2 20 65 82 12 12 3 17 12 66 |
二、 查询
1、查询某一行或某一列
可通过 data.frame[行号,] 或者 data.frame[,列号] 操作完成
其中 data.frame[行号,] 得到的类型是数据框
而 data.frame[,列号] 得到的类型是该列的类型
1
2
3
4
5
|
> df [2,] ID Class Chinese Math English 2 2 2 37 38 38 > df [,4] [1] 68 38 76 49 71 99 38 77 93 21 65 12 |
查询某一列还可以通过 data.frame$列名 操作完成
1
2
|
> df $Chinese [1] 26 37 57 90 20 89 94 66 62 6 20 17 |
data.frame[列号] 得到一个仅包含该列内容的数据框
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
> df [3] Chinese 1 26 2 37 3 57 4 90 5 20 6 89 7 94 8 66 9 62 10 6 11 20 12 17 |
若要查找符合条件的行,可采用 which() 函数,得到的类型是数据框
1
2
3
|
> df [ which ( df $ID == 4),] ID Class Chinese Math English 4 4 1 90 49 38 |
2、查询某一个值
可通过 data.frame[行号,列号] 或 data.frame[行号,‘列名'] 操作完成
1
2
3
4
|
> df [3,4] [1] 76 > df [3, 'Math' ] [1] 76 |
若查找符合条件的值,可采用 which() 函数
1
2
3
4
|
> df [ which ( df $Chinese == 57), 'Math' ] #查询语文成绩为57的同学的数学成绩 [1] 76 > df [ which ( df $Class == 2), 'English' ] #查询班级号为2的同学的英语成绩 [1] 38 86 59 82 |
三、修改
1、修改某一行或列
1
2
3
|
> df [1,] <- c(1,2,65,59,73) #修改第一行 #修改英语成绩 > df [, 'English' ] <- c(23,45,67,87,34,46,87,95,43,76,23,94) |
修改后结果为(1号同学英语成绩先由26修改为73,再修改为23)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
> df ID Class Chinese Math English 1 1 2 65 59 23 2 2 2 37 38 45 3 3 3 57 76 67 4 4 1 90 49 87 5 5 2 20 71 34 6 6 3 89 99 46 7 7 1 94 38 87 8 8 2 66 77 95 9 9 3 62 93 43 10 10 1 6 21 76 11 11 2 20 65 23 12 12 3 17 12 94 |
2、修改某一个值
直接将需要修改后的值赋给上述查询某一个值的操作即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
> df [3, 'Chinese' ] <- 65 #将3号同学的语文成绩修改为65 #将语文成绩低于20的同学的语文成绩修改为20 > df [ which ( df $Chinese < 20), 'Chinese' ] <- 20 > df ID Class Chinese Math English 1 1 2 65 59 23 2 2 2 37 38 45 3 3 3 65 76 67 4 4 1 90 49 87 5 5 2 20 71 34 6 6 3 89 99 46 7 7 1 94 38 87 8 8 2 66 77 95 9 9 3 62 93 43 10 10 1 20 21 76 11 11 2 20 65 23 12 12 3 20 12 94 |
3、修改行列名
可用rownames()及colnames()得到数据框的行列名,rownames(data.frame)[行号] 或 colnames(data.frame)[列号] 可得到指定位置的行名或者列名,若修改直接赋值给该变量即可
1
2
3
4
5
6
7
|
> colnames( df ) #查询列名 [1] "ID" "Class" "Chinese" "Math" "English" > colnames( df )[4] #查询第4列列名 [1] "Math" > colnames( df )[4] <- "math" #修改第4列列名为math #修改列名 > colnames( df ) <- c( "ID" , "Class" , "Chinese" , "Math" , "English" ) |
四、删除
删除行或列,仅需要选出该数据框的部分行或列,然后将其赋给该变量即可,其中在列号或行号前添加-表示不选该行或该列,在这里,为了方便接下来的操作,我们将选出后的数据框赋给其他变量,要实现删除操作应当将选出后的数据框赋给自己
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#选出df第1、3、5列 ( df <- df[,c(1,3,5)] ) > df .tmp <- df [,c(1,3,5)] > df .tmp ID Chinese English 1 1 65 23 2 2 37 45 3 3 65 67 4 4 90 87 5 5 20 34 6 6 89 46 7 7 94 87 8 8 66 95 9 9 62 43 10 10 20 76 11 11 20 23 12 12 20 94 #删除df第3行 ( df <- df[-3,] ) > df .tmp <- df [-3,] > df .tmp ID Class Chinese Math English 1 1 2 65 59 23 2 2 2 37 38 45 4 4 1 90 49 87 5 5 2 20 71 34 6 6 3 89 99 46 7 7 1 94 38 87 8 8 2 66 77 95 9 9 3 62 93 43 10 10 1 20 21 76 11 11 2 20 65 23 12 12 3 20 12 94 |
五、添加
1、添加行
data.frame[新行号,] <- 行值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
> df [13,] <- c(13,2,62,19,38) #新增13行数据 > df ID Class Chinese Math English 1 1 2 65 59 23 2 2 2 37 38 45 3 3 3 65 76 67 4 4 1 90 49 87 5 5 2 20 71 34 6 6 3 89 99 46 7 7 1 94 38 87 8 8 2 66 77 95 9 9 3 62 93 43 10 10 1 20 21 76 11 11 2 20 65 23 12 12 3 20 12 94 13 13 2 62 19 38 |
若想对行进行复制,可以采用重复行号的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
> df <- df [c(1,1:12),] #复制第1行1次 > df ID Class Chinese Math English 1 1 2 65 59 23 1.1 1 2 65 59 23 2 2 2 37 38 45 3 3 3 65 76 67 4 4 1 90 49 87 5 5 2 20 71 34 6 6 3 89 99 46 7 7 1 94 38 87 8 8 2 66 77 95 9 9 3 62 93 43 10 10 1 20 21 76 11 11 2 20 65 23 12 12 3 20 12 94 |
可使用rep()函数方便进行多行的复制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
> df <- df [rep(1:12,each = 2),] #对每行数据复制1次 > df ID Class Chinese Math English 1 1 2 65 59 23 1.1 1 2 65 59 23 2 2 2 37 38 45 2.1 2 2 37 38 45 3 3 3 65 76 67 3.1 3 3 65 76 67 4 4 1 90 49 87 4.1 4 1 90 49 87 5 5 2 20 71 34 5.1 5 2 20 71 34 6 6 3 89 99 46 6.1 6 3 89 99 46 7 7 1 94 38 87 7.1 7 1 94 38 87 8 8 2 66 77 95 8.1 8 2 66 77 95 9 9 3 62 93 43 9.1 9 3 62 93 43 10 10 1 20 21 76 10.1 10 1 20 21 76 11 11 2 20 65 23 11.1 11 2 20 65 23 12 12 3 20 12 94 12.1 12 3 20 12 94 |
还可采用rbind()函数,后续会有示例
2、添加列
data.frame$新列名 <- 列值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
> df $Physics <- c(23,34,67,23,56,67,78,23,54,56,67,34) > df ID Class Chinese Math English Physics 1 1 2 65 59 23 23 2 2 2 37 38 45 34 3 3 3 65 76 67 67 4 4 1 90 49 87 23 5 5 2 20 71 34 56 6 6 3 89 99 46 67 7 7 1 94 38 87 78 8 8 2 66 77 95 23 9 9 3 62 93 43 54 10 10 1 20 21 76 56 11 11 2 20 65 23 67 12 12 3 20 12 94 34 |
data.frame[,新列号] <- 列值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
> df [,7] <- c(1:12) > df ID Class Chinese Math English Physics V7 1 1 2 65 59 23 23 1 2 2 2 37 38 45 34 2 3 3 3 65 76 67 67 3 4 4 1 90 49 87 23 4 5 5 2 20 71 34 56 5 6 6 3 89 99 46 67 6 7 7 1 94 38 87 78 7 8 8 2 66 77 95 23 8 9 9 3 62 93 43 54 9 10 10 1 20 21 76 56 10 11 11 2 20 65 23 67 11 12 12 3 20 12 94 34 12 |
还可用dplyr包中的mutate()函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
> mutate( df ,Chemistry = Chinese + Math + English + Physics) ID Class Chinese Math English Physics V7 Chemistry 1 1 2 65 59 23 23 1 170 2 2 2 37 38 45 34 2 154 3 3 3 65 76 67 67 3 275 4 4 1 90 49 87 23 4 249 5 5 2 20 71 34 56 5 181 6 6 3 89 99 46 67 6 301 7 7 1 94 38 87 78 7 297 8 8 2 66 77 95 23 8 261 9 9 3 62 93 43 54 9 252 10 10 1 20 21 76 56 10 173 11 11 2 20 65 23 67 11 175 12 12 3 20 12 94 34 12 160 |
还可采用cbind()函数,后续会有示例
六、dplyr包常用函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
> df #原数据 ID Class Chinese Math English 1 1 2 65 59 23 2 2 2 37 38 45 3 3 3 65 76 67 4 4 1 90 49 87 5 5 2 20 71 34 6 6 3 89 99 46 7 7 1 94 38 87 8 8 2 66 77 95 9 9 3 62 93 43 10 10 1 20 21 76 11 11 2 20 65 23 12 12 3 20 12 94 |
1、arrange() 排序
1
2
|
arrange(.data, ...) arrange(.data, ..., .by_group = FALSE) |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
> arrange( df ,Chinese) #按语文成绩由小到大排序 ID Class Chinese Math English 1 5 2 20 71 34 2 10 1 20 21 76 3 11 2 20 65 23 4 12 3 20 12 94 5 2 2 37 38 45 6 9 3 62 93 43 7 1 2 65 59 23 8 3 3 65 76 67 9 8 2 66 77 95 10 6 3 89 99 46 11 4 1 90 49 87 12 7 1 94 38 87 |
函数中第一个是待排序的数据框,之后依次是变量,且变量优先级逐渐降低,如语文、数学成绩进行排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
> arrange( df ,Chinese,Math) #依次按语文、数学成绩由小到大排序 ID Class Chinese Math English 1 12 3 20 12 94 2 10 1 20 21 76 3 11 2 20 65 23 4 5 2 20 71 34 5 2 2 37 38 45 6 9 3 62 93 43 7 1 2 65 59 23 8 3 3 65 76 67 9 8 2 66 77 95 10 6 3 89 99 46 11 4 1 90 49 87 12 7 1 94 38 87 |
若想由大到小排序,使用desc()函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
> arrange( df ,desc(Chinese)) #按语文成绩由大到小排序 ID Class Chinese Math English 1 7 1 94 38 87 2 4 1 90 49 87 3 6 3 89 99 46 4 8 2 66 77 95 5 1 2 65 59 23 6 3 3 65 76 67 7 9 3 62 93 43 8 2 2 37 38 45 9 5 2 20 71 34 10 10 1 20 21 76 11 11 2 20 65 23 12 12 3 20 12 94 |
2、distinct()函数 去重
1
|
distinct(.data, ..., .keep_all = FALSE) |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
> df1 <- df [rep(1:nrow( df ),each = 2),] #将df每行复制1次 > df1 ID Class Chinese Math English 1 1 2 65 59 23 1.1 1 2 65 59 23 2 2 2 37 38 45 2.1 2 2 37 38 45 3 3 3 65 76 67 3.1 3 3 65 76 67 4 4 1 90 49 87 4.1 4 1 90 49 87 5 5 2 20 71 34 5.1 5 2 20 71 34 6 6 3 89 99 46 6.1 6 3 89 99 46 7 7 1 94 38 87 7.1 7 1 94 38 87 8 8 2 66 77 95 8.1 8 2 66 77 95 9 9 3 62 93 43 9.1 9 3 62 93 43 10 10 1 20 21 76 10.1 10 1 20 21 76 11 11 2 20 65 23 11.1 11 2 20 65 23 12 12 3 20 12 94 12.1 12 3 20 12 94 > df1 <- distinct(df1) #去除重复的行 > df1 ID Class Chinese Math English 1 1 2 65 59 23 2 2 2 37 38 45 3 3 3 65 76 67 4 4 1 90 49 87 5 5 2 20 71 34 6 6 3 89 99 46 7 7 1 94 38 87 8 8 2 66 77 95 9 9 3 62 93 43 10 10 1 20 21 76 11 11 2 20 65 23 12 12 3 20 12 94 |
3、group_by()函数 分组 summarise()函数 概括
1
2
3
|
group_by(.data, ..., add = FALSE, .drop = FALSE) ungroup(x, ...) summarise(.data, ...) |
group_by()与summarise()函数常连用,用于对不同的分组进行操作,在这里再介绍一个管道函数“%>%”,其作用是把左件的值发送给右件的表达式,并作为右件表达式函数的第一个参数
1
2
3
4
5
6
7
8
9
|
> df %>% + group_by(Class) %>% + summarise(max = max(Chinese)) #求出按Class分组每组中语文成绩最高分 # A tibble: 3 x 2 Class max <dbl> <dbl> 1 1 94 2 2 66 3 3 89 |
4、filter()函数 筛选
1
|
filter(.data, ..., .preserve = FALSE) |
选出符合条件的行(返回数据框格式)
1
2
3
4
5
6
7
8
9
10
|
> df %>% + group_by(Class) %>% + filter(Chinese == max(Chinese)) #选出每个班语文成绩最高的学生的信息 # A tibble: 3 x 5 # Groups: Class [3] ID Class Chinese Math English <dbl> <dbl> <dbl> <dbl> <dbl> 1 6 3 89 99 46 2 7 1 94 38 87 3 8 2 66 77 95 |
5、select()函数 选择
1
|
select (.data, ...) |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
> select ( df ,ID,Chinese,Math,English) #选出df中ID、语文、数学、英语数据 ID Chinese Math English 1 1 65 59 23 2 2 37 38 45 3 3 65 76 67 4 4 90 49 87 5 5 20 71 34 6 6 89 99 46 7 7 94 38 87 8 8 66 77 95 9 9 62 93 43 10 10 20 21 76 11 11 20 65 23 12 12 20 12 94 |
6、rbind()函数与cbind()函数 合并
rbind()函数根据行进行合并,cbind()根据列进行合并
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
#新建数据框df1 > df1 <- data.frame(ID = 13,Class = 2, Chinese = 65,Math = 26,English = 84) > df1 ID Class Chinese Math English 1 13 2 65 26 84 > rbind( df ,df1) #合并df与df1 ID Class Chinese Math English 1 1 2 65 59 23 2 2 2 37 38 45 3 3 3 65 76 67 4 4 1 90 49 87 5 5 2 20 71 34 6 6 3 89 99 46 7 7 1 94 38 87 8 8 2 66 77 95 9 9 3 62 93 43 10 10 1 20 21 76 11 11 2 20 65 23 12 12 3 20 12 94 13 13 2 65 26 84 > df2 #新建数据框df2 Biological 1 65 2 15 3 35 4 59 5 64 6 34 7 29 8 46 9 32 10 95 11 46 12 23 > cbind( df ,df2) #合并df与df2 ID Class Chinese Math English Biological 1 1 2 65 59 23 65 2 2 2 37 38 45 15 3 3 3 65 76 67 35 4 4 1 90 49 87 59 5 5 2 20 71 34 64 6 6 3 89 99 46 34 7 7 1 94 38 87 29 8 8 2 66 77 95 46 9 9 3 62 93 43 32 10 10 1 20 21 76 95 11 11 2 20 65 23 46 12 12 3 20 12 94 23 |
7、join函数 连接
1
2
3
4
5
6
7
|
inner_join(x, y, by = NULL, copy = FALSE, suffix = c( ".x" , ".y" ),...) left_join(x, y, by = NULL, copy = FALSE, suffix = c( ".x" , ".y" ), ...) right_join(x, y, by = NULL, copy = FALSE, suffix = c( ".x" , ".y" ),...) full_join(x, y, by = NULL, copy = FALSE, suffix = c( ".x" , ".y" ), ...) semi_join(x, y, by = NULL, copy = FALSE, ...) nest_join(x, y, by = NULL, copy = FALSE, keep = FALSE, name = NULL,...) anti_join(x, y, by = NULL, copy = FALSE, ...) |
join函数类型比较多,这里仅以left_join()函数举例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#新建数据框Class > Class <- data.frame(Class = c(1,2,3),class = c( '一班' , '二班' , '三班' )) > Class Class class 1 1 一班 2 2 二班 3 3 三班 > left_join( df ,Class,by = 'Class' ) #基于Class变量左连接df与Class数据框 ID Class Chinese Math English class 1 1 2 65 59 23 二班 2 2 2 37 38 45 二班 3 3 3 65 76 67 三班 4 4 1 90 49 87 一班 5 5 2 20 71 34 二班 6 6 3 89 99 46 三班 7 7 1 94 38 87 一班 8 8 2 66 77 95 二班 9 9 3 62 93 43 三班 10 10 1 20 21 76 一班 11 11 2 20 65 23 二班 12 12 3 20 12 94 三班 |
left_join()函数仅保留df对应的Class值的数据
以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。如有错误或未考虑完全的地方,望不吝赐教。
原文链接:https://www.cnblogs.com/huskysir/p/10841595.html