最近需要处理一批数据,每个数据框都具有相同的列名和列数,但是行数不同,所以就想着将数据框写入列表中,之后对列表进行循环操作,实现处理列表中数据框的列。由于能力不足,也折腾了一上午,所以在此记录下来。
数据如下:
文件夹中的文件
将文件夹中后缀名为novel.exp的文件导入R中,并创建列表
library(tidyverse)
a <- dir(pattern = "novel.exp") %>% lapply(function(x){read.table(x,header = F,sep = " ")})
其中每一个数据框都包括三列,如下:
接下来,我想通过cut()
函数对V2列进行区间分割(如果大家有什么好的方法,欢迎讨论区留言)
# 定义函数
map_list <- function(a){
library(tidyverse)
for(i in seq_len(length(a))){
a[[i]] <- a[[i]] %>% mutate(bin = cut(V2,breaks = c(-0.001,0.1,1,10,100,Inf))) %>% # cut函数分割,将结果添加到数据框中
count(bin,name = "number of transcript") %>% # 统计各个区间的频数
mutate(group = rep(i,nrow(.))) # 定义分组,每个数据框是一组
}
do.call(rbind,a) # rbind函数合并列表中的数据框
}
#运行函数
s <- map_list(a)
最近通过不断地学习,掌握了一种更简单而且高效的方法,特地补充进来!
# 首先构建一个包含数据框的列表
od <- list(
a = data.frame(x = c(1,2,3),y = c(2,3,4)),
b = data.frame(x = 7:9,y = 8:10)
)
# 直接使用purrr包的modify函数
library(purrr)
modify(od,~ modify(.x,~.x -1))
##$a
## x y
##1 0 1
##2 1 2
##3 2 3
##$b
## x y
##1 6 7
##2 7 8
##3 8 9
当然,这里只是一个简单的小例子,但是效率肯定能够提高不少,感兴趣可以使用system.time命令测试。
结果如下:
cut()
函数将V2列分割成五个区间,统计频数之后列表中的每个数据框都是5 x 3,所以使用rbind()
函数合并之后就产生了一个25 x 3 的数据框。这里的group是为了方便绘图加进去的。
library(knitr)
knitr::kable(s,align = "c")
bin | number of transcript | group |
---|---|---|
(-0.001,0.1] | 9710 | 1 |
(0.1,1] | 5505 | 1 |
(1,10] | 4540 | 1 |
(10,100] | 2200 | 1 |
(100,Inf] | 315 | 1 |
(-0.001,0.1] | 9882 | 2 |
(0.1,1] | 5575 | 2 |
(1,10] | 5485 | 2 |
(10,100] | 2624 | 2 |
(100,Inf] | 343 | 2 |
(-0.001,0.1] | 3271 | 3 |
(0.1,1] | 2157 | 3 |
(1,10] | 2359 | 3 |
(10,100] | 1816 | 3 |
(100,Inf] | 245 | 3 |
(-0.001,0.1] | 3807 | 4 |
(0.1,1] | 2163 | 4 |
(1,10] | 2110 | 4 |
(10,100] | 1703 | 4 |
(100,Inf] | 320 | 4 |
(-0.001,0.1] | 6797 | 5 |
(0.1,1] | 4762 | 5 |
(1,10] | 4084 | 5 |
(10,100] | 1964 | 5 |
(100,Inf] | 285 | 5 |
接下来就可以直接拿来画图了,因为数据tidy,所以做起图来容易很多。
library(ggplot2)
library(ggsci)
s %>% ggplot(aes(factor(group),`number of transcript`,fill = factor(bin,levels = rev(unique(bin))))) +
geom_bar(stat = "identity",width = .7) +
scale_y_continuous(expand = c(0,0),limits = c(0,25000)) +
theme_classic(base_line_size = .7) +
scale_fill_jco() +
theme(legend.title = element_blank(),
axis.title.x = element_blank())
s %>% ggplot(aes(factor(group),`number of transcript`,fill = factor(bin,levels = rev(unique(bin))))) +
geom_bar(stat = "identity",position = position_dodge(width = .9),width = .7,color = "black") +
scale_y_continuous(expand = c(0,0),limits = c(0,11000)) +
theme_classic(base_line_size = .7) +
scale_fill_jco() +
theme(legend.title = element_blank(),
axis.title.x = element_blank())
如果大家有更好的前期处理数据的方法,一定要留言讨论啊!