如何在R中根据列名设置rollapplyr()的不同窗口宽度
解决方案
要实现按列名分组设置不同窗口宽度计算滚动平均值,无需转换为长格式,有两种简洁的实现方式:
方法一:分多组调用across
直接针对不同列组分别指定窗口宽度,逻辑清晰易懂:
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( # var1至var3使用窗口宽度3 across( .cols = var1:var3, .fns = ~rolling_f(.x, 3, mean), .names = "{.col}_roll" ), # var4至var5使用窗口宽度5 across( .cols = var4:var5, .fns = ~rolling_f(.x, 5, mean), .names = "{.col}_roll" ), # var6至var8使用窗口宽度6 across( .cols = var6:var8, .fns = ~rolling_f(.x, 6, mean), .names = "{.col}_roll" ) )
方法二:通过列名匹配动态获取窗口宽度
如果列名有规律,可编写一个匹配窗口的函数,结合cur_column()动态获取当前列对应的窗口宽度,扩展性更强:
library(tidyverse) library(zoo) rolling_f <- function(x, wdw, fun){ rollapplyr(x, wdw, fun, partial = TRUE) } # 定义根据列名返回窗口宽度的函数 get_window_width <- function(col_name) { case_when( str_detect(col_name, "^var[1-3]$") ~ 3, str_detect(col_name, "^var[4-5]$") ~ 5, str_detect(col_name, "^var[6-8]$") ~ 6, TRUE ~ stop("无法识别的列名,请检查规则") ) } 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, get_window_width(cur_column()), mean), .names = "{.col}_roll" ) )
两种方法都无需转换数据格式,直接在原数据框上生成对应滚动平均列,可根据实际列的数量和规则选择合适的方式。
内容的提问来源于stack exchange,提问作者user13973103
相关产品推荐
相关产品推荐

