快速地将大量文件进行行绑定

7

我之前写了一篇(类似的)帖子在这里,当时我试图创建一个宽表而不是长表。但我意识到最好将我的表格设置为长格式,因此我将其作为另一个问题发布。我也会发布我已经尝试过的内容。

我正在使用R通过rbind来连接大约11,000个文件:

# get list of ~11000 files
lfiles <- list.files(pattern = "*.tsv", full.names = TRUE)

# row-bind the files
# use rbindlist to rbind and fread to read files
# use mclapply I am assigning 32 cores to it
# add the file basename as the id to identify rows
dat <- rbindlist(mclapply(lfiles, function(X) {
data.frame(id = basename(tools::file_path_sans_ext(X)),
           fread(X))},mc.cores = 32))

我使用R语言是因为我需要进行后续处理,如创建图形等。我的问题有两个:
1. 是否有方法可以使我的代码更加高效/快速? 我知道最终期望的行数,因此是否预分配数据框会有帮助?
2. 我应该用什么格式保存这些庞大的数据——是.RData还是数据库或其他文件格式?
额外信息:我有三种类型的文件需要处理,它们看起来像这样:
[centos@ip data]$ head C021_0011_001786_tumor_RNASeq.abundance.tsv
target_id   length  eff_length  est_counts  tpm
ENST00000619216.1   68  26.6432 10.9074 5.69241
ENST00000473358.1   712 525.473 0   0
ENST00000469289.1   535 348.721 0   0
ENST00000607096.1   138 15.8599 0   0
ENST00000417324.1   1187    1000.44 0.0673096   0.000935515
ENST00000461467.1   590 403.565 3.22654 0.11117
ENST00000335137.3   918 731.448 0   0
ENST00000466430.5   2748    2561.44 162.535 0.882322
ENST00000495576.1   1319    1132.44 0   0

[centos@ip data]$ head C021_0011_001786_tumor_RNASeq.rsem.genes.norm_counts.hugo.tab
gene_id C021_0011_001786_tumor_RNASeq
TSPAN6  1979.7185
TNMD    1.321
DPM1    1878.8831
SCYL3   452.0372
C1orf112    203.6125
FGR 494.049
CFH 509.8964
FUCA2   1821.6096
GCLC    1557.4431

[centos@ip data]$ head CPBT_0009_1_tumor_RNASeq.rsem.genes.norm_counts.tab
gene_id CPBT_0009_1_tumor_RNASeq
ENSG00000000003.14  2005.0934
ENSG00000000005.5   5.0934
ENSG00000000419.12  1100.1698
ENSG00000000457.13  2376.9100
ENSG00000000460.16  1536.5025
ENSG00000000938.12  443.1239
ENSG00000000971.15  1186.5365
ENSG00000001036.13  1091.6808
ENSG00000001084.10  1602.7165

任何帮助都将不胜感激!
谢谢!
2个回答

5

在R中,你无法比使用freadrbindlist更快地完成此操作。但是,你不应该使用data.frame并复制数据。相反,应该通过引用进行赋值:by reference

DF <- fread(X)
DF[, id := basename(tools::file_path_sans_ext(X))]
return(DF) 

然而,您应该考虑使用数据库。

PS:正确的正则表达式为".+\\.tsv$"。这匹配任何文件名,其中包含一个或多个字符,后跟一个句点和字符串"tsv",最后以文件名结尾。


3

关于问题1.,我不能确定是否会有明显的差异,但您可以尝试以下方法来避免data.frame调用(如@Roland在他的答案中所提到的):

lfiles <- list.files(pattern = ".*\\.tsv$", full.names = TRUE)
setattr(lfiles, "names", basename(lfiles))
dat <- rbindlist(mclapply(lfiles, fread, mc.cores = 32), idcol = "id")

在这里,你可以在 rbindlist 内使用 idcol 参数。

关于问题2.,我猜这取决于你在分析中想要做什么。


setnames(lfiles, basename(lfiles))是做什么的?它不会起作用,因为lfiles不是一个数据框。 - Komal Rathi
@KomalRathi,已更正使用setattr,它也适用于列表。 - talat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接