Почему rollapply работает намного медленнее, если fill=NA и функция возвращает несколько значений?

Если функция возвращает 2 или более значений и использует fill = NA, rollapply становится намного медленнее. Есть ли способы избежать этого?

f1= function(v)c(mean(v)+ median(v))    #return vector of length 1
f2= function(v)c(mean(v), median(v))    #return vector of length 2


v = rnorm(1000)
microbenchmark(rollapplyr(v, 20, f1), rollapplyr(v,20, f1, fill=NA) )

#                             expr      min       lq     mean   median       uq      max neval
#            rollapplyr(v, 20, f1) 50.84485 53.68726 57.21892 54.63793 57.78519 75.88305   100
# rollapplyr(v, 20, f1, fill = NA) 52.11355 54.69866 59.73473 56.20600 63.10546 99.96493   100

microbenchmark(rollapplyr(v, 20, f2), rollapplyr(v,20, f2, fill=NA) )

#                             expr      min       lq     mean   median       uq      max neval
#            rollapplyr(v, 20, f2) 51.77687 52.29403 56.80307 53.44605 56.65524 105.6713   100
# rollapplyr(v, 20, f2, fill = NA) 69.93853 71.08953 76.48056 72.21896 80.58282 151.4455   100

person user3226167    schedule 19.01.2017    source источник
comment
1-Вы не указали пакеты, которые используете. 2- Вы даже не указали единицы измерения. Вроде как небольшой штраф за выполнение дополнительной операции. 3- Если вы хотите повысить скорость, проверьте cran.r-project. org/web/packages/RcppRoll/RcppRoll.pdf   -  person David Arenburg    schedule 19.01.2017
comment
Дополнительное время кажется линейным с длиной v выше.   -  person user3226167    schedule 20.01.2017


Ответы (1)


Причина заключается в скорости использования fill.na для разных типов данных, как это происходит внутри функции rollapply(). Ваш f1 возвращает один вектор, тогда как f2 возвращает матрицу из двух столбцов (ну, на самом деле оба являются объектами zoo, но вы понимаете, о чем я).

Снижение скорости при вставке NA не пропорционально простому удвоению количества элементов, как это показывает:

library(zoo)
library(microbenchmark)

v <- zoo(rnorm(1000))
m <- zoo(matrix(rnorm(2000), ncol=2))
ix <- seq(1000)>50
microbenchmark(na.fill(v, NA, ix), na.fill(m, NA, ix))

# Unit: microseconds
#               expr      min        lq       mean    median         uq      max neval
# na.fill(v, NA, ix)  402.861   511.912   679.1114   659.597   754.8385  4716.46   100
# na.fill(m, NA, ix) 9746.643 10091.038 14281.5598 14057.304 17589.9670 22249.96   100
person mpjdem    schedule 19.01.2017