Обратите внимание, что я уже написал некоторый код, использующий dplyr, чтобы делать то, что мне нужно, но он кажется очень неуклюжим, и мне интересно, есть ли более элегантное решение
У меня есть датафрейм, который, по сути, таков:
df = data.frame(
id = c(1,1,1,2,2,2),
date = as.Date(c('2018/01/01', '2018/01/02',
'2018/01/03', '2018/01/01', '2018/01/02', '2018/06/01'))
)
id date
1 1 2018-01-01
2 1 2018-01-02
3 1 2018-01-03
4 2 2018-01-01
5 2 2018-01-02
6 2 2018-06-01
Я хочу получить таблицу, которая показывает для каждого идентификатора количество записей в течение 30 дней после первой записи и количество записей в течение 30 дней после последней записи. Для этой простой версии вывод должен выглядеть следующим образом:
id start.records end.records
1 3 3
2 2 1
Я могу получить желаемый вывод с помощью этого кода:
df %>%
group_by(id) %>%
summarize(min.date = min(date)) %>%
mutate(min.date.plus.30 = min.date + 30) %>%
fuzzy_left_join(
df,
by = list(x=c("id", "min.date.plus.30"), y=c("id", "date")),
match_fun = list(`==`, `>`)
) %>%
group_by(id.x, min.date) %>%
summarize(start.records = n()) %>%
left_join(
df %>%
group_by(id) %>%
summarize(max.date = max(date)) %>%
mutate(max.date.minus.30 = max.date - 30) %>%
fuzzy_left_join(
df,
by = list(x=c("id", "max.date.minus.30"), y=c("id", "date")),
match_fun = list(`==`, `<`)
) %>%
group_by(id.x, max.date) %>%
summarize(end.records = n()),
by = "id.x"
)
Но это похоже на очень не элегантное решение.
Есть ли лучший способ сделать это? Я бы предпочел не использовать sqldf, поскольку он не легко обрабатывает вычисления даты, а мой реальный набор данных содержит более 150 000 строк, и даже простые тестовые запросы sqldf выполняются вечно.
Заранее спасибо за любую помощь!