R语言使用技巧
当你要对按照数据框某一列的信息对文件进行分组时
1. 可以使用split函数
2. 可以使用group_by() 函数,但是这个函数不能方便你接下来对每个小的group进行更为复杂的操作。
3. group_split() 函数
4. group_nest() 函数以及nest()函数
split() 函数
具体参数可参考:
https://www.jianshu.com/p/2efbf6632dc6
> library(tidyverse)
> a = matrix(c(1,2,1,1,2,1,1,3,4,6,4,1), byrow = T, ncol =3) %>% as.data.frame()
> a
V1 V2 V3
1 1 2 1
2 1 2 1
3 1 3 4
4 6 4 1
> b = split(1:dim(a)[1], a$V2); b
$`2`
[1] 1 2
$`3`
[1] 3
$`4`
[1] 4
# 按照V2列的数值对行进行切割,返回一个list,list里面包含了每个数字所在行的数值
#比如V2 = 2的行是第1行,V2 = 3的行是第3行
#使用lapply进行遍历操作,可以对每个划分出来的小的list进行操作
> lapply(b, function(x){a[unlist(x), ]}) #提取a中的每个group,返回大数据集中的小数据集
$`2`
V1 V2 V3
1 1 2 1
2 1 2 1
$`3`
V1 V2 V3
3 1 3 4
$`4`
V1 V2 V3
4 6 4 1
## lapply 返回值是一个大的list
#直接使用split()切分数据
> split(a,a$V1)
$`1`
V1 V2 V3
1 1 2 1
2 1 2 1
3 1 3 4
$`6`
V1 V2 V3
4 6 4 1
> split(a,a$V1) %>% class()
[1] "list"
#生成一个list,后续可以使用lapply遍历。
使用group_by
##另一种方法
> group_by(a,V2)
# A tibble: 4 x 3
# Groups: V2 [3]
V1 V2 V3
1 1 2 1
2 1 2 1
3 1 3 4
4 6 4 1
#利用group_by 对文件按列的值对每行分列,这里通过V2分为了三个组,这样结合summarise() 对于每个组的求mean或者sum
> summarise(a, b = mean(V3))
# A tibble: 3 x 2
V2 b
*
1 2 1
2 3 4
3 4 1
group_split()函数
group_list()可以把大的数据框按照某一列切分为小的数据框,这些小的数据框再组成一个list
library(tidyverse)
test = data.frame('gene_id' = c(rep(1,3),rep(2,4),rep(3,1)),
'isoform_id' = c('1_1-1_2','1_2-1_9','1_3-1_6','2_1-2_3','2_2-2_5','2_3-2_6','2_4_2-6','3_1-3_4'),
'count' = c(1:8))
> test
gene_id isoform_id count
1 1 1_1-1_2 1
2 1 1_2-1_9 2
3 1 1_3-1_6 3
4 2 2_1-2_3 4
5 2 2_2-2_5 5
6 2 2_3-2_6 6
7 2 2_4_2-6 7
8 3 3_1-3_4 8
x1 = test %>% group_split(gene_id); x1
>[3]>
[[1]]
# A tibble: 3 x 3
gene_id isoform_id count
1 1 1_1-1_2 1
2 1 1_2-1_9 2
3 1 1_3-1_6 3
[[2]]
# A tibble: 4 x 3
gene_id isoform_id count
1 2 2_1-2_3 4
2 2 2_2-2_5 5
3 2 2_3-2_6 6
4 2 2_4_2-6 7
[[3]]
# A tibble: 1 x 3
gene_id isoform_id count
1 3 3_1-3_4 8
#数据是由三个tibble组成的list,可使用lapply遍历
nest() 函数
参考:https://mp.weixin.qq.com/s/XGb3P6SY2UlZMgun_etFmg
nest()函数可以创建嵌套数据框,将多列多行组成一个列表,而这个列表单独成为一列,称为列表列。
nest() 函数有两种使用方式。当用于分组数据框时,nest() 函数会保留用于分组的列,而将其他所有数据归并到列表列中。
还可以在未分组数据框上使用nest(),此时需要指定嵌套哪些列。
x2 = test %>% group_by(gene_id) %>% nest()
> x2
# A tibble: 3 x 2
# Groups: gene_id [3]
gene_id data
1 1
2 2
3 3
#nest()返回一个tibble,只是data这一列是由list组成的,调用查看一下data这一列的内容
> x2$data[1]
[[1]]
# A tibble: 3 x 2
isoform_id count
1 1_1-1_2 1
2 1_2-1_9 2
3 1_3-1_6 3
#也就是说这里以前是一个元素,一个数字或者是字符串,现在是一个列表
#这里的x2$data[1]返回还是一个list,使用x2$data[1][[1]]将会返回一个tibble
> x2$data[1] %>% class()
[1] "list"
> x2$data[1][[1]] %>% class()
[1] "tbl_df" "tbl" "data.frame"
#因为x2是一个tibble,所以要使用apply()遍历每行,获取每个小组分的信息
#也有很多和map()函数联合使用
使用group_nest()函数
> x3 = test %>% group_nest(gene_id)
> x3
# A tibble: 3 x 2
gene_id data
* >
1 1 [3 x 2]
2 2 [4 x 2]
3 3 [1 x 2]
#和使用nest函数得到的结果相似,但是由不完全一样
> x3$data[1] %>% class()
[1] "vctrs_list_of" "vctrs_vctr" "list"
#对于使用nest()函数生成的x2来说,这样取只能得到一个list,x2$data[1][[1]]才能拿到tibble
#我感觉这个比用nest少了一层list的嵌套
使用这些函数时,要清楚输入输出的格式是什么,怎么样取值才能得到想要的格式,是使用appply还是lapply,以及map要根据实际情况来定。