向量化计算 R 中移动平均数的差异?

vectorize computation of difference of moving averages in R?

我有一个向量,对于该向量中的每个点,我想计算紧接在该点之前的某些范围内的点的平均值减去紧接在该点之后的某些范围内的点的平均值之间的差值。我用 for 循环完成了此操作,因为 filter 似乎没有选项可以专门应用于矢量点之后的点(参数边 = 仅 1 或 2),因为我不知道如何将其硬塞进一个 apply 语句,因为我需要一个函数,它使用每个点在向量中的位置而不仅仅是它自己的值来操作每个点。谁能给我指路?

这是我用 for 循环完成的方法:

x = rep(c(1,1,1,1,1,10), 20)
x = x + 100
x = x - c(1:length(x))
lookahead = 4
y = x

for(i in (lookahead):(length(x)-lookahead))
{
y[i] = mean(x[(i-lookahead):i]) - mean(x[i:(i+lookahead)])
}
plot(x)
lines(y, col="red")

您可以从图中看出 objective 是什么:识别尖峰(但不,我不想被告知寻找尖峰的其他方法,我想使用我的简单 boxcar 移动平均线方法)。

一定有更好的方法来计算这个向量。感谢您的任何建议。

p.s。我看到有人想将其标记为 Calculating moving average in R 的重复,但是我的问题不同,因为该问题的答案(使用 roll_mean 或过滤器)未经修改不适用于此处。如果有使用 roll_mean 或过滤器的方法,我无法从文档中分辨出来,希望有人告诉我如何使用其中任何一个来计算前瞻性移动平均线而不是后视移动平均线.再次感谢。

好的。但是,我有一个解决方案,我已经修改了您的循环代码,使其从 (lookahead+1):(length(x)-lookahead) 开始。这样一来,第一个平均值就像其他所有值一样是 5 个值的平均值。

计算 5 个值的平均值向量:

lastIndexInY <- length(x)-lookahead 
Y_ave <- (x[ 1:lastIndexInY ] + x[ 1:lastIndexInY +1] + x[ 1:lastIndexInY +2] + x[ 1:lastIndexInY +3]+ x[ 1:lastIndexInY +4] )/5

那么你的结果 y 是一样的:

y_vec  <- c(x[1:4], Y_ave[1:(length(Y_ave)-4)] - Y_ave[5:length(Y_ave) ] ,  x[-3:0 + length(x)]  )

all(y - y_vec == 0 )
[1] TRUE

(您确定需要保留 x 的前 4 个和后 4 个值吗?)

您的程序的问题是它从 i=4 开始,子集 x[0:4] 中 R 自动修剪掉 0 索引。

y1 = RcppRoll::roll_mean(x, 5)
y1 = c(rep(NA, 4), y1) - c(y1, rep(NA, 4)) # you can use y1 = lag(y1, 4) - y1 instead if you have dplyr
# fill NA positions
y1[1:4]=x[1:4] 
y1[116:120]=x[116:120]

y1y 的不同之处仅在于第 4 位和第 116 位循环有问题。

如果您无法访问 RcppRoll,则可以使用 embed(比 zoo::rollmean 更快)。

y1 = rowMeans(embed(x, 5)) #slightly slower than roll_mean
y1 = c(rep(NA, 4), y1) - c(y1, rep(NA, 4)) # you can use y1 = lag(y1, 4) - y1 instead if you have dplyr
# fill NA positions
y1[1:4]=x[1:4] 
y1[116:120]=x[116:120]