R语言中按年份为所有列计算滑动平均值的实现方法
按年份分组计算多列滑动平均的实现方法
你原有的单列分组计算逻辑是正确的,要扩展到所有目标列,直接使用跨列操作语法即可,以下提供两种可直接运行的实现方案:
方案1:dplyr + across 实现(最简洁,推荐)
借助dplyr 1.0.0及以上版本支持的across()函数,可批量对多列执行分组计算:
library(TTR) library(dplyr) dat <- data.frame(yr = c(1980, 1980, 1980, 1980, 1980, 1981, 1981, 1981, 1981, 1981, 1982, 1982, 1982, 1982, 1982), data1 = c(-10.16, -7.48, -3.31, -6.04, -11.68, -13.40, -10.41, -10.65, -6.70, -17.05, -25.62, -29.14, -16.65, -6.42, 0.28), data2 = c(2.30, -7.52, -13.26, -13.24, -14.74, -9.38, -8.93, -11.78, -14.07, -11.66, -8.82, -10.30, -7.99, -10.02, -15.36), data3 = c(-14.83, -15.08, -16.44, -18.95, -13.40, -7.16, -4.35, -1.61, -0.01, -0.35, -2.09, -3.12, 0.87, -0.06, 2.29)) dat_runavg <- dat %>% # 按年份分组 group_by(yr) %>% # 对除yr外的所有列应用3点滑动平均,新列名后缀加_runavg3 mutate(across(-yr, ~ TTR::runMean(.x, n = 3), .names = "{col}_runavg3")) %>% ungroup()
如果需要直接覆盖原数据列而非生成新列,删除.names参数即可。
方案2:基础R lapply 实现
不需要额外依赖dplyr的场景可以用基础R语法实现:
library(TTR) dat <- data.frame(yr = c(1980, 1980, 1980, 1980, 1980, 1981, 1981, 1981, 1981, 1981, 1982, 1982, 1982, 1982, 1982), data1 = c(-10.16, -7.48, -3.31, -6.04, -11.68, -13.40, -10.41, -10.65, -6.70, -17.05, -25.62, -29.14, -16.65, -6.42, 0.28), data2 = c(2.30, -7.52, -13.26, -13.24, -14.74, -9.38, -8.93, -11.78, -14.07, -11.66, -8.82, -10.30, -7.99, -10.02, -15.36), data3 = c(-14.83, -15.08, -16.44, -18.95, -13.40, -7.16, -4.35, -1.61, -0.01, -0.35, -2.09, -3.12, 0.87, -0.06, 2.29)) # 提取要计算的列,排除yr target_cols <- setdiff(colnames(dat), "yr") # 批量对每列执行分组滑动平均 runavg_res <- lapply(dat[target_cols], function(col) { ave(col, dat$yr, FUN = function(x) TTR::runMean(x, n = 3)) }) # 结果合并回原数据框 dat_runavg <- cbind(dat, setNames(runavg_res, paste0(target_cols, "_runavg3")))
注意事项
TTR::runMean默认前n-1个值返回NA,若需要首尾也输出计算值,可添加参数na.rm = TRUE,也可通过align参数调整滑动窗口对齐方式(可选left/center/right,默认是center)- 调整参数
n的数值即可修改滑动窗口的大小
内容的提问来源于stack exchange,提问作者Indrute
相关产品推荐
相关产品推荐

