寻求R语言支持动态窗口大小的移动平均实现方案
动态窗口移动平均的R实现
当然可以实现动态窗口的移动平均!你提到的zoo::rollmean只支持固定窗口大小,那我们自己写一个适配动态窗口的函数就好,刚好匹配你要的左对齐需求。
实现思路
左对齐的动态窗口逻辑很明确:对于向量的第i个位置,取从i开始的dynamicRange[i]个元素计算均值;如果从i开始的元素数量不足dynamicRange[i]个(比如最后几个位置),就返回指定的填充值(默认NA)。
基础R实现
用基础R的sapply就能快速实现,不需要额外依赖:
foo <- function(x, window_sizes, fill = NA, align = "left") { # 仅支持左对齐,若需要其他对齐方式可以扩展 if (align != "left") { stop("当前版本仅支持左对齐(align='left')") } vec_length <- length(x) # 遍历每个位置计算对应窗口的均值 sapply(seq_len(vec_length), function(i) { current_window <- window_sizes[i] window_end <- i + current_window - 1 # 检查窗口是否超出向量范围 if (window_end > vec_length) { fill } else { mean(x[i:window_end]) } }) }
测试验证
用你给出的示例数据测试:
toSmoothed <- c(1,2,3,2,1,2,3,2) dynamicRange <- c(1,2,1,2,1,2,1,2) foo(toSmoothed, dynamicRange, fill = NA, align = "left")
运行结果完全符合你的预期:
[1] 1.0 2.5 3.0 1.5 1.0 2.5 3.0 NA
用purrr简化实现
如果你习惯用tidyverse工具链,用purrr::map2_dbl可以写出更简洁的代码:
library(purrr) foo <- function(x, window_sizes, fill = NA, align = "left") { stopifnot(align == "left") map2_dbl(seq_along(x), window_sizes, ~{ window_end <- .x + .y - 1 if (window_end > length(x)) fill else mean(x[.x:window_end]) }) }
性能说明
如果你的向量规模特别大(比如百万级以上),循环类的实现可能会有点慢,这时可以考虑用Rcpp写底层逻辑来提速;但对于绝大多数日常分析场景,上面的实现已经足够高效好用。
内容的提问来源于stack exchange,提问作者pepece
相关产品推荐
相关产品推荐

