【问题标题】:Given date ranges and corresponding IDs, find groups of IDs with overlapping dates给定日期范围和相应的 ID,查找具有重叠日期的 ID 组
【发布时间】:2020-03-30 23:40:37
【问题描述】:

我有一个包含 dateRanges 和相应 ID 的表。我想根据它们的开始/结束范围是否与另一个 ID 的日期范围重叠来对 ID 进行分组。如果某个 ID 的日期范围部分或完全在另一个 ID 的日期范围内,则它们应属于同一组。我想在组内最小和最大日期给出的开始/结束日期旁边添加一个指示此分组的列。

数据:

"ID"    "start" "end"
1   2018-10-02  2019-01-15
2   2019-01-13  2019-02-01
3   2018-10-01  2018-11-01
4   2018-10-05  2018-10-06
5   2019-09-09  2019-10-08
6   2019-02-06  2019-04-07
7   2019-03-24  2019-04-17
8   2019-03-21  2019-04-14
9   2019-03-27  2019-04-16
10  2019-04-30  2019-05-08

理想的结果:

"ID"    "start" "end"   "group_ID"  "group_start"   "group_end"
1   2018-10-02  2019-01-15  1   2018-10-01  2019-02-01
2   2019-01-13  2019-02-01  1   2018-10-01  2019-02-01
3   2018-10-01  2018-11-01  1   2018-10-01  2019-02-01
4   2018-10-05  2018-10-06  1   2018-10-01  2019-02-01
5   2019-09-09  2019-10-08  2   2019-09-09  2019-10-08
6   2019-02-06  2019-04-07  3   2019-02-06  2019-05-08
7   2019-03-24  2019-04-17  3   2019-02-06  2019-05-08
8   2019-03-21  2019-04-14  3   2019-02-06  2019-05-08
9   2019-03-27  2019-04-16  3   2019-02-06  2019-05-08
10  2019-04-30  2019-05-08  3   2019-02-06  2019-05-08

我一直认为这可能有效的是创建一个 ID 矩阵(即,从 ID 1 到 ID 10 的行和列)并填充每个单元格,以确定给定 ID 交集的日期范围是否重叠。在此之后,分箱然后分组并找到给定组的最小值/最大值,但这似乎真的很复杂。必须有一个更简单的解决方案,不涉及查看矩阵上的边缘来创建集群。

.csv 的编辑格式:

ID,start,end
1,2018-10-02,2019-01-15
2,2019-01-13,2019-02-01
3,2018-10-01,2018-11-01
4,2018-10-05,2018-10-06
5,2019-09-09,2019-10-08
6,2019-02-06,2019-04-07
7,2019-03-24,2019-04-17
8,2019-03-21,2019-04-14
9,2019-03-27,2019-04-16
10,2019-04-30,2019-05-08

【问题讨论】:

  • 如果之前的日期是 2018 年并且当前行是 2019 年,那么如何创建第 2 组?没有重叠的匹配。第 3 组也一样。你能解释一下重叠的确切位置吗?
  • 如果两个或多个 ID 的日期范围重叠,则它们应位于同一组中。由于第 2 组的开始和结束不属于第 1 组和第 3 组的任何区间,因此它在自己的组中。
  • 对于ID6,与组3的其他成员没有重叠,所以你应该得到4组而不是3?另外,您能否为您的初始数据框和预期数据框提供可重现的示例?这将使试图提供帮助的人更容易。检查此链接以了解如何操作:stackoverflow.com/questions/5963269/…
  • 那是我的错误,刚刚更新它!
  • 请提供可重现的示例 (stackoverflow.com/questions/5963269/…)。因为它是我们可以轻松地将其复制粘贴到 R 中并尝试解决您的问题。可以添加dput(df[1:10,])的输出

标签: r datetime overlap overlapping-matches


【解决方案1】:

这是一个选项:

setorder(DT, start, end)
DT[order(start, end), g := cumsum(start > shift(cummax(as.integer(end)), fill=0L))][,
    c("gstart","gend") := .(min(start), max(end)), g]    

输出:

    ID      start        end g     gstart       gend
 1:  1 2018-10-02 2019-01-15 1 2018-10-01 2019-02-01
 2:  2 2019-01-13 2019-02-01 1 2018-10-01 2019-02-01
 3:  3 2018-10-01 2018-11-01 1 2018-10-01 2019-02-01
 4:  4 2018-10-05 2018-10-06 1 2018-10-01 2019-02-01
 5:  5 2019-09-09 2019-10-08 4 2019-09-09 2019-10-08
 6:  6 2019-02-06 2019-04-07 2 2019-02-06 2019-04-17
 7:  7 2019-03-24 2019-04-17 2 2019-02-06 2019-04-17
 8:  8 2019-03-21 2019-04-14 2 2019-02-06 2019-04-17
 9:  9 2019-03-27 2019-04-16 2 2019-02-06 2019-04-17
10: 10 2019-04-30 2019-05-08 3 2019-04-30 2019-05-08

数据:

library(data.table)
DT <- fread("ID,start,end
1,2018-10-02,2019-01-15
2,2019-01-13,2019-02-01
3,2018-10-01,2018-11-01
4,2018-10-05,2018-10-06
5,2019-09-09,2019-10-08
6,2019-02-06,2019-04-07
7,2019-03-24,2019-04-17
8,2019-03-21,2019-04-14
9,2019-03-27,2019-04-16
10,2019-04-30,2019-05-08")
cols <- c("start", "end")
DT[, (cols) := lapply(.SD, as.IDate, format="%Y-%m-%d"), .SDcols=cols]

参考: How to flatten / merge overlapping time periods

【讨论】:

    猜你喜欢
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    • 1970-01-01
    • 1970-01-01
    • 2014-01-31
    相关资源
    最近更新 更多