在R中检查两个区间是否重叠

4

给定四列值(FromUp,ToUp,FromDown,ToDown),其中两个始终定义一个范围(FromUp,ToUp和FromDown,ToDown)。我如何测试这两个范围是否重叠。重要的是说明范围值没有排序,因此“From”值可以高于“To”值,反之亦然。

一些示例数据:

FromUp<-c(5,32,1,5,15,1,6,1,5)
ToUp<-c(5,31,3,5,25,3,6,19,1)

FromDown<-c(1,2,8,1,22,2,1,2,6)
ToDown<-c(4,5,10,6,24,4,1,16,2)

ranges<-data.frame(FromUp,ToUp,FromDown,ToDown)

因此,结果应如下所示:
FromUp ToUp FromDown ToDown   Overlap
      5    5        1      4    FALSE
     32   31        2      5    FALSE
      1    3        8     10    FALSE
      5    5        1      6    TRUE
     15   25       22     24    TRUE
      1    3        2      4    TRUE
      6    6        1      1    FALSE
      1   19        2     16    TRUE
      5    1        6      2    TRUE

我尝试了一些方法,但没有使它正常工作,特别是间隔不是“排序”的事情让我很难用我的R技能找到解决方案。我想过找到成对列(如FromUp,ToUp)的最小值和最大值,然后进行比较?

希望得到任何帮助。


@akrun等,你们能否展示一下如何使用foverlaps()来解决这个问题?也许我对问题的理解有误。 - Martin Morgan
我也很难想象在这种情况下如何使用 foverlaps。由于 foverlaps 需要设置键,因此相应列的顺序会改变,而此问题需要逐行比较。 - Jaap
2个回答

4

将它们排序

rng = cbind(pmin(ranges[,1], ranges[,2]), pmax(ranges[,1], ranges[,2]),
            pmin(ranges[,3], ranges[,4]), pmax(ranges[,3], ranges[,4]))

并编写条件

olap = (rng[,1] <= rng[,4]) & (rng[,2] >= rng[,3])

在一步中,这可能是

(pmin(ranges[,1], ranges[,2]) <= pmax(ranges[,3], ranges[,4])) &
    (pmax(ranges[,1], ranges[,2]) >= pmin(ranges[,3], ranges[,4]))

其他人提到的foverlap()函数(或IRanges::findOveralaps())适用于查找任意范围之间的重叠,但您正在寻找 '并行'(在行内?)的重叠。

此处解决方案的逻辑与@Julius的答案相同,但是它是“向量化”的(例如,只调用一次pmin()而不是调用nrow(ranges)sort()),并且对于可能范围更长的向量速度应该更快(尽管使用更多内存)。


是的,那可能不够清楚,我正在寻找行内的重叠部分。 看起来你的答案正是我在寻找的,如果我正确理解了代码,它采用了最小值和最大值的方法。太好了!谢谢! - Kitumijasi

2

总体而言:

apply(ranges,1,function(x){y<-c(sort(x[1:2]),sort(x[3:4]));max(y[c(1,3)])<=min(y[c(2,4)])})

或者,如果区间不能仅在一个点重叠(例如因为它们是开放的):
!apply(ranges,1,function(x){y<-sort(x)[1:2];all(y==sort(x[1:2]))|all(y==sort(x[3:4]))})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接