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

在R中基于用药天数生成患者覆盖天数指标(tidyverse优先)

解决方案(基于tidyverse)

针对你的需求,我们可以通过宽长格式转换+日期序列生成+分组聚合的思路实现,同时兼顾60万+患者的大数据量效率:

1. 加载依赖包

library(tidyverse)
library(lubridate)

2. 原始数据宽转长

先把日期列转为长格式,方便逐个处理每个日期的用药剂量:

df_long <- df %>%
  pivot_longer(
    cols = starts_with("2023"),  # 匹配所有日期列
    names_to = "date",
    values_to = "dose"
  ) %>%
  mutate(date = ymd(date))  # 转为标准日期格式

3. 生成药物覆盖日期序列

对每个非0剂量,生成「当日+后续N-1天」的覆盖日期,同时截断到数据的最大日期(避免超出时间范围):

max_date <- max(df_long$date)  # 提前提取全局最大日期,提升效率

df_coverage <- df_long %>%
  filter(dose > 0) %>%
  mutate(
    end_date = pmin(date + days(dose - 1), max_date),  # 截断结束日期
    coverage_date = map2(date, end_date, ~seq(.x, .y, by = "day"))  # 生成日期序列
  ) %>%
  unnest(coverage_date) %>%
  select(pat, drug, coverage_date) %>%
  mutate(covered = 1)

4. 转回宽格式得到药物级覆盖(df2)

将长格式的覆盖数据转回宽格式,补全缺失的日期列并填充0:

df2 <- df_coverage %>%
  pivot_wider(
    id_cols = c(pat, drug),
    names_from = coverage_date,
    values_from = covered,
    values_fill = 0
  ) %>%
  right_join(df %>% select(pat, drug), by = c("pat", "drug")) %>%  # 补全所有pat-drug组合
  mutate(across(starts_with("2023"), ~replace_na(.x, 0))) %>%
  arrange(pat, drug)

5. 聚合得到患者级覆盖(df3)

按患者分组,每个日期只要有任意一种药物覆盖,就标记为1:

df3 <- df2 %>%
  group_by(pat) %>%
  summarise(across(starts_with("2023"), ~max(.x)), .groups = "drop")

6. 计算覆盖天数占比

df3_with_ratio <- df3 %>%
  rowwise() %>%
  mutate(
    total_days = ncol(.) - 1,  # 排除pat列的总天数
    covered_days = sum(c_across(starts_with("2023"))),
    coverage_ratio = round(covered_days / total_days, 4)  # 保留4位小数
  ) %>%
  ungroup()

大数据量优化建议

  • 提前提取全局变量(如max_date),避免重复计算
  • 若内存压力大,可使用dplyr::group_split()按患者分块处理,再合并结果
  • 对于超大规模数据,可结合arrow包处理磁盘上的大数据框,减少内存占用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 13:30:29