在R中没有for循环的情况下获取重叠数据帧值的计数

时间:2019-02-15 22:02:53

标签: r

我有两个数据框,其中一个称为segments,其中包含数字“开始”和“停止”值

segments <- as.data.frame(
  cbind(
    rep(seq(1, 22, 1), 2),
    seq(500000, 3000000, 57000),
    seq(1000000, 3500000, 57000)
  )
)
colnames(segments) <- c("chr", "segment.start", "segment.end")

还有一个名为positions的数字,包含数字值。

positions <- as.data.frame(cbind(1, seq(750000, 2000000, 56000)))
colnames(positions) <- c("chr", "pos")

我有兴趣计算segments中“开始”和“停止”值之间的区域与positions中的每个值重叠的行数,并将这些计数添加到新列中的positions

positions$count <- 0

我可以使用以下for循环获取这些计数,但是在大型数据集上,这非常慢。

for (n in 1:nrow(segments)) {
  segment <- segments[n, ]
  to.update <- which(
    positions$pos >= segment$segment.start &
      positions$pos <= segment$segment.end & 
      positions$chr == segment$chr
    )
  positions[to.update, "count"] <- positions[to.update, "count"] + 1
}

有人知道如何在没有for循环的情况下获得这些计数吗?

1 个答案:

答案 0 :(得分:2)

如果没有验证,我认为data.table可以很好地完成。我确定可以使用其他工具(基本工具或tidyverse)来完成此操作,但这很快并且使用了我最近一直在使用的工具:foverlaps

library(data.table)
setDT(segments)
setDT(positions)
positions[, pos2 := pos ]

setkey(segments, segment.start, segment.end)
setkey(positions, pos, pos2)

作为解释要点,foverlaps要求两个帧都具有两个字段,前提是该功能是在一个帧的范围内与另一个帧的重叠。可能有人认为在此重叠检查中使用单列选项可能会有用,但添加第二列(在这种情况下为pos2)是微不足道的,并且无需更改{{1 }}代码。

编辑:已更新为包含“按data.table”逻辑。

编辑2 :取反,以chr作为主要内容:

positions