合并/合并重叠的时间范围

时间:2018-06-27 11:31:10

标签: r data.table

我知道可以使用reduce使用Bioconductor的IRanges软件包解决以下问题。 但是由于该函数仅接受数字输入,并且无论如何我都在使用data.table,所以我想知道使用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. 一个范围的开始是另一个范围的结束

子组可以忽略

如上所述,我知道可以使用biocondustor的IRanges reduce完成此操作,但是我想知道是否可以使用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 个答案:

答案 0 :(得分:1)

如果您安排分组并以该顺序开始,并且未选择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