【问题标题】:In R: Group the sequence of events based on their ID and calculating the time difference between the first and last seen event在 R 中:根据事件的 ID 对事件序列进行分组,并计算第一个和最后一个看到的事件之间的时间差
【发布时间】:2020-05-26 16:29:45
【问题描述】:

在下面的数据框中,我有可以重复的事件序列,直到生成新事件。 在选择这些相似的行后,我想使用一个函数来帮助我,计算 last seen eventtimestamp_endfirst eventtimestamp_start 之间的差异/strong>。

数据框:

DF1 <- data.frame(segment_id = c(1, 1, 1, 1, 2 , 3, 4), first_event= c("a", "a", "a","a", "a", "b","c" ), second_event = c("a", "a","a","a", "b", "c", "c"), timestamp_start = c("2019-06-06 11:47:00","2019-06-06 12:59:38", "2019-06-06 13:01:03", "2019-06-06 14:47:03   ", "2019-06-06 18:47:00", "2019-06-06 22:47:00", "2019-06-07 02:47:00") , timestamp_end = c("2019-06-06 12:59:38", "2019-06-06 13:01:03", "2019-06-06 14:47:03", "2019-06-06 18:47:00", "2019-06-06 22:47:00    ", "2019-06-07 02:47:00", "2019-06-07 06:47:00"))


segment_id   first_event   second_event          timestamp_start            timestamp_end

  1            a              a                2019-06-06 11:47:00        2019-06-06 12:59:38
  1            a              a                2019-06-06 12:59:38        2019-06-06 13:01:03
  1            a              a                2019-06-06 13:01:03        2019-06-06 14:47:03
  1            a              a                2019-06-06 14:47:03        2019-06-06 18:47:00
  2            a              b                2019-06-06 18:47:00        2019-06-06 22:47:00
  3            b              c                2019-06-06 22:47:00        2019-06-07 02:47:00
  4            c              c                2019-06-07 02:47:00        2019-06-07 06:47:00

所以,我尝试了 dplyrpackage 和 group_by()mutate() 函数。但是,我不确定哪个函数可以帮助我获得持续时间。

DF2 <- DF1 %>%
   group_by(segment_id)%>%
   mutate("duration" = difftime(????) , units = 'hours')

我正在寻找 DF2 的最终结果应该是这样的:

>DF2
segment_id   first_event   second_event          timestamp_start            timestamp_end        duration

  1            a              a                2019-06-06 11:47:00        2019-06-06 18:47:00      7        
  2            a              b                2019-06-06 18:47:00        2019-06-06 22:47:00      4
  3            b              c                2019-06-06 22:47:00        2019-06-07 02:47:00      4
  4            c              c                2019-06-07 02:47:00        2019-06-07 06:47:00      4

感谢您在这方面的帮助。

【问题讨论】:

    标签: r dataframe datatable dplyr tidyverse


    【解决方案1】:

    使用data.table的选项:

    setDT(DF1)[, .(timestamp_start=min(timestamp_start), timestamp_end=max(timestamp_end)), .(segment_id, first_event, second_event)][, 
        duration := difftime(timestamp_end, timestamp_start, units="hours")][]
    

    数据:

    library(data.table)
    cols <- c("timestamp_start", "timestamp_end")
    setDT(DF1)[, (cols) := lapply(.SD, as.POSIXct, format="%Y-%m-%d %T"), .SDcols=cols]
    

    【讨论】:

      【解决方案2】:
      library(lubridate)
      
      DF1 %>%
          mutate_at(vars(timestamp_start, timestamp_end)
                    , function(x) ymd_hms(as.character(x))) %>%
          group_by(segment_id) %>%
          summarise(first_event = first(first_event)
                    , second_event = last(second_event)
                    , timestamp_start = first(timestamp_start)
                    , timestamp_end = last(timestamp_end)
                    , duration = max(timestamp_end) - min(timestamp_start))
      
        segment_id first_event second_event timestamp_start     timestamp_end       duration
             <dbl> <fct>       <fct>        <dttm>              <dttm>              <drtn>  
      1          1 a           a            2019-06-06 11:47:00 2019-06-06 18:47:00 7 hours 
      2          2 a           b            2019-06-06 18:47:00 2019-06-06 22:47:00 4 hours 
      3          3 b           c            2019-06-06 22:47:00 2019-06-07 02:47:00 4 hours 
      4          4 c           c            2019-06-07 02:47:00 2019-06-07 06:47:00 4 hours 
      

      【讨论】:

        【解决方案3】:

        我们可以将timestamp_starttimestamp_end列更改为POSIXct类型,group_bysegment_idfirst_eventsecond_event,得到firsttimestamp_start和@98765343@30@98765343@30并计算它们之间的小时差。

        library(dplyr)
        
        DF1 %>%
          mutate_at(vars(starts_with('timestamp')), as.POSIXct) %>%
          group_by(segment_id, first_event, second_event) %>%
          summarise(timestamp_start = first(timestamp_start), 
                    timestamp_end = last(timestamp_end),
                    duration = as.numeric(difftime(timestamp_end, 
                              timestamp_start, units = "hours")))
        
        #     segment_id first_event second_event timestamp_start     timestamp_end       duration
        #       <dbl> <fct>       <fct>        <dttm>              <dttm>                 <dbl>
        #1          1 a           a            2019-06-06 11:47:00 2019-06-06 18:47:00        7
        #2          2 a           b            2019-06-06 18:47:00 2019-06-06 22:47:00        4
        #3          3 b           c            2019-06-06 22:47:00 2019-06-07 02:47:00        4
        #4          4 c           c            2019-06-07 02:47:00 2019-06-07 06:47:00        4
        

        【讨论】:

        • 这是完美的,谢谢,我会在最后添加一个缺少的inner_joininner_join(DF1, by = 'segment_id').
        猜你喜欢
        • 2022-11-02
        • 1970-01-01
        • 2018-10-14
        • 1970-01-01
        • 2017-05-21
        • 1970-01-01
        • 1970-01-01
        • 2022-11-30
        • 1970-01-01
        相关资源
        最近更新 更多