У меня большой набор данных, и я пытаюсь отфильтровать дни после определенного события c для каждого субъекта. Эта проблема заключается в том, что интересующее «событие» может происходить несколько раз для некоторых субъектов, а для некоторых субъектов событие вообще не происходит (в этом случае их можно просто удалить из обобщенных данных).
Вот пример данных и того, что я пробовал:
library(tidyverse)
set.seed(355)
subject <- c(rep(LETTERS[1:4], each = 40), rep("E", times = 40))
event <- c(sample(0:1, size = length(subject)-40, replace = T, prob = c(0.95, 0.05)), rep(0, times = 40))
df <- data.frame(subject, event)
df %>%
filter(event == 1) %>%
count(subject, event, sort = T)
# A tibble: 4 x 3
subject event n
<fct> <dbl> <int>
1 D 1 3
2 A 1 2
3 B 1 2
4 C 1 2
Итак, мы видим, что у субъекта D было событие 3 раза, в то время как у субъектов A, B и C это событие было 2 раза. Субъект E вообще не имел события.
Моим следующим шагом было создание тега «событие», который идентифицирует, где произошло каждое событие, а затем генерирует NA для всех строк. Я также создал последовательность событий, которая располагается между событиями, потому что я думал, что это может быть полезно, но я не пытался использовать ее.
df_cleaned <- df %>%
group_by(subject, event) %>%
mutate(event_seq = seq_along(event == 1),
event_detail = ifelse(event == 1, "event", NA)) %>%
as.data.frame()
Я пробовал два разных подхода, используя filter()
и between()
, чтобы получить каждое событие и 2 строки после каждого события. Оба этих подхода создают ошибку из-за множества событий внутри субъекта. Я не могу найти хороший обходной путь для этого.
Подход 1:
df_cleaned %>%
group_by(subject) %>%
filter(., between(row_number(),
left = which(!is.na(event_detail)),
right = which(!is.na(event_detail)) + 1))
Подход 2:
df_cleaned %>%
group_by(subject) %>%
mutate(event_group = cumsum(!is.na(event_detail))) %>%
filter(., between(row_number(), left = which(event_detail == "event"), right = which(event_detail == "event") + 2))