You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:48:43