Да, это простое решение в базе R:
indx <- unlist(lapply(which(df$tag == "event"), "+", 0:1))
df[indx, ]
# subject value1 value2 tag
#6 a 25.996706 15.65917 event
#7 a 20.336984 35.03734 <NA>
#16 b 9.825914 25.34336 event
#17 b 24.344257 30.15755 <NA>
#24 c 18.586266 33.82119 event
#25 c 25.879272 52.43784 <NA>
#39 d 24.366653 25.03767 event
#40 d 19.870183 36.61909 <NA>
#43 e 23.706029 43.46765 event
#44 e 15.091674 29.45431 <NA>
Здесь which
возвращает все признаки строки для «события», а lapply
добавляет вектор 0:1
(т.е.0 и 1) для каждого из этих признаков, указывающих «строку-событие» и строку после.
Существует также несколько других способов получить его:
# Alternative 1
indx <- apply(expand.grid(which(df$tag == "event"), 0:1), 1, sum)
# Alternative 2
eindx <- which(df$tag == "event")
indx <- c(eindx, eindx + 1)
Эти признакиПриходите в другом порядке, но всегда можно sort
их.
Чтобы решить это по субъекту, вы можете проверить, что это добавление одного удерживает его в рамках предмета, и исключить, если нет:
eindx <- which(df$tag == "event")
not_eq <- which(df$subject[eindx] != df$subject[eindx+1])
indx <- sort(c(eindx, setdiff(eindx, not_eq) + 1))
df[indx, ]
или вы можете заключить эти подходы в функцию и использовать функции by
или split
:
get_event <- function(f) {
eindx <- which(f$tag == "event")
indx <- sort(c(eindx, eindx + 1))
f[indx, ]
}
res <- do.call(rbind, by(df, subject, get_event))
или
res <- do.call(rbind, lapply(split(df, subject), get_event))