Я пытаюсь перебрать фрейм данных и найти последовательности событий между начальным и остановочным объектом (событие, которое происходит как в начале, так и в конце).
Вот некоторые примеры данных:
time = c('8:20', '8:19', '8:15', '8:14', '8:14', '8:10', '8:04', '8:03', '8:00', '7:59', '7:55', '7:44', '7:43','7:42')
action = c('A', 'B', 'C', 'B', 'F', 'T', 'Z', 'U', 'A', 'G', 'B', 'C', 'L', 'Z')
group = c('group1', 'group1', 'group1', 'group2', 'group1', 'group1', 'group2', 'group2','group2', 'group2', 'group2', 'group2', 'group1', 'group1')
test.df = cbind(time, action, group) %>% data.frame()
Полный набор данных длиннее и шире, но этого должно быть достаточно.
Правила таковы, что если одна группа (либо группа1, либо группа2) регистрирует действие «А» и только «А», она запускает последовательность запуска. После этого может произойти любое количество событий, пока противоположная группа (группа 2, если группа 1 инициировала «А», или группа 1, если это наоборот) не зарегистрирует действие «Z». Действие «Z» противоположной группы означает «конечную» точку последовательности.
Этот процесс повторяется сотни раз по кадру данных.
Каждый раз, когда одна из групп запускает действие «A», я хочу, чтобы каждое последующее событие было связано со значением идентификатора, которое суммируется каждый раз, когда группа запускает новую последовательность в фрейме данных, пока действие «Z» не будет выполнено противоположной группой. .
IE, в приведенном выше примере будет новый столбец, указывающий, что это «группа 1», к которой принадлежит последовательность, и это идентификатор 1, а их следующая последовательность, которая инициируется позже в наборе данных, будет иметь идентификатор 2 для группы 1. , так далее.
time action group group.sequence id
8:20 A group1 group1 1
8:19 B group1 group1 1
8:15 C group1 group1 1
8:14 B group2 group1 1
8:14 F group1 group1 1
[...]
Таким образом, можно найти суммирование по времени, количество промежуточных действий, типы промежуточных действий. Любые действия, которые происходят вне действий группы от «А» до «Я» (например, строка 8), можно пока игнорировать.
Предпочитаю что-то, что я могу использовать в своей трубке dplyr, но открыто для любых решений, которые принесут успех.
Вот моя попытка использовать tidyverse
. Запустите код с большим dataframe
и дайте мне знать, если ваш ожидаемый ответ отличается от моего.
library(tidyverse)
test.df %>%
mutate_if (is.factor, as.character) %>%
filter(action != "U") %>%
mutate(temp = ifelse(paste(group, action) %in%
c("group1 A", "group2 A", "group1 Z", "group2 Z"),
paste(group, action), NA),
group.sequence = ifelse(temp %in% c("group1 Z", "group2 Z"), NA, temp),
group.sequence = ifelse(!is.na(group.sequence), group, NA)) %>%
group_by(group.sequence) %>%
mutate(id = 1:n(),
id = ifelse(is.na(group.sequence), NA, id)) %>%
ungroup() %>%
fill(c(group.sequence, id)) %>%
select(-temp)
#> # A tibble: 13 x 5
#> time action group group.sequence id
#> <chr> <chr> <chr> <chr> <int>
#> 1 8:20 A group1 group1 1
#> 2 8:19 B group1 group1 1
#> 3 8:15 C group1 group1 1
#> 4 8:14 B group2 group1 1
#> 5 8:14 F group1 group1 1
#> 6 8:10 T group1 group1 1
#> 7 8:04 Z group2 group1 1
#> 8 8:00 A group2 group2 1
#> 9 7:59 G group2 group2 1
#> 10 7:55 B group2 group2 1
#> 11 7:44 C group2 group2 1
#> 12 7:43 L group1 group2 1
#> 13 7:42 Z group1 group2 1
Для справки, быстрый хак, который я использовал, состоял в том, чтобы добавить шаг между вашим кодом и перед функцией заполнения, где я изменил значение id
на 0 после события Z, так как это всегда означает перерыв в действиях. Затем, когда я использую функцию заполнения, она учитывает разрывы и присваивает идентификаторы последовательности только действиям между A
и Z
.
Почти 100%, я сказал, что мы можем игнорировать строку 8, но не имел в виду, что мы можем удалить ее буквально. Прямо сейчас в расширенном фрейме данных после запуска скрипта есть несколько экземпляров после действия «Z», где другие события происходят перед следующим действием «A» для любой команды, которые сгруппированы в один и тот же идентификатор #. У вас есть рекомендации, как это учесть?