[英]Given date ranges and corresponding IDs, find groups of IDs with overlapping dates
我有一个带有 dateRanges 和相应 ID 的表。 我想根据 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
这是一个选项:
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]
参考: 如何展平/合并重叠的时间段
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.