检查两个间隔是否在 R 中重叠
Check if two intervals overlap in R
给定四列值(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
我尝试了一个视图,但没有让它工作,特别是间隔不是 "sorted" 的事情使得我的 R 技能很难找到解决方案。
我想找到成对的列(例如 FromUp、ToUp)的最小值和最大值,然后比较它们?
如有任何帮助,我们将不胜感激。
排序
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]))
如果您正在寻找 any[=30= 之间的重叠,其他人(或 IRanges::findOveralaps()
)提到的 foverlap()
函数将是合适的] 范围,但您正在寻找 'parallel'(行内?)重叠。
这里的解决逻辑和@Julius的答案是一样的,但是是'vectorized'(例如,1次调用pmin()
,而不是nrow(ranges)
次调用sort()
) 并且对于可能范围更长的向量应该更快(尽管使用更多内存)。
总的来说:
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]))})
给定四列值(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
我尝试了一个视图,但没有让它工作,特别是间隔不是 "sorted" 的事情使得我的 R 技能很难找到解决方案。 我想找到成对的列(例如 FromUp、ToUp)的最小值和最大值,然后比较它们?
如有任何帮助,我们将不胜感激。
排序
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]))
如果您正在寻找 any[=30= 之间的重叠,其他人(或 IRanges::findOveralaps()
)提到的 foverlap()
函数将是合适的] 范围,但您正在寻找 'parallel'(行内?)重叠。
这里的解决逻辑和@Julius的答案是一样的,但是是'vectorized'(例如,1次调用pmin()
,而不是nrow(ranges)
次调用sort()
) 并且对于可能范围更长的向量应该更快(尽管使用更多内存)。
总的来说:
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]))})