У меня есть датафрейм, для которого характерно множество разных идентификаторов. Для каждого идентификатора существует несколько событий, которые характеризуются совокупной продолжительностью времени между событиями (часы) и продолжительностью этого события (секунды). Итак, это будет выглядеть примерно так:
Id <- c(1,1,1,1,1,1,2,2,2,2,2)
cumulative_time<-c(0,3.58,8.88,11.19,21.86,29.54,0,5,14,19,23)
duration<-c(188,124,706,53,669,1506.2,335,349,395,385,175)
test = data.frame(Id,cumulative_time,duration)
> test
Id cummulative_time duration
1 1 0.00 188.0
2 1 3.58 124.0
3 1 8.88 706.0
4 1 11.19 53.0
5 1 21.86 669.0
6 1 29.54 1506.2
7 2 0.00 335.0
8 2 5.00 349.0
9 2 14.00 395.0
10 2 19.00 385.0
11 2 23.00 175.0
Я бы хотел сгруппировать по идентификатору, а затем реструктурировать группу путем выборки по кумулятивному количеству, скажем, каждые 10 часов, и из этой суммы в 10 часов по продолжительности, которая произошла в 10-часовом интервале. Количество ячеек, которые я хочу, должно быть от 0 до 30 часов. Таким образом, было бы 3 бункера.
Я посмотрел на функцию cut
и сумел взломать ее в рамках фрейма данных - даже я, как новый пользователь r, знаю, что это не красиво
test_cut = test %>%
mutate(bin_durations = cut(test$cummulative_time,breaks = c(0,10,20,30),labels = c("10","20","30"),include.lowest = TRUE)) %>%
group_by(Id,bin_durations) %>%
mutate(total_duration = sum(duration)) %>%
select(Id,bin_durations,total_duration) %>%
distinct()
, который дает вывод:
test_cut
Id time_bins duration
1 1 10 1018.0
2 1 20 53.0
3 1 30 2175.2
4 2 10 684.0
5 2 20 780.0
6 2 30 175.0
В конечном счете, я хочу, чтобы интервал и число ячеек были произвольными - если у меня есть промежуток в 5000 часов, и я хочу, чтобы ячейка производилась за 1 час. Для этого я бы использовал breaks=seq(0,5000,1)
для bins
Я бы сказал labels = as.character(seq(1,5000,1))
Это также будет применяться к очень большому кадру данных, поэтому скорость вычислений несколько желательна.
Было бы неплохо использовать решение dplyr, так как я применяю биннинг для каждой группы.
Полагаю, между cut
и, возможно, split
имеется хорошее взаимодействие для генерации желаемого результата.
Заранее спасибо.
Обновление
После тестирования я обнаружил, что даже моя текущая реализация не совсем то, что я хотел бы, как если бы я сказал:
n=3
test_cut = test %>%
mutate(bin_durations = cut(test$cumulative_time,breaks=seq(0,30,n),labels = as.character(seq(n,30,n)),include.lowest = TRUE)) %>%
group_by(Id,bin_durations) %>%
mutate(total_duration = sum(duration)) %>%
select(Id,bin_durations,total_duration) %>%
distinct()
Я получаю
test_cut
# A tibble: 11 x 3
# Groups: Id, bin_durations [11]
Id bin_durations total_duration
<dbl> <fct> <dbl>
1 1 3 188
2 1 6 124
3 1 9 706
4 1 12 53
5 1 24 669
6 1 30 1506.
7 2 3 335
8 2 6 349
9 2 15 395
10 2 21 385
11 2 24 175
Если в последовательности ячеек нет вхождений, я просто должен получить 0 в столбце длительности. Скорее, чем упущение.
Таким образом, это должно выглядеть так:
test_cut
# A tibble: 11 x 3
# Groups: Id, bin_durations [11]
Id bin_durations total_duration
<dbl> <fct> <dbl>
1 1 3 188
2 1 6 124
3 1 9 706
4 1 12 53
5 1 15 0
6 1 18 0
7 1 21 0
8 1 24 669
9 1 27 0
10 1 30 1506.
11 2 3 335
12 2 6 349
13 2 9 0
14 2 12 0
15 2 15 395
16 2 18 0
17 2 21 385
18 2 24 175
19 2 27 0
20 2 30 0