【问题标题】:Find overlap of multiple ranges in data.table在 data.table 中查找多个范围的重叠
【发布时间】:2019-07-12 13:55:20
【问题描述】:

我想在 data.table 对象中找到多个范围的重叠部分。

一个例子是:

t <- data.table(a = c(3,4,5), b = c(13,12,19))

所以我们有范围:

3 - 13, 4 - 12, 5 - 19

因此重叠范围为:

5 - 12

如果有额外的范围 19 - 22,则重叠应返回 NA - NA 或 0 - 0,因为没有重叠。

我找到了类似问题的解决方案,例如 spatstat.utils:: intersect.ranges()。然而,这只适用于两个向量,很难在 data.table 中实现

    DT[,.(o.l = function()[1], o.r = function()[2], by=.()] 

如果可能的话,我真的很想这样做,..

作为这个例子的输出,我想要:

t <- data.table(a = c(3,4,5), b = c(13,12,19), o.l = c(5,5,5), o.r = c(12,12,12))

【问题讨论】:

  • 检查foverlaps
  • 我已经使用 foverlaps 连接两个 data.tables,但现在不知道如何在这种情况下应用它
  • data.table(a = c(3,4,5), b = c(13,12,19))[, .(max(a), min(b))]
  • 谢谢,这当然适用于该示例。我也稍微调整了这个问题以解释这种情况

标签: r dataframe data.table overlap


【解决方案1】:

这是一个单行示例:

library(data.table)

dt = data.table(a = c(3,4,5), b = c(13,12,19))

dt[, c("o.l", "o.r") := as.list(range(Reduce(intersect, mapply(seq, a, b, 1))))]

dt
#    a  b o.l o.r
# 1: 3 13   5  12
# 2: 4 12   5  12
# 3: 5 19   5  12

问题的核心在哪里

dt = data.table(a = c(3,4,5), b = c(13,12,19))
dt[, Reduce(intersect, mapply(seq, a, b, 1))]
# [1]  5  6  7  8  9 10 11 12

【讨论】:

    【解决方案2】:

    借鉴 David Aurenburg 在How to flatten / merge overlapping time periods 中的回答,这是另一种可能的方法:

    DT[, g := c(0L, cumsum(shift(a, -1L) >= cummax(b))[-.N])][, 
        c("ol", "or") := .(max(a), min(b)), g]
    

    数据:

    DT <- data.table(a = c(3,4,5,19,20,24), b = c(13,12,19,22,23,25))
    

    输出:

        a  b g ol or
    1:  3 13 0  5 12
    2:  4 12 0  5 12
    3:  5 19 0  5 12
    4: 19 22 1 20 22
    5: 20 23 1 20 22
    6: 24 25 2 24 25
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多