我有一个数据集,其中包含多个感兴趣的变量。我想做的是使用
rollapplyr()
包中的 zoo
函数为每个函数计算滚动平均值作为附加列,但需要注意的是我想使用不同的窗口宽度(width =
)取决于列。我还希望避免将数据转换为长格式。
library(tidyverse)
library(zoo)
rolling_f <- function(x, wdw, fun){ rollapplyr(x, wdw, fun, partial = TRUE) }
set.seed(1)
ex <- data.frame(
var1 = rnorm(20, 8000, 500),
var2 = rnorm(20, 8000, 500),
var3 = rnorm(20, 8000, 500),
var4 = rnorm(20, 8000, 500),
var5 = rnorm(20, 8000, 500),
var6 = rnorm(20, 8000, 500),
var7 = rnorm(20, 8000, 500),
var8 = rnorm(20, 8000, 500)
) %>%
mutate(
across(
.cols = starts_with("var"),
.fns = ~rolling_f(.x, 5, mean),
.names = "{.col}_roll"
)
)
到目前为止,我的代码为每列计算相同的窗口宽度 (5),但我希望有人能够帮助我进一步定义我的自定义函数,这样窗口可以是 3 表示
var1:var3
,5 表示 var4:var5
,例如 6 表示 var6:var8
。我认为这只需要在我启动的自定义 rolling_f()
函数中添加一些额外的代码。
您可以使用
case_match()
/case_when()
来确定窗口大小:
library(dplyr)
library(readr)
library(zoo)
# case_match()
ex %>%
mutate(across(
.cols = starts_with("var"),
.fns = ~ rolling_f(.x, case_match(
parse_number(cur_column()), 1:3 ~ 3, 4:5 ~ 5, 6:8 ~ 6
), mean),
.names = "{.col}_roll"
))
# case_when()
ex %>%
mutate(across(
.cols = starts_with("var"),
.fns = ~ rolling_f(
.x,
case_when(
cur_column() %in% paste0("var", 1:3) ~ 3,
cur_column() %in% paste0("var", 4:5) ~ 5,
cur_column() %in% paste0("var", 6:8) ~ 6
),
mean
),
.names = "{.col}_roll"
))