У меня есть data.frame test
, где я бы хотел определить, что будет до и после шаблона bar
- foo
для каждого id
.Шаблон должен быть последовательным по timestamp
Например, в следующем примере есть три паттерна bar
- foo
.
> test
timestamp id message result
1 2019-01-01 00:00:21 1 bar negative
2 2019-01-01 00:00:58 1 bar positive
3 2019-01-01 00:01:35 1 foo positive
4 2019-01-01 00:03:02 1 bar negative
5 2019-01-01 00:06:42 1 baz positive
6 2019-01-01 00:07:16 1 baz positive
7 2019-01-01 00:07:39 1 bar positive
8 2019-01-01 00:09:14 2 bar negative
9 2019-01-01 00:09:56 2 foo negative
10 2019-01-01 00:10:56 2 foo positive
11 2019-01-01 00:11:13 2 foo negative
12 2019-01-01 00:11:32 2 foo positive
13 2019-01-01 00:11:49 2 bar negative
14 2019-01-01 00:12:18 2 foo positive
15 2019-01-01 00:15:28 2 bar positive
В результате идеальный вывод будет выглядеть следующим образом:
> output
before after id
1 negative negative 1
2 <NA> positive 2
3 positive positive 2
Код, который я применил ниже , работает , но кажется сложным и неэффективным
test %>%
group_by(id) %>%
mutate(next.message = lead(message, order_by=timestamp),
previous.result = lag(result, order_by=timestamp),
next.result = lead(result, n = 2, order_by=timestamp)) %>%
filter(message == 'bar', next.message == 'foo') %>%
filter_all(any_vars(!is.na(.))) %>%
select (-c(timestamp, message, result, next.message)) %>%
rename(before = previous.result , after = next.result)
Что может быть лучше для решения этой проблемы с использованием функций dplyr
или data.table
?
пример данных:
dput(test)
structure(list(timestamp = structure(c(1546318821, 1546318858,
1546318895, 1546318982, 1546319202, 1546319236, 1546319259, 1546319354,
1546319396, 1546319456, 1546319473, 1546319492, 1546319509, 1546319538,
1546319728), class = c("POSIXct", "POSIXt")), id = c(1, 1, 1,
1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2), message = c("bar", "bar",
"foo", "bar", "baz", "baz", "bar", "bar", "foo", "foo", "foo",
"foo", "bar", "foo", "bar"), result = c("negative", "positive",
"positive", "negative", "positive", "positive", "positive", "negative",
"negative", "positive", "negative", "positive", "negative", "positive",
"positive")), row.names = c(NA, -15L), class = "data.frame")