Создайте группы и выберите продолжительность, в которой интервал времени не превышает заданное c число (R, Dplyr) - PullRequest
1 голос
/ 04 февраля 2020

У меня есть фрейм данных, df, где я хотел бы создать «группу» и затем взять ее продолжительность, учитывая, что последовательность дата-время не превышает 2 минуты.

DateA

5:00:01 PM
5:00:02 PM
5:00:03 PM
5:00:04 PM 
5:01:26 PM 
5:01:27 PM
5:01:28 PM 
5:01:30 PM
5:02:55 PM
5:02:56 PM
5:10:01 PM

Это результат Я хотел бы:

Group             Duration

  a                  3 sec 
  b                  4 sec
  c                  1 sec
  d                  0 sec

Где дата-время 5:00:01, 5:00:02, 5:00:03 и 5: 00: 4 сгруппирована как Где дата-время 5: 01:26, 5:01:27, 5:01:28, 5:01:30 сгруппированы как b, где дата-время 5:02:55, 5:02:56 сгруппирована как c, где дата-время 5:10:01 сгруппировано как d

Here is my dput:

structure(list(DateA = structure(c(1L, 2L, 2L, 3L, 4L, 5L, 6L, 
7L, 8L, 9L, 10L, 11L), .Label = c("5:00:01", "5:00:02", "5:00:03", 
"5:00:04", "5:01:26", "5:01:27", "5:01:28", "5:01:30", "5:02:55", 
"5:02:56", "5:10:01"), class = "factor")), class = "data.frame", row.names = c(NA, 
-12L))

Это то, что я пробовал, однако я не уверен, как изменить код, в котором столбец DateA сгруппирован вместе с трех sh .

library(dplyr)
thresh <- 2

df %>%  
mutate(DateA = mdy_hms(DateA)) %>%
group_by(DateA, Group = cumsum(difftime(DateA, 
lag(DateA, default = first(DateA)), 
units = "mins") > thresh)) %>% summarise(Duration = 
difftime(max(DateAC), min(DateA), units = "secs")) %>%
ungroup %>%
mutate(Group = paste0('a', row_number()))

1 Ответ

1 голос
/ 04 февраля 2020

Мы можем преобразовать в data.table с помощью setDT, изменить 'DateA' на объект Time, создать 'группу', выполнив кумулятивную сумму diff логического выражения и использовать difftime для вычисления разница в секундах между max и min

library(data.table)
setDT(df)[, DateA := as.ITime(as.character(DateA))][, 
   .(Duration = difftime(max(as.POSIXct(DateA)), min(as.POSIXct(DateA)), 
     unit = 'sec')),.(group = letters[cumsum(c(TRUE, diff(DateA) > thresh))])]
#   group Duration
#1:     a   3 secs
#2:     b   4 secs
#3:     c   1 secs
#4:     d   0 secs

Или мы можем изменить группировку с diff на difftime, чтобы избежать любых несоответствий в unit s

setDT(df)[, DateA := as.ITime(as.character(DateA))][, 
         .(Duration = difftime(max(as.POSIXct(DateA)), min(as.POSIXct(DateA)), 
      unit = 'sec')), .(group = letters[cumsum(c(TRUE, 
      difftime(DateA[-1], DateA[-.N], unit = "min") > thresh))])]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...