Проверьте предыдущую строку в datetime, если время больше определенного значения, поместите в группу и измерьте его продолжительность в секундах (R, dplyr, lubridate) - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть набор данных, df: (набор данных содержит более 4000 строк)

  DATEB

  9/9/2019 7:51:58 PM
  9/9/2019 7:51:59 PM
  9/9/2019 7:51:59 PM
  9/9/2019 7:52:00 PM
  9/9/2019 7:52:01 PM
  9/9/2019 7:52:01 PM
  9/9/2019 7:52:02 PM
  9/9/2019 7:52:03 PM
  9/9/2019 7:54:00 PM
  9/9/2019 7:54:02 PM
  9/10/2019 8:00:00PM

I w sh для размещения в группах (если время не превышает 10 секунд после предыдущего ряда) а затем взять продолжительность вновь сформированной группы.

Требуемый вывод:

Group   Duration

 a       5 sec
 b       2 sec
 c       0 sec




 dput:


  structure(list(DATEB = structure(c(2L, 3L, 3L, 4L, 5L, 5L, 6L, 
  7L, 8L, 9L, 1L), .Label = c("      9/10/2019 8:00:00 PM", "      9/9/2019 7:51:58 PM", 
  "      9/9/2019 7:51:59 PM", "      9/9/2019 7:52:00 PM", "      9/9/2019 7:52:01 PM", 
  "      9/9/2019 7:52:02 PM", "      9/9/2019 7:52:03 PM", "      9/9/2019 7:54:00 PM", 
  "      9/9/2019 7:54:02 PM"), class = "factor")), class = "data.frame", row.names = c(NA, 
  -11L))

Я попробовал приведенный ниже код, который работает хорошо, за исключением того, что я хочу единицы в секундах. Код ниже дает единицы минут и секунд.

  library(dplyr)
  library(lubridate)


  df2 <- mutate(df,
          DATEB = lubridate::mdy_hms(DATEB))

 df2$time_since_last_row <- df2$DATEB - lag(df2$DATEB)
 df2$time_since_last_row[[1]] <- 0 # replace the first NA
 df2$group_10s <- 0

 for ( i in 2:nrow(df2))
   {
 if(df2$time_since_last_row[[i]]>seconds(10))
 df2$group_10s[[i]] <-  df2$group_10s[[i-1]] +1 
 else 
 df2$group_10s[[i]] <-  df2$group_10s[[i-1]]
      }





 df3 <- group_by(df2,
            group_10s) %>%
   summarise(volume_in_group=n(),
   min_DATEB=min(DATEB),
   max_DATEB=max(DATEB),
   group_duration = max_DATEB - min_DATEB)



   #nirgrahamuk-R community

Любое предложение приветствуется.

Ответы [ 2 ]

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

Вот что я бы сделал:

gap_threshold <- 10
df %>%
  mutate(DATEB = lubridate::mdy_hms(DATEB), 
         gap = c(0, diff(DATEB))) %>% 
  group_by(grp = cumsum(gap > gap_threshold)) %>% 
  summarise(begin = min(DATEB), end = max(DATEB), 
            duration = difftime(end, begin, units = "secs"))
# A tibble: 3 x 4
    grp begin               end                 duration
  <int> <dttm>              <dttm>              <drtn>  
1     0 2019-09-09 19:51:58 2019-09-09 19:52:03 5 secs  
2     1 2019-09-09 19:54:00 2019-09-09 19:54:02 2 secs  
3     2 2019-09-10 20:00:00 2019-09-10 20:00:00 0 secs

Обратите внимание, что в выводе больше столбцов, чем запрошено только для демонстрации.

Всякий раз, когда промежуток между двумя последующими строками больше заданного gap_threshold, количество групп grp увеличивается на единицу. Наконец, min() и max() взяты для каждой группы, и продолжительность вычисляется из них.

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

На самом деле я делал нечто подобное раньше. Вы можете изменить свой последний блок с помощью:

df3 <- group_by(df2, group_10s) %>%
  summarise(
    volume_in_group=n(),
    min_DATEB=min(DATEB),
    max_DATEB=max(DATEB),
    group_duration = as.numeric(max_DATEB - min_DATEB, units = "secs")
  )
...