【问题标题】:R - Condensing rows based on continuity of start and end timestampsR - 基于开始和结束时间戳的连续性压缩行
【发布时间】:2020-08-29 00:52:53
【问题描述】:

我有一些带有时间戳的 ID 表现出我无法控制的行为。这会导致相同 ID 的新行,但给定 ID 的第一行的 end_time 与同一 ID 的下一行的 start_time 匹配。一个示例如下所示:

df <- data.frame(id = c("1", "1", "1", "2", "3", "3"),
                 start_time = c("7/4/2020 10:06:27", "7/16/2020 07:16:44", "7/16/2020 07:20:32", "7/9/2020 03:27:37", "7/4/2020 02:01:49", "7/9/2020 00:00:00"),
                 end_time = c("7/16/2020 07:16:44", "7/16/2020 07:20:32", "7/25/2020 18:17:46", "7/21/2020 20:13:16", "7/5/2020 09:17:54", "7/11/2020 15:43:22"))
> df
id         start_time           end_time
1  1  7/4/2020 10:06:27 7/16/2020 07:16:44
2  1 7/16/2020 07:16:44 7/16/2020 07:20:32
3  1 7/16/2020 07:20:32 7/25/2020 18:17:46
4  2  7/9/2020 03:27:37 7/21/2020 20:13:16
5  3  7/4/2020 02:01:49  7/5/2020 09:17:54
6  3  7/9/2020 00:00:00 7/11/2020 15:43:22

但我想将 id = 1 的时间戳(以及其他可能表现出这种行为的行)“缝合”在一起,形成一个不同的行,如下所示。请注意此 id 的 end_time 和 start_time 条目是如何匹配的。

> df
  id        start_time           end_time
1  1 7/4/2020 10:06:27 7/25/2020 18:17:46
2  2 7/9/2020 03:27:37 7/21/2020 20:13:16
3  3 7/4/2020 02:01:49  7/5/2020 09:17:54
4  3 7/9/2020 00:00:00 7/11/2020 15:43:22

id = 3 的条目是合适的,因为第一个实例的 end_time 是从第二个实例的开始时间开始的实例,因此期望的行为是这些行保持不变

【问题讨论】:

    标签: r dataframe timestamp


    【解决方案1】:

    这是一个 dplyr 解决方案:

    library(dplyr)
    df %>%
      mutate_at(vars(start_time, end_time), ~ as.POSIXct(., format = "%m/%d/%Y %T")) %>%
      arrange(id, start_time) %>%
      group_by(id) %>%
      mutate(grp = cumsum(start_time != dplyr::lag(end_time, default=end_time[1]))) %>%
      group_by(id, grp) %>%
      summarize(start_time = start_time[1], end_time = end_time[n()]) %>%
      ungroup() %>%
      select(-grp)
    # # A tibble: 4 x 3
    #   id    start_time          end_time           
    #   <chr> <dttm>              <dttm>             
    # 1 1     2020-07-04 10:06:27 2020-07-25 18:17:46
    # 2 2     2020-07-09 03:27:37 2020-07-21 20:13:16
    # 3 3     2020-07-04 02:01:49 2020-07-05 09:17:54
    # 4 3     2020-07-09 00:00:00 2020-07-11 15:43:22
    

    编辑添加as.POSIXct。一条评论是确保按start_time 排序以确保比较是好的,但要意识到由于这些最初是字符串,因此不能保证它们会正确排序。例如,sort(c("7/31/2020", "12/01/2020")) 排序不正确。鉴于这些数据不太可能,但仍然是一个很好的保护措施。

    【讨论】:

    • 我正在做一些非常相似的事情 :) 我喜欢使用 first(x)last(x) 而不是 x[1]x[n()] 但它的工作原理是一样的。
    • 我一直试图说服自己,first(x) 相对于x[1] 的可读性值得它引入的微不足道的开销。我开始使用 first 的最大原因是,就像 seq_len 一样,当给定长度为 0 的向量时,它会直观地做出反应(而不是在框架中)。谢谢。
    • @r2evans 太棒了,谢谢!事后我意识到我必须做的一个小调整是添加一个arrange(start_time) %&gt;%,因为有些数据很奇怪,而且行并不总是像我给出的示例那样流动。
    • 是的,这是一个很好的预防措施,我会添加它,谢谢你的建议。但是,由于这些不是正确的日期,因此只有在所有月份/年份相同时才会“安全”。
    猜你喜欢
    • 2016-10-31
    • 2021-12-20
    • 1970-01-01
    • 2011-01-23
    • 2021-01-26
    • 2020-02-24
    • 2012-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多