R - Как суммировать разницу во времени в пределах определенных временных интервалов?

У меня есть сотни тысяч записей со временем начала, временем окончания и типом активности для этого периода времени. Я хотел бы иметь возможность найти общее количество времени, которое совпадает с определенными, заданными интервалами времени и сгруппировать по типу деятельности.

Вот что у меня есть:

    start                      stop                      activity
 2015-12-24 12:55:00.000    2015-12-24 13:25:00.000         a
 2015-12-24 13:45:00.000    2015-12-24 13:59:00.000         b
 2015-12-24 13:55:00.000    2015-12-24 14:10:00.000         b
 2015-12-24 14:13:00.000    2015-12-24 15:05:00.000         a

И вот пример того, что я хотел бы иметь в конечном результате. Это показано сгруппированным по получасу, но возможность указать любой нормальный временной интервал (день, час, полчаса, четверть часа) идеальна:

   intervalStart               activityMinutes      activity       
 2015-12-24 12:30:00.000         5                     a
 2015-12-24 13:00:00.000         25                    a                                 
 2015-12-24 13:30:00.000         19                    b
 2015-12-24 14:00:00.000         17                    a
 2015-12-24 14:00:00.000         10                    b
 2015-12-24 14:30:00.000         30                    a
 2015-12-24 15:00:00.000         5                     a

У меня есть SQL-запрос, который очень хорошо подходит для этого, который я получил из предыдущего вопроса stackoverflow, который я опубликовал ранее в этом году:

Как суммировать время действия, которое произошло в течение 15-минутных интервалов с использованием перекрывающихся времен начала и окончания (SQL) (t-SQL)

Однако использование этого запроса в R очень громоздко и не всегда работает в зависимости от диапазона дат, на который я смотрю. Это также очень медленно, и я надеюсь, что решение с использованием R будет быстрее и надежнее.

Спасибо за помощь и дайте мне знать, если есть какая-либо другая информация, которую я могу предоставить!

РЕДАКТИРОВАТЬ - отредактировано для отображения результатов в интервалах времени с 30-минутным интервалом.


person William    schedule 28.12.2015    source источник
comment
Посмотрите на ?difftime   -  person Jaap    schedule 28.12.2015
comment
@Jaap Я просмотрел difftime, но не нашел способа сохранить разницу во времени в пределах заранее определенных интервалов.   -  person William    schedule 28.12.2015
comment
Используя dplyr, вы можете попробовать что-то вроде этого для группировки по дням и часам для каждого действия: df %›% mutate(interval = format(start, '%Y-%m-%d %H')) %›% group_by( интервал, активность) %›% summarise(activityMinutes sum(difftime(stop, start, unit = 'mins')))   -  person Gopala    schedule 28.12.2015
comment
Этот выше метод будет группировать по часам дня. Если вам нужны произвольные интервалы, вы должны предоставить более конкретный пример ввода и конкретный желаемый результат, чтобы кто-то мог вам помочь.   -  person Gopala    schedule 28.12.2015
comment
Вы можете сделать что-то вроде library(data.table) ; setDT(df)[, seq(start, stop, by = "min"), by = names(df)][, .N, by = .(as.IDate(V1), hour(V1), activity)], если start и stop относятся к классу POSIXct, хотя я не ручаюсь за эффективность.   -  person David Arenburg    schedule 28.12.2015
comment
@ user3949008 Я знаком с dplyr, так что попробую. я отредактировал сообщение, чтобы показать выходные данные, разбитые на 30-минутные интервалы.   -  person William    schedule 28.12.2015
comment
Старт и стоп @DavidArenburg находятся в POSIXct, так что я попробую. Есть ли способ указать интервал времени, отличный от часа?   -  person William    schedule 28.12.2015
comment
Чтобы указать временные интервалы, отличные от часа, вам нужно будет написать еще немного кода для преобразования вывода 'format()' выше в желаемые 30 минут. Например, вы можете написать df$minuteInterval = ifelse(as.numeric(format(start, '%M')) ‹ 30, 00, 30). Затем вы можете добавить minuteInterval к ​​приведенному выше 'group_by()', который я показал вам с помощью dplyr.   -  person Gopala    schedule 28.12.2015
comment
@user3949008 user3949008 Если я не делаю что-то не так, похоже, что метод dplyr не даст того, что мне нужно. Результаты для строки 1 в моем примере дали бы общее время 30 минут и поместили бы все это в интервал 12:30. Вместо этого мне нужно время, разделенное на интервалы 12:30 и 13:00.   -  person William    schedule 28.12.2015
comment
@DavidArenburg Кажется, ваше решение работает! Я раньше не использовал data.table, но, возможно, мне нужно начать. Если вы отправите ответ, я отмечу его как правильный. Спасибо   -  person William    schedule 28.12.2015
comment
Если вы предоставите воспроизводимый пример, я могу предоставить рабочий код dplyr. На вашем месте я бы изучил dplyr и data.table. Последнее превосходно, но dplyr очень универсален и интуитивно понятен, особенно для новичков в R.   -  person Gopala    schedule 30.12.2015
comment
@user3949008 user3949008 Я некоторое время работал с dplyr, поэтому я знаком со многими основными функциями, которые он может делать. Я изучаю data.table и иногда буду использовать его вместо dplyr, в зависимости от того, что я пытаюсь сделать. Я согласен, что это не так интуитивно понятно, хотя   -  person William    schedule 08.01.2016