查找data.table中多个范围的重叠

时间:2019-07-12 13:55:20

标签: r dataframe data.table overlap

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

一个例子是:

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))

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

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