#r #dplyr #iranges
#r #dplyr #iranges
Вопрос:
Я хотел бы найти ближайшие диапазоны, которые не перекрываются от первого начала до последней конечной позиции. Есть идеи, как поступить? В приведенном ниже примере 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
Комментарии:
1. Строка 3, 14 25 перекрывается со строкой 2 8, 33, но она не удаляется?
Ответ №1:
Я бы сделал это как простой цикл, поскольку исключение строки зависит от результата вычисления для предыдущей строки
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
Ответ №2:
Я пошел со следующим ответом, опубликованным на веб-сайте сообщества 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
Ответ №3:
Поскольку ваш 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
Комментарии:
1. очень хорошо, но это не сработало бы для следующей последовательности: df <- data.frame(start = c(7,8,100), end = c(8,100,101))
2. @Nivel Тогда каков ваш желаемый результат?
3. Желаемый результат был бы start = c (7, 100), end = c(8, 101). Если я использую вашу формулу, также отбрасывается последняя строка.
4. @Nivel Кажется, вы все равно сохраняете последнюю строку. Пожалуйста, ознакомьтесь с моим обновлением
5. Извините, но это все еще не дает правильного вывода. Рассмотрим следующее: df <- data.frame(начало = c (7,8,10,12,14), конец = c (16,9,11,13,15)). Желаемый результат — start = 7 и end = 16.