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

在R中按列值条件合并行:合并间隔不足1小时的用药记录

我来帮你搞定这个合并连续用药记录的需求!你的核心思路是对的,但现有代码里的循环逻辑和dplyr的使用方式有问题,咱们用tidyverse的工具来更优雅地解决这个问题,完全不需要复杂的循环。

解决方案代码
library(tidyverse)
library(lubridate)

merge_pressor_doses <- function(df) {
  df %>%
    # 先按患者ID和起始时间排序,确保记录是按时间顺序排列的
    arrange(icustay_id, starttime) %>%
    group_by(icustay_id) %>%
    # 计算当前记录的starttime与上一条记录的endtime的时间差(转换为分钟)
    # 第一条记录没有上一条,所以时间差设为NA
    mutate(interval = as.duration(starttime - lag(endtime)) / dminutes(1)) %>%
    # 创建分组标识:当间隔>=60分钟(或第一条记录)时,新建一个组
    mutate(group_id = cumsum(is.na(interval) | interval >= 60)) %>%
    # 按患者ID和分组标识聚合,应用合并规则
    group_by(icustay_id, group_id) %>%
    summarise(
      starttime = min(starttime),
      endtime = max(endtime),
      vaso_rate = mean(vaso_rate),
      vaso_amount = sum(vaso_amount),
      .groups = "drop" # 取消分组,返回普通数据框
    ) %>%
    # 移除临时的group_id列,保持输出整洁
    select(-group_id)
}

# 测试函数
merged_df <- merge_pressor_doses(df)
print(merged_df)
代码逻辑拆解

咱们一步步捋清楚这个实现:

  1. 排序:先用arrange确保每个患者的记录按时间先后排列,这是后续计算间隔的基础,否则间隔判断会出错。
  2. 计算时间间隔:用lag(endtime)获取当前记录的上一条记录的结束时间,再计算两条记录的时间差并转换为分钟数。第一条记录没有上一条,所以lag(endtime)返回NA,对应的interval也是NA。
  3. 生成分组标识:用cumsum来创建分组ID——每当遇到间隔≥60分钟的情况(或者是第一条记录),就累加1,这样连续的、间隔不足1小时的记录会被分到同一个组里。
  4. 聚合计算:按患者ID和分组ID分组后,严格按照你的需求聚合:取最早的starttime、最晚的endtime,vaso_rate取平均值,vaso_amount求和。
  5. 清理输出:最后移除临时的group_id列,让输出格式和你期望的一致。
测试结果

运行代码后,你会得到符合预期的输出:

icustay_id starttime           endtime             vaso_rate vaso_amount
       <dbl> <dttm>              <dttm>                  <dbl>       <dbl>
1          1 2019-09-10 13:20:00 2019-09-12 01:20:00         6        896.
2          1 2019-09-14 16:40:00 2019-09-15 16:40:00         4        209.
3          2 2019-09-10 12:40:00 2019-09-13 13:20:00         2        864.
4          3 2019-09-10 01:20:00 2019-09-11 13:20:00         9        405.

(注:icustay_id=1的前两条记录合并后,vaso_rate是(3+9)/2=6,vaso_amount是293+603≈896,这是符合合并规则的正确结果)

原有代码的问题说明

简单说几个关键问题:

  • 执行df %>% arrange(...)后没有把结果赋值回df,导致排序操作根本没生效
  • 循环里的which(df$icustay_id==i) && j < max(...)逻辑错误,不能将索引向量和布尔值直接混合使用
  • 使用mutate时没有保存结果,且df$starttime[j+1]这种写法不符合dplyr的向量式操作逻辑
  • 最后return(df)返回的是原数据框,不是聚合后的结果

用tidyverse的窗口函数(比如lag、cumsum)处理这种连续分组的问题,比循环高效得多,也更易读和维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:18:10