3

我想找到从第一个开始到最后一个结束位置不重叠的最近范围。知道如何进行吗?在下面的示例中,应过滤掉 c(8, 33) 和 c(155, 161),因为它们与前面的范围重叠。

#Example data
df <- data.frame(
  start = c(7,8,14,34,67,92,125,155,170,200),
  end = c(13,33,25,66,91,124,155,161,181,214)
)

   start end
1      7  13
2      8  33
3     14  25
4     34  66
5     67  91
6     92 124
7    125 155
8    155 161
9    170 181
10   200 214

#Overlapping rows
  start end
1     8  33
2   155 161

#Desired output where overlapping rows are filtered away
  start end
1     7  13
2    14  25
3    34  66
4    67  91
5    92 124
6   125 155
7   170 181
8   200 214
4

3 回答 3

2

我会将其作为一个简单的循环来执行,因为是否排除一行取决于前一行的计算结果

i <- 2

while(i < nrow(df)) {
  if(df$start[i] <= df$end[i - 1]) {
    df <- df[-i,] 
  } else { 
    i <- i + 1
  }
}

df
#>    start end
#> 1      7  13
#> 3     14  25
#> 4     34  66
#> 5     67  91
#> 6     92 124
#> 7    125 155
#> 9    170 181
#> 10   200 214
于 2020-09-07T08:05:46.143 回答
0

由于您的start列已按升序排列,因此您可以end仅通过以下值检查重叠,例如,

repeat {
  ind <- with(df, head(which(!c(TRUE,end[-nrow(df)]<start[-1])),1))
  if (!length(ind)) break
  df <- df[-ind,]
}

这使

> df
   start end
1      7  13
3     14  25
4     34  66
5     67  91
6     92 124
7    125 155
9    170 181
10   200 214
于 2020-09-07T10:41:54.600 回答
0

我在 R 社区网站上发布了以下答案:

find_nonover <- function(df) {
  to_drop <- logical(nrow(df))
  for (i in seq_along(df[["end"]])) {
    if (i %in% which(to_drop)) next
    to_drop <- to_drop | c(logical(i), df[i, "end"] >= df[["start"]][-seq_len(i)])
  }
  list(nonover = df[!to_drop, ],
       over    = df[to_drop, ])
}

https://community.rstudio.com/t/find-closest-non-overlapping-ranges-from-start-to-end/79642/3

于 2020-09-08T08:19:23.393 回答