Поскольку cota[3]
полагается на обновленное значение cota[2]
, которое опирается на cota[1]
, вы не можете выполнить простую векторизацию этой функции. Иногда вы можете обмануть, используя cumsum
, cumprod
или аналогичные кумулятивные функции (которые все еще итеративны, но в действительно оптимизированном коде), но это зависит от «простого итеративного накопления». В этом случае, однако, последовательность
cota[2] = cota[1] * (pl[2] - mov[2]) / pl[1],
cota[3] = cota[2] * (pl[3] - mov[3]) / pl[2]
если вы замените cota[2]
, вы получите
(cota[1] * (pl[2] - mov[2]) / pl[1]) * (pl[3] - mov[3]) / pl[2]
что эффективно
cota[1] * (pl[2]*pl[3] - pl[2]*mov[3] - pl[3]*mov[2] + mov[2]*mov[3]) / (pl[1] * pl[2])
, который не сразу поддается простым кумулятивным операторам.
Некоторые функции, обеспечивающие своего рода подвижные окна, в частности zoo::rollapply
, но часто они делают петлю for
под капотом. (Технически, я считаю, что большинство *apply
функций также делают for
петли под капотом, хотя, вероятно, хорошо под капотом.)
Если у вас есть проблемы с производительностью этой или подобных функций, вы всегда можете использовать Rcpp
или аналогичные ускорения. (Как только вы попадете на Rcpp
-территорию, вы можете обнаружить, что необработанный цикл for
превзойдет векторизованный код, даже Rcpp
-нативную векторизацию, хотя это во многом зависит от многих других вещей.)