【问题标题】:How to create a bucket of timestamps with a gap of X minutes in R from given timestamp values (example given)?如何根据给定的时间戳值(给出的示例)在 R 中创建一个间隔为 X 分钟的时间戳桶?
【发布时间】:2020-10-14 21:17:49
【问题描述】:

我有一个 mydf 表,它有带设备的 time_stamps 列。只要 2 个连续 time_stamps 之间的差异等于或小于 30 分钟,我就想继续合并 time_stamps 。开始 time_stamp 将被标记为 start_timestamp 并且当间隔超过 30 分钟时,我将结束该访问并将该结束分类为 end_timestamps,如下面给出的示例所示

df<-data.frame(customer=rep("XYZ",4),device=rep("x",4),time_stamps=c("2020-05-13 07:50:06","2020-05-13 07:55:06","2020-05-13 08:05:06","2020-05-13 08:50:06"))
df1<-data.frame(customer=rep("XYZ",3),device=rep("y",3),time_stamps=c("2020-05-14 07:50:06","2020-05-14 08:15:06","2020-05-14 08:25:06"))
df2<-data.frame(customer=rep("XYZ",1),device=rep("z",1),time_stamps=c("2020-05-16 09:50:06"))
df3<-data.frame(customer=rep("XYZ",2),device=rep("a",2),time_stamps=c("2020-05-16 09:50:06","2020-05-16 19:50:06"))
df4<-data.frame(customer=rep("XYZ",2),device=rep("b",2),time_stamps=c("2020-05-17 09:50:06","2020-05-17 10:15:06"))
df5<-data.frame(customer=rep("XYZ",4),device=rep("c",4),time_stamps=c("2020-05-13 07:50:06","2020-05-13 07:55:06","2020-05-13 08:05:06","2020-05-13 08:32:06"))

mydf<-rbind(df,df1,df2,df3,df4,df5)

这是我预期的数据框

expected_df<-data.frame(customer=rep("XYZ",8),device=c("x","x","y","z","a","a","b","c"),
        start_timestamp=c("2020-05-13 07:50:06","2020-05-13 08:50:06","2020-05-14 07:50:06","2020-05-16 09:50:06","2020-05-16 09:50:06","2020-05-16 19:50:06","2020-05-17 09:50:06","2020-05-13 07:50:06"),
        end_startstamp=c("2020-05-13 08:05:06","2020-05-13 08:50:06","2020-05-14 08:25:06","2020-05-16 09:50:06","2020-05-16 09:50:06","2020-05-16 19:50:06","2020-05-17 10:15:06","2020-05-13 08:32:06"))

【问题讨论】:

    标签: sql r dplyr sparklyr


    【解决方案1】:

    重点是创建我们可以group_by 的群组。为此,我们识别出彼此相距在 30 * 60 秒内的那些记录,然后使用 rle 合并它们:

    library(dplyr)
    
    mydf %>% 
      group_by(customer, device) %>% 
      mutate(time_stamps = as.POSIXct(time_stamps),
             diff = time_stamps - lag(time_stamps, default = first(time_stamps)),
             same_group_as_lag = diff <= 30*60,
             group = with(rle(same_group_as_lag), rep(seq_along(lengths), lengths)))
    #> # A tibble: 16 x 6
    #> # Groups:   customer, device [6]
    #>    customer device time_stamps         diff       same_group_as_lag  group
    #>    <fct>    <fct>  <dttm>              <drtn>     <lgl>              <int>
    #>  1 XYZ      x      2020-05-13 07:50:06     0 secs TRUE                   1
    #>  2 XYZ      x      2020-05-13 07:55:06   300 secs TRUE                   1
    #>  3 XYZ      x      2020-05-13 08:05:06   600 secs TRUE                   1
    #>  4 XYZ      x      2020-05-13 08:50:06  2700 secs FALSE                  2
    #>  5 XYZ      y      2020-05-14 07:50:06     0 secs TRUE                   1
    #>  6 XYZ      y      2020-05-14 08:15:06  1500 secs TRUE                   1
    #>  7 XYZ      y      2020-05-14 08:25:06   600 secs TRUE                   1
    #>  8 XYZ      z      2020-05-16 09:50:06     0 secs TRUE                   1
    #>  9 XYZ      a      2020-05-16 09:50:06     0 secs TRUE                   1
    #> 10 XYZ      a      2020-05-16 19:50:06 36000 secs FALSE                  2
    #> 11 XYZ      b      2020-05-17 09:50:06     0 secs TRUE                   1
    #> 12 XYZ      b      2020-05-17 10:15:06  1500 secs TRUE                   1
    #> 13 XYZ      c      2020-05-13 07:50:06     0 secs TRUE                   1
    #> 14 XYZ      c      2020-05-13 07:55:06   300 secs TRUE                   1
    #> 15 XYZ      c      2020-05-13 08:05:06   600 secs TRUE                   1
    #> 16 XYZ      c      2020-05-13 08:32:06  1620 secs TRUE                   1
    

    那么就是总结一下:

    mydf %>% 
      group_by(customer, device) %>% 
      mutate(time_stamps = as.POSIXct(time_stamps),
             diff = time_stamps - lag(time_stamps, default = first(time_stamps)),
             same_group_as_lag = diff <= 30*60,
             group = with(rle(same_group_as_lag), rep(seq_along(lengths), lengths))) %>% 
      group_by(group, add = TRUE) %>% 
      summarise(start_timestamp = min(time_stamps),
                end_startstamp = max(time_stamps))
    #> # A tibble: 8 x 5
    #> # Groups:   customer, device [6]
    #>   customer device group start_timestamp     end_startstamp     
    #>   <fct>    <fct>  <int> <dttm>              <dttm>             
    #> 1 XYZ      x          1 2020-05-13 07:50:06 2020-05-13 08:05:06
    #> 2 XYZ      x          2 2020-05-13 08:50:06 2020-05-13 08:50:06
    #> 3 XYZ      y          1 2020-05-14 07:50:06 2020-05-14 08:25:06
    #> 4 XYZ      z          1 2020-05-16 09:50:06 2020-05-16 09:50:06
    #> 5 XYZ      a          1 2020-05-16 09:50:06 2020-05-16 09:50:06
    #> 6 XYZ      a          2 2020-05-16 19:50:06 2020-05-16 19:50:06
    #> 7 XYZ      b          1 2020-05-17 09:50:06 2020-05-17 10:15:06
    #> 8 XYZ      c          1 2020-05-13 07:50:06 2020-05-13 08:32:06
    

    reprex package (v0.3.0) 于 2020 年 6 月 25 日创建

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-15
      • 1970-01-01
      • 2020-10-26
      • 2015-03-07
      • 2018-08-15
      • 2023-02-08
      • 1970-01-01
      • 2022-01-26
      相关资源
      最近更新 更多