考虑以下小标题:
df <- tribble(
~dt, ~value, ~avg,
make_date(2023-08-01),1,NA,
make_date(2023,08,02),2,1,
make_date(2023,08,04),3,1.5,
make_date(2023,08,07),4,3,
make_date(2023,08,08),5,4,
make_date(2023,08,09),6,4.5,
make_date(2023,08,10),7,5,
make_date(2023,08,11),8,6,
make_date(2023,08,12),9,7
)
我想计算 dt 之前三天内任何记录的平均值。例如,在 2023-08-04,我对 2023-08-03、2023-08-02 和 2023-08-01 的值进行平均,它们是 NA、2、1,所以这些 (na.rm) 值的平均值是 1.5。
因此,对于这个示例,我想添加“avg”列:
dt value avg
<date> <dbl> <dbl>
2014-01-01 1 NA
2023-08-02 2 1
2023-08-04 3 1.5
2023-08-07 4 3
2023-08-08 5 4
2023-08-09 6 4.5
2023-08-10 7 5
2023-08-11 8 6
2023-08-12 9 7
日期中可能存在任何大小的空白。真正的应用程序将有许多日期(数千个)并按 subject_id 分组(此处不包括)。对于其他窗口大小,可能需要重复前“三天”。
这是使用
rollapply
包中的 zoo
的方法:
library(dplyr)
library(zoo)
library(lubridate)
df %>%
mutate(
avg = rollapply(value, 4, \(x) mean(head(x, -1), na.rm = TRUE),
align = 'right', partial = TRUE, fill = NA)
)
dt value avg
<date> <dbl> <dbl>
1 2014-01-01 1 NaN
2 2023-08-02 2 1
3 2023-08-04 3 1.5
4 2023-08-07 4 2
5 2023-08-08 5 3
6 2023-08-09 6 4
7 2023-08-10 7 5
8 2023-08-11 8 6
9 2023-08-12 9 7