如何将紧凑的R data.table范围数据展开为逐行宽格式表?
从紧凑区间格式展开为逐位置宽格式(data.table高效解法)
问题回顾
你有一个存储染色体区间的紧凑data.table:
dt.compact = data.table(chr=c('chr1','chr1','chr2','chr2'),start = c(1,5,2,7), stop = c(3,7,3,8))
输出如下:
chr start stop 1: chr1 1 3 2: chr1 5 7 3: chr2 2 3 4: chr2 7 8
想要转换成每行对应单个位置的格式,目标输出示例:
do.call(data.table, list(V1 = c(rep('chr1', 6),rep('chr2', 4)), V2 = c(1:3, 5:7, 2:3, 7:8)))
对应的结果:
V1 V2 1: chr1 1 2: chr1 2 3: chr1 3 4: chr1 5 5: chr1 6 6: chr1 7 7: chr2 2 8: chr2 3 9: chr2 7 10: chr2 8
高效内置解决方案
不用自己写mapply自定义函数,data.table的分组操作+seq.int就能一步搞定,代码简洁还高效:
library(data.table) # 定义原始紧凑表 dt.compact = data.table(chr=c('chr1','chr1','chr2','chr2'),start = c(1,5,2,7), stop = c(3,7,3,8)) # 核心展开操作 dt.expanded = dt.compact[, .(V2 = seq.int(start, stop)), by = chr] # 如果需要和示例完全一致的列名,重命名即可 setnames(dt.expanded, c("chr", "V2"), c("V1", "V2"))
解法说明
- 利用
data.table的by = chr按染色体分组,对每组内的start和stop调用seq.int生成连续的位置序列 - 这种方法是
data.table原生优化过的,处理大规模数据集时比mapply这类基础函数快很多 - 代码逻辑清晰,一眼就能看懂是在做什么,后期维护也方便
内容的提问来源于stack exchange,提问作者Danyou
相关产品推荐
相关产品推荐

