我在 R 中有一个 data.table,在这个 data.table 中有一些日期范围(从日期到日期),数据可以通过 id 分组在一起。对于每个 id,我想合并重叠的日期范围,最终得到每个 id 不重叠的唯一日期范围
例如这是我的数据的一个非常简化的版本
input <- data.table(
id = c(rep(1, 4), rep(2, 3), rep(3, 2)),
from_date = c('2000-01-01', '2001-01-01', '2002-01-01', '2003-01-01',
'2000-01-01', '2001-01-01', '2002-01-01',
'2000-01-01', '2001-01-01'),
to_date = c('2000-06-01', '2003-06-01', '2002-06-01', '2003-10-01',
'2001-05-01', '2001-02-01', '2002-06-01',
'2000-06-01', '2002-06-01')
)
> input
id from_date to_date
1: 1 2000-01-01 2000-06-01
2: 1 2001-01-01 2003-06-01
3: 1 2002-01-01 2002-06-01
4: 1 2003-01-01 2003-10-01
5: 2 2000-01-01 2001-05-01
6: 2 2001-01-01 2001-02-01
7: 2 2002-01-01 2002-06-01
8: 3 2000-01-01 2000-06-01
9: 3 2001-01-01 2002-06-01
对于 id 1,第二个、第三个和第四个日期范围重叠,因此我需要将它们全部合并为一个,从和到日期反映范围内的最小/最大日期。对于 id 2,第二个和第三个日期范围重叠(实际上,第二个日期范围完全包含第三个日期范围),因此再次需要合并这些日期范围。对于第三个 id,它们不重叠,所以可以保持不变
所以对于以上,我想结束
> output
id from_date to_date
1: 1 2000-01-01 2000-06-01
2: 1 2001-01-01 2003-10-01
3: 2 2000-01-01 2001-05-01
4: 2 2002-01-01 2002-06-01
5: 3 2000-01-01 2000-06-01
6: 3 2001-01-01 2002-06-01
实际上 data.table 更大(1,000,000 行,100,000 组)并且包含其他数据以及 id 和日期范围,因此重要的是任何解决方案都具有合理的性能和速度,最好使用数据。例如,table 而不是 dplyr,因为其余代码使用 data.tables.
提前致谢
我知道更简单的方法是使用
ivs
包,但我不确定它是否可以很好地扩展。您可以使用 iv_start
和 iv_end
以原始格式获取数据。
library(dplyr)
library(ivs)
input %>%
reframe(range = iv_groups(iv(from_date, to_date)), .by = id)
# id range
# 1 1 [2000-01-01, 2000-06-01)
# 2 1 [2001-01-01, 2003-10-01)
# 3 2 [2000-01-01, 2001-05-01)
# 4 2 [2002-01-01, 2002-06-01)
# 5 3 [2000-01-01, 2000-06-01)
# 6 3 [2001-01-01, 2002-06-01)