我有一个包含开始和结束时间的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
在此示例中,第2行和第3行中的范围完全在第1行的"start"和第4行的"stop"之间的范围内.因此,重叠范围1-4应折叠为一个范围:
> ranges start stop 1 65.72000 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
而现在我只需要弄清楚如何结合所有真实的,但不确定它是否是最好的方法
你可以试试这个:
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 ##1 0 65.72000 87.75625 #2 1 89.61625 104.94062
这是一个data.table
解决方案
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
.在每组中,计算最小开始和最大停止.