使用变量 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 行的平均值。
我已经尝试使用一些 zoo
和 data.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))
我有一个生命体征的重复测量数据集。我正在尝试计算患者前 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 行的平均值。
我已经尝试使用一些 zoo
和 data.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))