Вы можете использовать некоторые вспомогательные функции из data.table
package: rleid
до «[g] enerate run-length type group id» и shift
для получения значений до и после фокального индекса в векторе.
library(data.table)
setDT(d)
d[ , r := rleid(activity)]
d[!(r %in% r[activity == "pt" & shift(activity, type = "lead") == "outside" |
shift(activity) == "outside" & activity == "pt"])]
# activity dist r
# 1: home 1 1
# 2: outside 5 3
# 3: outside 6 3
# 4: work 9 5
# 5: pt 10 6
# 6: pt 11 6
# 7: home 12 7
Пояснение:
Приведите data.frame
к data.table
(setDT(d)
). Создайте индекс продолжительности выполнения «активности» (rleid
). Проверьте, является ли текущее значение «pt», а следующее значение - «за пределами» (activity == "pt" & shift(activity, type = "lead") == "outside"
) или (|
), если текущее значение равно «pt», а предыдущее значение - «за пределами» (activity == "pt" & shift(activity) == "outside"
).
Если это условие TRUE
, захватите группы запусков, которые нужно удалить (r[<condition>]
). Проверьте, есть ли прогоны в удаляемых группах (r %in% <run groups to be removed>
). Если это так, не (!
) сохраняйте эти строки при индексировании данных (d[<condition>]
)
base
альтернатива с использованием rle
.
Значения прогонов 'pt' до или после 'outside' заменяются на NA
. Значение преобразуется обратно в вектор (inverse.rle
), а строки с NA
удаляются (na.omit
).
Очевидно, если в исходном наборе данных есть строки с NA
, которые вы хотите сохранить, вам нужно использовать другое значение для замены.
with(rle(d$activity),
values[c(which(head(values, -1) == "pt" & tail(values, -1) == "outside"),
which(head(values, -1) == "outside" & tail(values, -1) == "pt") + 1)]) <- NA
d$activity = inverse.rle(r)
na.omit(d)