You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于起止日期补全不重叠的缺失日期范围(R语言)

补全不重叠的日期范围(基于指定上下限)

需要基于给定的起始边界(2000-01-01)和结束边界(2001-07-31)补全现有数据集中的缺失日期区间,且所有最终的日期区间必须互不重叠。

现有数据集

have <- data.frame(ID = c(1, 1),
                 date1 = as.Date(c("2000-01-29", "2000-07-16")),
                 date2 = as.Date(c("2000-07-15", "2001-04-30")))

# 输出
#   ID      date1      date2
# 1  1 2000-01-29 2000-07-15
# 2  1 2000-07-16 2001-04-30

期望结果

want <- data.frame(ID = c(1, 1, 1, 1),
                 date1 = as.Date(c("2000-01-01", "2000-01-29", "2000-07-16", "2001-05-01")),
                 date2 = as.Date(c("2000-01-28", "2000-07-15", "2001-04-30", "2001-07-31")))

# 输出
#   ID      date1      date2
# 1  1 2000-01-01 2000-01-28
# 2  1 2000-01-29 2000-07-15
# 3  1 2000-07-16 2001-04-30
# 4  1 2001-05-01 2001-07-31

原方案的问题

原方案生成的区间存在日期重叠(如2000-07-15同时作为前一个区间的date2和后一个补全区间的date1),导致区间边界重复:

library(dplyr)
start <- as.Date("2000-01-01"); end <- as.Date("2001-07-31")

ex <- have %>%
  group_by(ID) %>%
  summarize(newdate1 = c(start, date2), newdate2 = c(date1, end)) %>%
  rename(date1 = newdate1, date2 = newdate2) %>%
  filter(date2 > date1) %>%
  ungroup() %>%
  bind_rows(have) %>%
  arrange(ID, date1)

# 输出
# # A tibble: 5 × 3
#      ID date1      date2     
#   <dbl> <date>     <date>    
# 1     1 2000-01-01 2000-01-29
# 2     1 2000-01-29 2000-07-15
# 3     1 2000-07-15 2000-07-16
# 4     1 2000-07-16 2001-04-30
# 5     1 2001-04-30 2001-07-31

修正方案

核心是调整补全区间的边界,避免与原有区间重叠:

  • 补全现有区间之前的缺失部分时,将现有区间的date1减1天作为补全区间的date2
  • 补全现有区间之间/之后的缺失部分时,将前一个区间的date2加1天作为补全区间的date1

修正后的代码:

library(dplyr)
start <- as.Date("2000-01-01"); end <- as.Date("2001-07-31")

corrected <- have %>%
  group_by(ID) %>%
  # 生成补全区间:调整边界避免重叠
  summarize(
    newdate1 = c(start, date2 + 1),
    newdate2 = c(date1 - 1, end)
  ) %>%
  rename(date1 = newdate1, date2 = newdate2) %>%
  # 过滤无效区间(日期顺序颠倒的情况)
  filter(date2 >= date1) %>%
  # 合并原数据并按日期排序
  bind_rows(have) %>%
  arrange(ID, date1) %>%
  ungroup()

# 查看结果
corrected
# 输出
# # A tibble: 4 × 3
#      ID date1      date2     
#   <dbl> <date>     <date>    
# 1     1 2000-01-01 2000-01-28
# 2     1 2000-01-29 2000-07-15
# 3     1 2000-07-16 2001-04-30
# 4     1 2001-05-01 2001-07-31

这个结果完全匹配期望的want数据集,所有区间边界互不重叠,且完整覆盖了从start到end的整个时间范围。


内容的提问来源于stack exchange,提问作者TJ87

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 05:13:16