【问题标题】:Getting counts of overlapping dataframe values without a for loop in R在R中没有for循环的情况下获取重叠数据帧值的计数
【发布时间】:2019-02-15 22:02:52
【问题描述】:

我有两个数据框,一个名为 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 循环的情况下获得这些计数?

【问题讨论】:

    标签: r


    【解决方案1】:

    不用验证,我觉得用data.table就可以搞定。我确信它可以使用其他工具(base 或 tidyverse)来完成,但这很快并且使用了我最近经常使用的工具:foverlaps

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

    作为解释,foverlaps 要求两个帧都有两个字段,功能的前提是一个帧范围内的重叠与另一帧的重叠。尽管有人可能会争辩说,在此重叠检查中使用单列选项可能很有用,但添加第二列(在本例中为 pos2)是微不足道的,并且无需更改 data.table 代码即可启用完全相同的功能。

    编辑:更新为包含“by chr”逻辑。

    编辑 2:反转,导致 positions 作为主要:

    foverlaps(positions, segments) [
        , .(count = sum(!is.na(segment.start))), by = .(chr, pos, pos2) ][
        , pos2 := NULL ]
    #     chr     pos count
    #  1:   1  750000     1
    #  2:   1  806000     1
    #  3:   1  862000     1
    #  4:   1  918000     1
    #  5:   1  974000     1
    #  6:   1 1030000     0
    #  7:   1 1086000     0
    #  8:   1 1142000     0
    #  9:   1 1198000     0
    # 10:   1 1254000     0
    # 11:   1 1310000     0
    # 12:   1 1366000     0
    # 13:   1 1422000     0
    # 14:   1 1478000     0
    # 15:   1 1534000     0
    # 16:   1 1590000     0
    # 17:   1 1646000     0
    # 18:   1 1702000     0
    # 19:   1 1758000     1
    # 20:   1 1814000     1
    # 21:   1 1870000     1
    # 22:   1 1926000     1
    # 23:   1 1982000     1
    #     chr     pos count
    

    【讨论】:

    • 谢谢!有没有办法考虑到两个数据帧中存在的chr 列?如果positions 值介于segment.startsegment.end 之间并且chr 列在两个数据帧之间相同,我只想记录重叠。
    • 我实际上对逆 foverlaps(positions, segments) [ , .(n = .N), by = .(pos, pos2) ] 感兴趣,它不会返回 n 的正确值(对于许多中间值 @987654340,对于 pos 的所有值,n=1 @ 应该为 0,因为它们不与 chr=1) 的段重叠
    • 是的,抱歉,我没有与您的 for 循环输出进行比较。现在怎么样?
    • 如果我做一个小的调整newdepthcounts&lt;-foverlaps(bim, seg.file) [, .(count = sum(!is.na(segment.start))), by = .(chr,pos, pos2) ][, pos2 := NULL ],这在我更大的数据集上非常有效。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2019-09-02
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 2021-01-29
    • 1970-01-01
    相关资源
    最近更新 更多