R 折叠具有重叠范围的行

R 折叠具有重叠范围的行,r,subset,rows,overlap,overlapping,R,Subset,Rows,Overlap,Overlapping,我有一个带有开始和结束时间的data.frame: ranges<- data.frame(start = c(65.72000,65.72187, 65.94312,73.75625,89.61625),stop = c(79.72187,79.72375,79.94312,87.75625,104.94062)) > ranges start stop 1 65.72000 79.72187 2 65.72187 79.72375 3 65.94312

我有一个带有开始和结束时间的data.frame:

ranges<- data.frame(start = c(65.72000,65.72187, 65.94312,73.75625,89.61625),stop = c(79.72187,79.72375,79.94312,87.75625,104.94062))

> ranges
     start      stop
1 65.72000  79.72187
2 65.72187  79.72375
3 65.94312  79.94312
4 73.75625  87.75625
5 89.61625 104.94062
我试过这个:

mdat <- outer(ranges$start, ranges$stop, function(x,y) y > x)
mdat[upper.tri(mdat)|col(mdat)==row(mdat)] <- NA
mdat
mdat x)
mdat[upper.tri(mdat)| col(mdat)=row(mdat)]您可以尝试以下方法:

library(dplyr)
ranges %>% 
       arrange(start) %>% 
       group_by(g = cumsum(cummax(lag(stop, default = first(stop))) < start)) %>% 
       summarise(start = first(start), stop = max(stop))

# A tibble: 2 × 3
#      g    start      stop
#  <int>    <dbl>     <dbl>
#1     0 65.72000  87.75625
#2     1 89.61625 104.94062
库(dplyr)
范围%>%
安排(开始)%%>%
分组依据(g=cumsum(cummax(滞后(停止,默认值=first(停止)))%
总结(开始=第一(开始),停止=最大(停止))
#一个tibble:2×3
#g起止点
#           
#1     0 65.72000  87.75625
#2     1 89.61625 104.94062

这是一个
数据表
解决方案

library(data.table)
setDT(ranges)
ranges[, .(start=min(start), stop=max(stop)),
       by=.(group=cumsum(c(1, tail(start, -1) > head(stop, -1))))]
   group    start      stop
1:     1 65.72000  87.75625
2:     2 89.61625 104.94062

在这里,通过检查上一次启动是否大于停止,然后使用
cumsum
来构建组。在每个组中,计算最小开始时间和最大停止时间。

对于
基本R
熔化/取消堆叠
,让我们再添加一些日期,使问题更有趣和通用:

ranges<- data.frame(start = c(65.72000,65.72187, 65.94312,73.75625,89.61625,105.1,104.99),stop = c(79.72187,79.72375,79.94312,87.75625,104.94062,110.22,108.01))
ranges
#      start      stop
#1  65.72000  79.72187
#2  65.72187  79.72375
#3  65.94312  79.94312
#4  73.75625  87.75625
#5  89.61625 104.94062
#6 105.10000 110.22000
#7 104.99000 108.01000

library(reshape2)
ranges <- melt(ranges)
ranges <- ranges[order(ranges$value),]
ranges
#   variable     value
#1     start  65.72000
#2     start  65.72187
#3     start  65.94312
#4     start  73.75625
#8      stop  79.72187
#9      stop  79.72375
#10     stop  79.94312
#11     stop  87.75625
#5     start  89.61625
#12     stop 104.94062
#7     start 104.99000
#6     start 105.10000
#14     stop 108.01000
#13     stop 110.22000

看起来不太容易。你已经看过dplyr了吗?这将是我第一次尝试解决。我尝试了以下方法:
mdat x)mdat[upper.tri(mdat)| col(mdat)=row(mdat)]您将什么定义为重叠?相关:,。我猜如果下一行的开始在前一行的范围内,那么我希望保持下一行的“停止”。因此,如果下一行的起点是73.75625(终点是87.75625),而上一行的范围是65.94312到79.94312,那么我想有一个范围,作为两者的组合,基本上包括这两个范围:65.94312到87.75625。这很好地解决了我的问题,但我还不太明白如何解决。感谢你的小提琴技巧,同时我再次检查代码,试图辨别它的魔力。@Jemus42代码首先按
start
列对行进行排序
lag(stop)
添加一个虚拟列,其中包含先前的
stop
cummax
将保留以前的
stop
值中的最高值,以便您可以与
start
列进行比较。如果
start
值大于新组中前面
stop
值的最大值
cumsum
将累计
TRUE
s,以便您拥有每组的标识符(
g
)<代码>总结
将按组id进行聚合,并获取乞讨和间隔结束时间。非常智能的解决方案@Psidom:)
ranges<- data.frame(start = c(65.72000,65.72187, 65.94312,73.75625,89.61625,105.1,104.99),stop = c(79.72187,79.72375,79.94312,87.75625,104.94062,110.22,108.01))
ranges
#      start      stop
#1  65.72000  79.72187
#2  65.72187  79.72375
#3  65.94312  79.94312
#4  73.75625  87.75625
#5  89.61625 104.94062
#6 105.10000 110.22000
#7 104.99000 108.01000

library(reshape2)
ranges <- melt(ranges)
ranges <- ranges[order(ranges$value),]
ranges
#   variable     value
#1     start  65.72000
#2     start  65.72187
#3     start  65.94312
#4     start  73.75625
#8      stop  79.72187
#9      stop  79.72375
#10     stop  79.94312
#11     stop  87.75625
#5     start  89.61625
#12     stop 104.94062
#7     start 104.99000
#6     start 105.10000
#14     stop 108.01000
#13     stop 110.22000
indices <- intersect(which(ranges$variable=='start')-1, which(ranges$variable=='stop'))
unstack(ranges[c(1, sort(c(indices, indices+1)), nrow(ranges)),], value~variable)
#      start      stop
#1  65.72000  87.75625
#2  89.61625 104.94062
#3 104.99000 110.22000