私は指数関数的に加重移動平均を実行したいです(パラメータ化はhereと定義されています)。以下の最初の試みよりも優れた実装がありますか?指数加重移動平均の高速R実装ですか?
私の最初の試みだった:
ewma <- function(x, a) {
n <- length(x)
s <- rep(NA,n)
s[1] <- x[1]
if (n > 1) {
for (i in 2:n) {
s[i] <- a * x[i] + (1 - a) * s[i-1]
}
}
return(s)
}
y <- 1:1e7
system.time(s <- ewma(y,0.5))
#user system elapsed
# 2.48 0.00 2.50
私の第二の試みで、私はベクトル化でもっとうまくできると思っていた:
ewma_vectorized <- function(x,a) {
a <- 0.1
n <- length(x)
w <- cumprod(c(1, rep(1-a, n-1)))
x1_contribution <- w * x[1]
w <- a * w
x <- x[-1]
s <- apply(as.array(1:(n-1)), 1, function(i,x,w){sum(w[i:1] * x[1:i])}, x=x, w=w)
s <- x1_contribution + c(0,s)
return(s)
}
system.time(s <- ewma_vectorized(y,0.5))
# I stopped the program after it continued to run for 4min
私は結果によってあまりにも驚いていたべきではないと思います私の2回目の試みで。ベクトル化の試みはかなり醜い試みでした。しかし、のようなものがのようなものでなければならない。
UPDATE:
私はより良い実装hereを見つけたし、次のようにそれを適応:
ewma_vectorized_v2 <- function(x, a) {
s1 <- x[1]
sk <- s1
s <- vapply(x[-1], function(x) sk <<- (1 - a) * x + a * sk, 0)
s <- c(s1, s)
return(s)
}
system.time(s <- ewma_vectorized_v2(y,0.5))
# user system elapsed
# 1.74 0.01 1.76
は、あなただけの高速な実装を使用することをお探しですか? [TTRパッケージはC言語で実装しています](https://github.com/joshuaulrich/TTR/blob/master/src/moving_averages.c)。 – Gregor
私はRでこれをやろうとしていて、パッケージを使わないようにしていました。しかしそれは役に立つリンクです。 – lowndrul
@Gregor:それはひどい*パッケージです。 :P OPは代わりに 'stats :: filter'を使うことができます。 –