【问题标题】:Find groups of overlapping intervals with data.table使用 data.table 查找重叠区间组
【发布时间】:2020-01-28 20:50:36
【问题描述】:

我有多个区间,需要找出哪些区间会形成一个连续的组。

在这个 MWE 中,我有 Interval.id、Interval.start 和 Interval.end。我想计算 Wanted.column。

DT <- data.table(Interval.id=c(1L, 2L, 3L, 4L, 5L, 6L),
                 Interval.start=c(2.0, 3.0, 4.0, 4.6, 4.7, 5.5),
                 Interval.end=c(4.5, 3.5, 4.8, 5.0, 4.9, 8.0),
                 Wanted.column=c(1L, 1L, 1L, 1L, 1L, 2L))

我想foverlaps 是这里的朋友,但我不知道怎么做。

Wanted.column 如何计算?

【问题讨论】:

  • 如何定义连续组?能详细说明一下你是如何实现通缉的吗?无法立即看到序列。
  • 不知道怎么说,但如果区间A与B相交,C与B相交,那么A,B,C是同一组。即使 A 和 C 不相交。
  • 另请参阅:stackoverflow.com/questions/55836442/… 鉴于此答案要求的拆分数据,通过比较区间结束与后续区间开始(例如使用 data.table::shift)来找到联合应该是微不足道的

标签: r data.table


【解决方案1】:
DT[ , g := cumsum(
  cummax(shift(Interval.end, fill = Interval.end[1])) < Interval.start) + 1]

#    Interval.id Interval.start Interval.end Wanted.column   g
# 1:           1            2.0          4.5             1   1
# 2:           2            3.0          3.5             1   1
# 3:           3            4.0          4.8             1   1
# 4:           4            4.6          5.0             1   1
# 5:           5            4.7          4.9             1   1
# 6:           6            5.5          8.0             2   2

归功于高度相关的答案: Collapse rows with overlapping ranges, How to flatten / merge overlapping time periods

【讨论】:

    【解决方案2】:

    您可以先创建一个具有唯一/分组间隔的 data.table,然后使用foverlaps() 执行连接。 main-interval data.table 可以使用intervals-package 创建。使用interval_union()-函数将区间“合并”成不重叠的惰性值。

    #use the intervals-package to create the "main" unique intervals
    library( intervals )
    DT.int <- as.data.table(
      intervals::interval_union( 
        intervals::Intervals( as.matrix( DT[, 2:3] ) ) , 
        check_valid = TRUE ) )
    #set names
    setnames( DT.int, names(DT.int), c("start", "end" ) )
    #set group_id-column
    DT.int[, group_id := .I ][]
    #    start end group_id
    # 1:   2.0   5        1
    # 2:   5.5   8        2
    
    #now perform foverlaps()
    setkey( DT, Interval.start, Interval.end)
    setkey( DT.int, start, end)
    foverlaps( DT.int, DT )
    
    #    Interval.id Interval.start Interval.end Wanted.column start end group_id
    # 1:           1            2.0          4.5             1   2.0   5        1
    # 2:           2            3.0          3.5             1   2.0   5        1
    # 3:           3            4.0          4.8             1   2.0   5        1
    # 4:           4            4.6          5.0             1   2.0   5        1
    # 5:           5            4.7          4.9             1   2.0   5        1
    # 6:           6            5.5          8.0             2   5.5   8        2
    

    如您所见,group_id 列与您的Wanted.column 匹配

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-17
      • 1970-01-01
      相关资源
      最近更新 更多