【问题标题】:Merging rows in R while adding conditions according to column values在根据列值添加条件的同时合并R中的行
【发布时间】:2026-02-02 23:30:01
【问题描述】:

我正在使用以下数据集: 图书馆(tidyverse) 图书馆(润滑)

df <- data.frame(
  icustay_id = c(1, 1, 1, 2, 3),
  starttime = as.POSIXct(c("2019-09-10 13:20", "2019-09-11 13:30",  "2019-09-14 16:40", "2019-09-10 12:40", "2019-09-10 01:20")),
  endtime = as.POSIXct(c("2019-09-10 13:20", "2019-09-12 01:20", "2019-09-15 16:40", "2019-09-13 13:20", "2019-09-11 13:20")),
  vaso_rate = sample(1:10, 5, replace = TRUE),
  vaso_amount = runif(5, 0, 1000)
)

df
#       icustay_id           starttime             endtime vaso_rate vaso_amount
# 1          1 2019-09-10 13:20:00 2019-09-11 13:20:00         3    293.0896
# 2          1 2019-09-11 13:30:00 2019-09-12 01:20:00         9    602.9983
# 3          1 2019-09-14 16:40:00 2019-09-15 16:40:00         4    208.9360
# 4          2 2019-09-10 12:40:00 2019-09-13 13:20:00         2    864.1494
# 5          3 2019-09-10 01:20:00 2019-09-11 13:20:00         9    405.2939

基本上,这显示了 POSIXCT 中不同患者接受药物的开始时间和结束时间。


我正在尝试构建一个函数:

  1. 对于每个唯一的患者(每个唯一的 icusstay_id),合并停止服药不到一小时的行。
  2. 当行合并时: 某些列将保留相同的值(即患者标识符) 必须修改某些列:
  3. 保持较早的开始时间
  4. 保留后一个 endttime
  5. 平均血管速率
  6. 总血管量
  7. 删除持续时间

我在第二部分苦苦挣扎,我似乎找不到解决这种有条件“合并”的最佳方法。

要获得类似的东西:

df
#       icustay_id           starttime             endtime vaso_rate vaso_amount
# 1          1 2019-09-10 13:20:00 2019-09-12 01:20:00         3    293.0896
# 2          1 2019-09-14 16:40:00 2019-09-15 16:40:00         4    208.9360
# 3          2 2019-09-10 12:40:00 2019-09-13 13:20:00         2    864.1494
# 4          3 2019-09-10 01:20:00 2019-09-11 13:20:00         9    405.2939

注意在此示例中,icusstay 1 的患者情况如何:仅对连续结束时间-开始时间差 1 小时与其他人的差异)保持未分组。

这是我目前所拥有的。我尝试为满足上述条件的患者添加一个额外的组列,然后最终 group_by 这个条件。

但它不起作用......

merge_pressor_doses <- function(df){
  df %>% arrange(icustay_id,starttime)
  a <- 1
  for (i in unique(df$icustay_id))
    {
    for (j in which(df$icustay_id==i) && j < max(which(df$icustay_id==i)))
      {
        df%>%mutate(group = ifelse(df$starttime[j+1]-df$endtime[j] < 60, a, 0))
      }
    }
  df%>%group_by(group) %>% 
    summarise(
      starttime = min(starttime), 
      endtime = max(endtime),
      vaso_rate = mean(vaso_rate),
      sum_vaso_amount = sum(vaso_amount))
    return(df)
}

【问题讨论】:

  • 您好,截图不是分享数据的好方法。以下是创建良好 minimal reproducible example 的方法(即,将您的数据分享给 SO 以更快地获得帮助)。
  • 谢谢,会注意的!!
  • 我无法理解您示例中的分组条件。你不应该根本没有分组吗,因为对于icustay_id == 1,所有观察都有endtime - starttime &gt; 1 hour,除了第1行吗?
  • 是的,你是对的@SamuelDiebolt,我错了。我修改了示例。
  • 是的。我更改了我的示例 df 来说明这一点,并修改了我的 notice 评论!再次感谢,对不清楚的地方深表歉意!

标签: r merge conditional-statements tidyr


【解决方案1】:

回复原帖(endtime - starttime &lt; 1H 稍后添加)

您要查找的不是行合并,而是按患者分组后的某些列的摘要。我使用您的屏幕截图构建了一个玩具数据集(请参阅我的评论以了解如何共享您的数据样本):

library(tidyverse)
library(lubridate)

df <- data.frame(
  icustay_id = c(1, 1, 1, 2, 3),
  starttime = as.POSIXct(c("2019-09-10 13:20", "2019-09-10 15:20",  "2019-09-10 16:40", "2019-09-10 12:40", "2019-09-10 01:20")),
  endtime = as.POSIXct(c("2019-10-10 13:20", "2019-12-10 01:20", "2019-09-15 16:40", "2019-09-13 13:20", "2019-09-11 13:20")),
  vaso_rate = sample(1:10, 5, replace = TRUE),
  vaso_amount = runif(5, 0, 1000)
)
df
#       icustay_id           starttime             endtime vaso_rate vaso_amount
# 1          1 2019-09-10 13:20:00 2019-10-10 13:20:00         3    293.0896
# 2          1 2019-09-10 15:20:00 2019-12-10 01:20:00         9    602.9983
# 3          1 2019-09-10 16:40:00 2019-09-15 16:40:00         4    208.9360
# 4          2 2019-09-10 12:40:00 2019-09-13 13:20:00         2    864.1494
# 5          3 2019-09-10 01:20:00 2019-09-11 13:20:00         9    405.2939

然后我按患者 (icustay_id) 分组,并使用来自 dplyrsummarise 函数汇总您指定的变量。

df %>%
  group_by(icustay_id) %>% 
  summarise(
    starttime       = min(starttime), 
    endtime         = max(endtime),
    avg_vaso_rate   = mean(vaso_rate),
    sum_vaso_amount = sum(vaso_amount)
  )
# A tibble: 3 x 5
#   icustay_id starttime           endtime             avg_vaso_rate sum_vaso_amount
#        <dbl> <dttm>              <dttm>                      <dbl>           <dbl>
# 1          1 2019-09-10 13:20:00 2019-12-10 01:20:00          5.33           1105.
# 2          2 2019-09-10 12:40:00 2019-09-13 13:20:00          2               864.
# 3          3 2019-09-10 01:20:00 2019-09-11 13:20:00          9               405.

【讨论】:

  • 谢谢@Samuel!这绝对是诀窍!事实上,我并没有将其视为总结/分组问题。谢谢!
  • @EricYamga:很高兴我能帮上忙!我应该提到所有其他变量都将被删除。如果您想保留它们,可以将它们添加到 group_by,确保它们包含每个患者的唯一值。否则,您需要创建这些变量的摘要(均值、总和等)
  • 其实我才意识到一个小问题。该功能在开始和结束时间大于 1 小时的情况下无济于事。我真正希望做的是专门针对将两个连续事件分开的时间小于 1 小时的情况进行分组。例如,是否可以将分组限制为行的子集?
  • 我更新了我的问题以说明我要指出的内容!再次感谢!
最近更新 更多