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

如何基于个体ID创建并统计连续数值序列时段(适配日期)

合并连续时段数据集的解决方案

问题描述

现有包含个体ID(enrolid)、起始数值(start)、结束数值(end)的数据集,需要生成个体-时段级别的连续时段数据集。连续时段定义为:当前行的start ≤ 上一行的end + 1,满足该条件的行需合并为一个连续时段,取合并组内最小的start和最大的end作为新时段的起止值,并为每个个体的连续时段生成序号。

现有数据:

have <- tibble(
  enrolid = c(1,1,1,1,2,2,2,2),
  start = c(0,11,19,24,2,14,17,37),
  end  = c(10,15,25,29,13,16,35,49)
)

期望结果:

want <- tibble(
  enrolid = c(1,1,2,2),
  continuous_cov_start = c(0,19,2,37),
  continuous_cov_end = c(15,29,35,49),
  continuous_cov_sequence = c(1,2,1,2)
)

注:当前使用数值类型的start和end,后续需适配为日期类型,目标是生成唯一的连续保险覆盖时段数据集。

解决方案(使用tidyverse工具链)

用dplyr的分组、窗口函数即可实现,无需循环,代码简洁且适配后续日期类型需求:

library(dplyr)

want <- have %>%
  # 按个体ID分组,确保每个个体的时段按start排序(核心前提,避免顺序错乱)
  group_by(enrolid) %>%
  arrange(start, .by_group = TRUE) %>%
  # 标记新时段:当前行start超过上一行end+1时,视为新时段起点
  mutate(new_period = if_else(start > lag(end, default = -Inf) + 1, 1, 0)) %>%
  # 累加标记值,生成每个个体内的连续时段分组ID
  mutate(continuous_cov_sequence = cumsum(new_period) + 1) %>%
  # 按个体ID和时段ID聚合,取组内最小start和最大end
  group_by(enrolid, continuous_cov_sequence) %>%
  summarise(
    continuous_cov_start = min(start),
    continuous_cov_end = max(end),
    .groups = "drop"
  )

代码解释

  1. 分组排序:先按enrolid分组,再按start排序,确保每个个体的时段按数值/时间顺序排列,这是合并连续时段的基础。
  2. 标记新时段:用lag()获取上一行的end值,判断当前行start是否超出上一行end+1,是则标记为新时段(new_period=1)。default=-Inf是为了处理每个个体的第一行,确保第一行被识别为新时段起点。
  3. 生成时段序号:对new_period做累加(cumsum)后加1,得到每个个体内的连续时段序号。
  4. 聚合合并:按enrolid和时段序号分组,取组内最小start作为连续时段起始,最大end作为结束。

适配日期类型的说明

如果后续将start和end改为日期类型(如Date或POSIXct),只需确保日期格式正确,上述代码无需修改——dplyr的比较运算符、lag()、min()/max()对日期类型同样适用。示例:

# 模拟日期类型数据
have_date <- tibble(
  enrolid = c(1,1),
  start = as.Date(c("2020-01-01", "2020-01-11")),
  end = as.Date(c("2020-01-10", "2020-01-15"))
)

# 用相同代码处理
have_date %>%
  group_by(enrolid) %>%
  arrange(start, .by_group = TRUE) %>%
  mutate(new_period = if_else(start > lag(end, default = as.Date("1900-01-01")) + 1, 1, 0)) %>%
  mutate(continuous_cov_sequence = cumsum(new_period) + 1) %>%
  group_by(enrolid, continuous_cov_sequence) %>%
  summarise(
    continuous_cov_start = min(start),
    continuous_cov_end = max(end),
    .groups = "drop"
  )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 12:15:26