如何在R或bash中按IID匹配汇总1500个PLINK2 .scount文件的列数值之和
解决方案
问题说明
你现有方案的主要问题有3个:
- 基础包
read.table、rbind、aggregate本身执行效率极低,不适合十万行级以上数据批量处理 - 首列
#IID的#会被默认识别为注释符,导致表头读取异常 aggregate的公式语法写反,无法实现按IID分组对其余列求和的需求
R优化方案(基于data.table)
data.table是R中针对结构化数据优化的高性能包,读写、拼接、聚合速度比基础包快10~100倍,完全适配你的数据规模:
# 安装加载包 install.packages("data.table") library(data.table) # 批量读取所有scount文件,关闭注释识别避免#IID报错 fnames <- list.files(pattern = "\\.scount$") df_all <- rbindlist(lapply(fnames, function(f) { fread(f, sep = "\t", header = TRUE, comment.char = "") })) # 按IID分组,对其余所有数值列求和 # 如果首列列名是#IID,把下面的IID换成`#IID`即可 res <- df_all[, lapply(.SD, sum), by = IID] # 输出结果,速度远快于write.table fwrite(res, "merged_scount_sum.tsv", sep = "\t")
如果内存不足,可以在fread中增加nThread参数调用多线程,或者设置colClasses指定列类型进一步提速。
命令行快速方案(基于awk)
如果不需要后续在R中处理数据,直接用awk命令行执行速度最快,内存占用极低,无需加载额外工具:
awk ' BEGIN {FS=OFS="\t"} # 跳过所有文件的表头,只保留第一个表头 FNR == 1 { if (NR == 1) header = $0 next } # 按IID累加各列数值 { for (i=2; i<=NF; i++) sum[$1][i] += $i } # 所有文件处理完后输出结果 END { print header for (iid in sum) { printf "%s", iid for (i=2; i<=NF; i++) printf "%s%s", OFS, sum[iid][i] print "" } } ' *.scount > merged_scount_sum.tsv
该命令会自动遍历当前目录下所有scount文件,跳过重复表头,按IID累加所有数值列,直接输出汇总文件。
内容的提问来源于stack exchange,提问作者tacrolimus
相关产品推荐
相关产品推荐

