0%

R里面批量处理数据

用R批量合并多个数据框。

1. 简便方法1:写函数

将merge函数包装一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
multimerge<-function(dat=list(),...){
if(length(dat)<2)return(as.data.frame(dat))
mergedat<-dat[[1]]
dat[[1]]<-NULL
for(i in dat){
mergedat<-merge(mergedat,i,...)
}
return(mergedat)
}
#实例
dat1<-data.frame(x=1:10,y=rnorm(10))
dat2<-data.frame(x=3:12,z=rnorm(10))
dat3<-data.frame(x=-3:6,w=rnorm(10))
multimerge(list(dat1,dat2,dat3))
x y z w
1 3 -0.9569581 2.4628856 -2.7649845
2 4 1.1603587 0.8045977 2.2755481
3 5 1.6707883 -0.3543526 -1.6977815
4 6 0.8594658 0.5454031 0.5791043

2. 方法二

批量从文件中读取数据框,并合并每个表格。

第一步:先用lapply批量将文件名赋值给一个list。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
library(dplyr)

# 将变量内容更改为文件名字,方便后续批量读取
x <- 1:2
batch_list <- lapply(1:8, function(i) paste0("tmp/b", x + 2*(i-1), "_TE.csv"))
head(batch_list)
[[1]]
[1] "tmp/b1_TE.csv" "tmp/b2_TE.csv"

[[2]]
[1] "tmp/b3_TE.csv" "tmp/b4_TE.csv"

[[3]]
[1] "tmp/b5_TE.csv" "tmp/b6_TE.csv"

[[4]]
[1] "tmp/b7_TE.csv" "tmp/b8_TE.csv"

[[5]]
[1] "tmp/b9_TE.csv" "tmp/b10_TE.csv"

[[6]]
[1] "tmp/b11_TE.csv" "tmp/b12_TE.csv"

第二步:批量读取文件中的表格,每次读取两个,返回给变量list_file_batch1、list_file_btach2等,每个list里面两个表格,用于后续的merge。如果表格多可能会导致需要的内存比较大,时间也比较久,所以选择每次合并两个。

1
2
3
4
for (i in 1:8) {
var_name <- paste0("list_file_batch", i)
assign(var_name, lapply(batch_list[[i]], read.csv))
}

assign用于将得到的list分配给var_name所指向的变量。var_name并不是真正的变量名,var_name中的

第三步:合并每一个list中的两个表格。

1
2
3
4
5
6
7
8
9
10
11
12
for (i in 1:8) {
in_var_name <- paste0("list_file_batch",i)
in_var <- get(in_var_name)
out_var_name <- paste0("merged_df", i)
merged_df <- Reduce(function(x, y) merge(x,y,by="gene_name",all = TRUE),in_var)
merged_df <- merged_df %>% group_by(gene_name) %>% summarise_all(sum)
assign(out_var_name,merged_df)
rm(merged_df)
gc()
print("c1")
}

然后再继续合并得到第一次合并后的表格。

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
for (i in 1:4){
var1 <- paste0("merged_df",i)
var2 <- paste0("merged_df",i+4)
out_var_name <- paste0("merged2_df",i)
in_var_name <- list(var1,var2)
in_var <- lapply(in_var_name, get)
#in_var <- get(in_var_name)
merged_df <- Reduce(function(x, y) merge(x,y,by="gene_name",all = TRUE),in_var)
merged_df <- merged_df %>% group_by(gene_name) %>% summarise_all(sum)
assign(out_var_name,merged_df)
rm(merged_df)
gc()
print("c2")
}

#rm(merge_df1,merge_df2,merge_df3,merge_df4,merge_df5,merge_df6,merge_df7,merge_df8)

for (i in 1:2){
var1 <- paste0("merged2_df",i)
var2 <- paste0("merged2_df",i+2)
out_var_name <- paste0("merged3_df",i)
in_var_name <- list(var1,var2)
in_var <- lapply(in_var_name, get)
#in_var <- get(in_var_name)
merged_df <- Reduce(function(x, y) merge(x,y,by="gene_name",all = TRUE),in_var)
merged_df <- merged_df %>% group_by(gene_name) %>% summarise_all(sum)
assign(out_var_name,merged_df)
rm(merged_df)
gc()
print("c3")
}

#rm(merge2_df1,merge2_df2,merge2_df3,merge2_df4)
gc()
ls()

i <- 1
var1 <- paste0("merged3_df",i)
var2 <- paste0("merged3_df",i+1)
in_var_name <- list(var1,var2)
in_var <- lapply(in_var_name, get)
merged4_df <- Reduce(function(x, y) merge(x,y,by="gene_name",all = TRUE),in_var)
merged4_df <- merged4_df %>% group_by(gene_name) %>% summarise_all(sum)
print("c4")
gc()

这样的方式可能有点笨。之后如果有进展会再更新。这个方法的优势在于不用每个表格都读取一遍文件,如果表格比较小,其实也可以一次性全部merge,不用分这么多次。

参考资料:

  1. https://bbs.pinggu.org/thread-3712315-1-1.html