我试着用R来计算矩阵中一系列值的移动平均值。R中似乎没有一个内置函数可以让我计算移动平均线。有任何软件包提供这样的服务吗?还是需要我自己写?


当前回答

你可以通过以下方法计算窗口宽度为k的向量x的移动平均值:

apply(embed(x, k), 1, mean)

其他回答

caTools包具有非常快速的滚动mean/min/max/sd和其他一些功能。我只使用过runmean和runsd,它们是迄今为止提到的其他包中最快的。

使用费用应充分、有效。假设你有一个向量x,你想要n个数的和

cx <- c(0,cumsum(x))
rsum <- (cx[(n+1):length(cx)] - cx[1:(length(cx) - n)]) / n

正如@mzuther在评论中指出的那样,这假设数据中没有NAs。要处理这些问题,需要将每个窗口除以非na值的数量。这里有一种方法,结合@里卡多·克鲁兹的评论:

cx <- c(0, cumsum(ifelse(is.na(x), 0, x)))
cn <- c(0, cumsum(ifelse(is.na(x), 0, 1)))
rx <- cx[(n+1):length(cx)] - cx[1:(length(cx) - n)]
rn <- cn[(n+1):length(cx)] - cn[1:(length(cx) - n)]
rsum <- rx / rn

这仍然有一个问题,如果窗口中的所有值都是NAs,那么将会有一个零误差的除法。

下面是一个简单的带有过滤器的函数,演示了一种方法来处理带有填充的开始和结束NAs,并使用自定义权重计算加权平均值(由过滤器支持):

wma <- function(x) { 
  wts <- c(seq(0.5, 4, 0.5), seq(3.5, 0.5, -0.5))
  nside <- (length(wts)-1)/2
  # pad x with begin and end values for filter to avoid NAs
  xp <- c(rep(first(x), nside), x, rep(last(x), nside)) 
  z <- stats::filter(xp, wts/sum(wts), sides = 2) %>% as.vector 
  z[(nside+1):(nside+length(x))]
}

动物园包中的滚动平均值/最大值/中位数(rollmean) TTR中的移动平均线 马云在预测

或者你可以简单地计算它使用过滤器,这是我使用的函数:

ma <- function(x, n = 5){filter(x, rep(1 / n, n), sides = 2)}

如果使用dplyr,请注意在上面的函数中指定stats::filter。