Я отредактировал код из предыдущих ответов так, что они являются функциями, которые принимают одинаковые входные данные (одномерный временной ряд) и возвращают тот же результат (вектор дней с момента последнего n-дневного максимума):
daysSinceHigh1 <- function(x,n) {
as.vector(n-rollapply(x, n, which.max))
}
daysSinceHigh2 <- function(x, n){
apply(embed(x, n), 1, which.max)-1
}
Вторая функция, кажется, самая быстрая, но они дают несколько иные результаты:
> getSymbols("^GSPC",from='01-01-1900')
[1] "GSPC"
> system.time(x <- daysSinceHigh1(Cl(GSPC), 200))
user system elapsed
0.42 0.00 0.42
> system.time(y <- daysSinceHigh2(Cl(GSPC), 200))
user system elapsed
0.24 0.00 0.24
> all.equal(x,y)
[1] "Mean relative difference: 0.005025126"
При ближайшем рассмотрении оказывается, что в 1-й функции есть некоторые странные крайние случаи:
data <- c(1,2,3,4,5,6,7,7,6,5,6,7,8,5,4,3,2,1)
answer <- c(0,0,0,0,1,2,3,0,0,1,2,3,4,4)
x <- daysSinceHigh1(data, 5)
y <- daysSinceHigh2(data, 5)
> x
[1] 0 0 0 1 2 3 4 4 0 1 2 3 4 4
> y
[1] 0 0 0 0 1 2 3 0 0 1 2 3 4 4
> answer
[1] 0 0 0 0 1 2 3 0 0 1 2 3 4 4
> all.equal(x,answer)
[1] "Mean relative difference: 0.5714286"
> all.equal(y,answer)
[1] TRUE
Поэтому, похоже, что вторая функция (на основе кода Андри) лучше.