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

R语言按patient_id分组筛选24小时内两类不同就诊记录的方法

高效实现方案

核心思路是使用分组窗口函数替代join操作,避免同组内所有记录两两匹配的O(n²)复杂度,仅需对分组内排序后的记录做一次线性扫描,时间复杂度为O(n),大数据量下性能提升非常明显。

Tidyverse 实现版本

library(tidyverse)

df <- df %>%
  # 先按患者和就诊日期排序
  arrange(patient_id, date_visit) %>%
  group_by(patient_id) %>%
  mutate(
    # 计算当前行与上一行、下一行的就诊时间差(单位:天)
    lag_diff = as.numeric(date_visit - lag(date_visit), units = "days"),
    lead_diff = as.numeric(lead(date_visit) - date_visit, units = "days"),
    # 判断上下行的就诊类型是否和当前行不同
    lag_type_diff = type_of_visit != lag(type_of_visit),
    lead_type_diff = type_of_visit != lead(type_of_visit),
    # 满足任意一种情况即标记为符合条件:和上一行间隔<=1天且类型不同 / 和下一行间隔<=1天且类型不同
    is_qualified = (lag_diff <= 1 & lag_type_diff) | (lead_diff <= 1 & lead_type_diff),
    # 首尾行的空值替换为FALSE
    is_qualified = replace_na(is_qualified, FALSE)
  ) %>%
  ungroup() %>%
  # 可选:删除中间辅助列
  select(-lag_diff, -lead_diff, -lag_type_diff, -lead_type_diff)

# 如果需要仅保留符合条件的行,追加以下代码
df_filtered <- df %>% filter(is_qualified)

超大数据量可选 Data.table 版本

如果数据量在百万级以上,用data.table实现速度会更快:

library(data.table)
# 转换为data.table格式并排序
setDT(df)
setorder(df, patient_id, date_visit)

# 分组计算标记列
df[, `:=`(
  lag_diff = as.numeric(date_visit - shift(date_visit), units = "days"),
  lead_diff = as.numeric(shift(date_visit, type = "lead") - date_visit, units = "days"),
  lag_type_diff = type_of_visit != shift(type_of_visit),
  lead_type_diff = type_of_visit != shift(type_of_visit, type = "lead")
), by = patient_id]

df[, is_qualified := fcoalesce((lag_diff <= 1 & lag_type_diff) | (lead_diff <= 1 & lead_type_diff), FALSE)]

# 可选:删除辅助列
df[, c("lag_diff", "lead_diff", "lag_type_diff", "lead_type_diff") := NULL]

# 可选:筛选符合条件的行
df_filtered <- df[is_qualified == TRUE]

性能说明

原来的left join方案会将同一个患者的所有记录做笛卡尔积匹配,若单个患者有N条就诊记录就会生成N²条关联结果,数据量大时内存和时间消耗都会急剧升高。窗口函数方案仅需要对排序后的分组数据做一次遍历,无论单患者就诊记录多少,都只做线性次数的运算,性能远高于join方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 11:27:00