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

R中无需循环为数据框添加同一患者30天内Inpatient事件求和列

当然有啦!在R里处理这种「同一患者过去30天内事件统计」的需求,完全不用写繁琐的for循环,用矢量化的工具包就能高效搞定。下面给你两种常用的实现方式,适配不同的使用习惯:

方法一:用dplyr + slider(适合tidyverse用户)

这个组合语法直观,容易理解,尤其适合已经熟悉tidyverse工作流的同学。核心是用slider包的滑动窗口函数,基于日期索引精准计算过去30天的总和。

首先确保你的数据按「患者ID」和「事件日期」排序,然后分组计算:

library(dplyr)
library(slider)

# 假设你的数据框结构如下(可替换成你的真实数据)
df <- tibble(
  patient_id = c(1, 1, 1, 2, 2),
  event_date = as.Date(c("2023-01-01", "2023-01-15", "2023-02-05", "2023-03-01", "2023-03-25")),
  # 先把Inpatient事件转成0/1数值(如果原数据是字符型的话)
  is_inpatient = ifelse(event_type == "Inpatient", 1, 0)
)

# 核心处理步骤
df_processed <- df %>%
  arrange(patient_id, event_date) %>%  # 按患者+日期排序,确保窗口顺序正确
  group_by(patient_id) %>%             # 按患者分组
  mutate(
    past_30d_inpatient_sum = slide_index_sum(
      .x = is_inpatient,               # 要求和的变量
      .i = event_date,                 # 作为索引的日期列
      .before = days(30),              # 窗口范围:当前日期往前30天
      .complete = FALSE                # 即使窗口不满30天也计算(如需满30天则设为TRUE)
    )
  ) %>%
  ungroup()

关键说明:

  • slide_index_sum会自动针对每个患者,以event_date为基准,只统计过去30天内的事件,完全不用手动循环;
  • 如果你的「Inpatient」事件是分类变量(比如"住院"/"非住院"),记得先转成0/1的数值型,这样才能求和。

方法二:用data.table(适合大数据场景)

如果你的数据量很大(比如几十万甚至上百万行),data.table的速度优势会非常明显。这里推荐用非等自连接的方式,精准匹配每个行对应的30天窗口:

library(data.table)

# 转换为data.table格式
setDT(df)

# 先按患者ID和日期排序
setorder(df, patient_id, event_date)

# 非等连接计算过去30天内的住院事件总和
df[, past_30d_inpatient_sum := df[df, 
                                  sum(is_inpatient), 
                                  on = .(
                                    patient_id, 
                                    event_date >= event_date - days(30),  # 窗口起始:当前日期-30天
                                    event_date <= event_date             # 窗口结束:当前日期
                                  ),
                                  by = .EACHI]$V1]

关键说明:

  • 非等连接的方式逻辑非常直接:对每一行,找到同一个患者、且事件日期在「当前日期-30天」到「当前日期」之间的所有行,然后求和is_inpatient;
  • 这种方法的计算效率极高,处理大数据时比dplyr组合快很多。

重要注意事项

  • 确保event_date是Date类型:如果原数据是字符型,记得用as.Date(event_date)转换;
  • 必须先排序:不管用哪种方法,都要先按患者ID和事件日期排序,否则窗口计算会出错;
  • 窗口范围的调整:如果不想包含当前日期的事件,可以把event_date <= event_date改成event_date < event_date。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:12:59