我有一个看起来像这样的数据框(这只是一个子集,实际上数据集有 2724098 行)
> head(dat)
chr start end enhancer motif
chr10 238000 238600 9_EnhA1 GATA6
chr10 238000 238600 9_EnhA1 GATA4
chr10 238000 238600 9_EnhA1 SRF
chr10 238000 238600 9_EnhA1 MEF2A
chr10 375200 375400 9_EnhA1 GATA6
chr10 375200 375400 9_EnhA1 GATA4
chr10 440400 441000 9_EnhA1 GATA6
chr10 440400 441000 9_EnhA1 GATA4
chr10 440400 441000 9_EnhA1 SRF
chr10 440400 441000 9_EnhA1 MEF2A
chr10 441600 442000 9_EnhA1 SRF
chr10 441600 442000 9_EnhA1 MEF2A
我能够将我的数据集转换为这种格式,其中 chr、start、end 和 Enhancer 组代表单个 ID:
> dat
id motif
1 GATA6
1 GATA4
1 SRF
1 MEF2A
2 GATA6
2 GATA4
3 GATA6
3 GATA4
3 SRF
3 MEF2A
4 SRF
4 MEF2A
我想找到按 id 分组的每对可能的图案的数量。 所以我想要一个像 这样的输出表,
motif1 motif2 count
GATA6 GATA4 3
GATA6 SRF 2
GATA6 MEF2A 2
... and so on for each pair of motif
在实际数据集中,有 1716 个独特的图案。有83509个唯一ID。
有关如何进行的任何建议?
最佳答案
更新:这是一个使用 data.table
的快速且内存高效的版本:
require(data.table) ## 1.9.4+
set.seed(1L) ## For reproducibility
N = 2724098L
motif = sample(paste("motif", 1:1716, sep="_"), N, TRUE)
id = sample(83509, N, TRUE)
DT = data.table(id, motif)
DT = unique(DT) ## IMPORTANT: not to have duplicate motifs within same id
setorder(DT) ## IMPORTANT: motifs are ordered within id as well
setkey(DT, id) ## reset key to 'id'. Motifs ordered within id from previous step
DT[, runlen := .I]
ans = DT[DT, {
tmp = runlen < i.runlen;
list(motif[tmp], i.motif[any(tmp)])
},
by=.EACHI][, .N, by="V1,V2"]
在最后一步 3 中,这需要大约 27 秒和大约 1GB 的内存。
这个想法是执行自连接,但要使用 data.table 的
by=.EACHI
功能,评估 j-expression
每个i
,因此内存高效。和 j-expression
确保我们只获得条目“motif_a,motif_b”而不是多余的“motif_b,motif_a”。这也节省了计算时间和内存。并且二进制搜索非常快,即使有 87K+ id。最后,我们通过主题组合进行聚合以获得每个组合中的行数 - 这就是您所需要的。HTH
PS: See revision for the older (+ slower) version.
关于r - 计算按多列分组的列中每对可能的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26244685/