使用变量 window 宽度按 ID 计算滚动平均值

Calculating rolling mean by ID with variable window width

我有一个生命体征的重复测量数据集。我正在尝试计算患者前 24 小时观察的一些汇总统计数据(平均值、最小值、最大值、斜率等),由 Admit_to_Perform 变量测量, 排除 目前的观察。这是第一位患者的前 15 次观察的摘录:

df1 <- data.frame(ID = rep(1, 15), 
Admit_to_Perform = c(1.07, 1.07, 1.70, 3.73, 3.73, 4.20, 8.87, 11.68, 14.80, 15.67, 19.08, 23.15, 29.68, 36.03, 39.08), 
Resp_Rate = c(18, 17, 18, 17, 16, 16, 16, 16, 16, 17, 16, 16, 16, 16, 16))

     ID     Admit_to_Perform Resp_Rate
 1:  1             1.07        18
 2:  1             1.07        17
 3:  1             1.70        18
 4:  1             3.73        17
 5:  1             3.73        16
 6:  1             4.20        16
 7:  1             8.87        16
 8:  1            11.68        16
 9:  1            14.80        16
10:  1            15.67        17
11:  1            19.08        16
12:  1            23.15        16
13:  1            29.68        16
14:  1            36.03        16
15:  1            39.08        16

我想为 Resp_Rate 的每个摘要统计信息添加一列。第一行在过去 24 小时内没有先前的观测值,因此可以为空,但对于第二行,平均值为 18,第三行为 17.5,第四行为 17.667,依此类推。然而对于第 13 行,因为 Admit_to_Perform 在前 6 次观察后超过 24 小时,它只会取第 7-12 行的平均值。

我已经尝试使用一些 zoodata.table 函数,但似乎没有任何效果。

编辑:我应该提一下我的数据集超过了 150 万行。因此,使用任何类型的 rowwise 或过滤器的基础 R 和 dplyr 解决方案都是有效的,但速度太慢 运行(4 天并在我终止命令之前计数)

一个快速而肮脏的解决方案,其中 Resp_Rate 是 hard-coded 到 f(),它会很慢,因为它对每一行的数据集执行过滤器,但是这就是你想要的。

library(tidyverse)

df1 <- data.frame(ID = rep(1, 15), 
                  Admit_to_Perform = c(1.07, 1.07, 1.70, 3.73, 3.73, 4.20, 8.87, 11.68, 14.80, 15.67, 19.08, 23.15, 29.68, 36.03, 39.08), 
                  Resp_Rate = c(18, 17, 18, 17, 16, 16, 16, 16, 16, 17, 16, 16, 16, 16, 16))


f <- function(data, id, outcome, time, window=24) {
  data <- filter(data, 
                 ID==id,
                 Admit_to_Perform>(time-window),
                 Admit_to_Perform<time)
  if(length(!is.na(data$Resp_Rate))==0) return(NA)
  mean(data$Resp_Rate)
}



df1 %>%
  rowwise() %>%
  mutate(roll=f(data=., id=ID, outcome=Resp_Rate, time=Admit_to_Perform))