代码之家  ›  专栏  ›  技术社区  ›  Wimpel

合并/合并重叠时间范围[重复]

  •  1
  • Wimpel  · 技术社区  · 6 年前

    这个问题已经有了答案:

    我知道以下问题可以用生物导体的iranges包解决,使用 reduce . 但是,由于该函数只接受数字输入,而且我正在处理data.table,所以我想知道下面的van是否是使用data.tables实现的。 foverlaps() .

    样本数据

        structure(list(group = c("A", "A", "A", "A", "B", "B", "B", "B"
    ), subgroup = c(1, 1, 2, 2, 1, 1, 2, 2), start = structure(c(1514793600, 
    1514795400, 1514794200, 1514798100, 1514815200, 1514817000, 1514815800, 
    1514818800), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
        end = structure(c(1514794500, 1514797200, 1514794800, 1514799000, 
        1514816100, 1514818800, 1514817600, 1514820600), class = c("POSIXct", 
        "POSIXt"), tzone = "UTC")), row.names = c(NA, -8L), class = c("tbl_df", 
    "tbl", "data.frame"))
    
    #    group subgroup               start                 end
    # 1:     A        1 2018-01-01 08:00:00 2018-01-01 08:15:00
    # 2:     A        1 2018-01-01 08:30:00 2018-01-01 09:00:00
    # 3:     A        2 2018-01-01 08:10:00 2018-01-01 08:20:00
    # 4:     A        2 2018-01-01 09:15:00 2018-01-01 09:30:00
    # 5:     B        1 2018-01-01 14:00:00 2018-01-01 14:15:00
    # 6:     B        1 2018-01-01 14:30:00 2018-01-01 15:00:00
    # 7:     B        2 2018-01-01 14:10:00 2018-01-01 14:40:00
    # 8:     B        2 2018-01-01 15:00:00 2018-01-01 15:30:00
    

    问题

    我希望在以下情况下(按组)加入/合并事件:

    1. 一个范围(开始-结束)与另一个范围重叠(或部分重叠)
    2. 范围的开始是另一个范围的结束

    可以忽略子组

    如前所述,我知道这可以通过使用生物传感器来完成。 减少 但我想知道使用data.table是否可以实现相同的结果。我不能动摇那种感觉 foverlaps 应该能够解决我的问题,但我不知道如何…

    因为我是一个中间的R用户,但在data.table中几乎是个新手,所以我很难“阅读”stackoverflow上已经提供的一些解决方案。所以我不确定是否有人问过类似的问题并回答过(如果有,请温柔一点;-)

    期望输出

    structure(list(group = c("A", "A", "A", "B"), start = structure(c(1514793600, 
    1514795400, 1514798100, 1514815200), class = c("POSIXct", "POSIXt"
    ), tzone = "UTC"), end = structure(c(1514794800, 1514797200, 
    1514799000, 1514820600), class = c("POSIXct", "POSIXt"), tzone = "UTC")), row.names = c(NA, 
    -4L), class = c("tbl_df", "tbl", "data.frame"))
    
    #    group               start                 end
    # 1:     A 2018-01-01 08:00:00 2018-01-01 08:20:00
    # 2:     A 2018-01-01 08:30:00 2018-01-01 09:00:00
    # 3:     A 2018-01-01 09:15:00 2018-01-01 09:30:00
    # 4:     B 2018-01-01 14:00:00 2018-01-01 15:30:00
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Lennyy    6 年前

    如果您按组排列并开始(按此顺序)并取消选择INDX列,那么由David Arenburg发布的此解决方案将非常有效: How to flatten/merge overlapping time periods in R

    library(dplyr)
    
    df1 %>% 
    group_by(group) %>%
      arrange(group, start) %>% 
      mutate(indx = c(0, cumsum(as.numeric(lead(start)) >
                                  cummax(as.numeric(end)))[-n()])) %>%
      group_by(group, indx) %>%
      summarise(start = first(start), end = last(end)) %>% 
      select(-indx)
    
     group start               end                
      <chr> <dttm>              <dttm>             
    1 A     2018-01-01 08:00:00 2018-01-01 08:20:00
    2 A     2018-01-01 08:30:00 2018-01-01 09:00:00
    3 A     2018-01-01 09:15:00 2018-01-01 09:30:00
    4 B     2018-01-01 14:00:00 2018-01-01 15:30:00