使用purrr中的pmap迭代具有时间序列函数的列表列表

时间:2018-06-11 21:37:13

标签: r time-series purrr

我编写了以下函数 mape_fcn 来计算时间序列预测的准确性,如下所示:

library(forecast)
mape_fcn <- function(fcn, trn, tst, h) {
   fcst <- forecast(fcn(trn), h = h) # calculates a forecast using the training data
   fcst_mean <- as.numeric(fcst$mean) # converts the forecast to a numeric value
   mape <- sum(abs(fcst_mean - tst))/sum(tst) # calculates the weighted MAPE (Mean Absolute Percentage Error) of this forecast on the training data to the test data
   mape
}

其中 fcn 是测试的时间序列函数, trn 是时间序列训练数据(除了最后的 h 观察之外的所有数据),< em> tst 是为了测试预测的准确性而被保留的时间序列测试数据, h 是预测的范围。

我已将此函数与 purrr 库中的 pmap 一起用于通过一次培训计算预测库中各种函数的MAPE一个测试数据集如下。

library(purrr)
library(forecast)

fcns <- list(auto.arima, nnetar, tbats)
trainlstsku1 <- list(trainsku1)
testlstsku1 <- list(testsku1)
pmap(list(fcns, trainlstsku1, testlstsku1, 12), mape_fcn) 

下面的输出是各种函数的MAPE(小数,而不是百分数)。

# [[1]]
# [1] 0.4552366
# 
# [[2]]
# [1] 0.3576489
# 
# [[3]]
# [1] 0.4256295

我想扩展这个,分别迭代两个训练和两个测试集,正如我在下面尝试过的那样。

trainlstsample <- list(list(trainsku1, trainsku2))
testlstsample <- list(list(testsku1, testsku2))
pmap(list(fcns, trainlstsample, testlstsample, 12), mape_fcn)

因此,对于每个数据集(sku1和sku2),我想查看列出的三个函数的MAPE。将有6个MAPE输出。

然而,这是我得到的错误:

 Error in is.constant(x) : 
    (list) object cannot be coerced to type 'double'
    Called from: is.constant(x)

以下是带有将矢量转换为 ts 对象的代码的相应数据。 (由于格式化问题,我没有作为 ts 对象共享。)虽然通常不建议,但我共享所有数据,因为数据集不大,并且预测功能需要足够的观察。在此先感谢您的帮助。

trainsku1 <- ts( c(31900, 48000, 16000, 0, 16000, 48000, 96000, 0, 0, 31900, 32000, 63000, 63600, 32000, 0, 0, 0, 63100, 63300, 126500, 32000, 96000, 32000, 61400, 30000, 32000, 63700, 63700, 0, 0, 92800, 29800, 0, 0, 61800, 76500, 47800, 107600, 45200, 31700, 14600, 63600, 79500, 31900, 16000, 48000, 48000, 48000), start = c(2013, 8), frequency = 12)  
testsku1 <- ts( c(16000, 48000, 32000, 16000, 48000, 64000, 111900, 48000, 16000, 62900, 31300, 32000), start = c(2017, 8), frequency = 12)
trainsku2 <- ts( c(56250, 90000, 108900, 96000, 0, 0, 0, 86400, 32400, 43200, 162000, 216000, 64800, 97200, 75600, 75600, 64800, 64800, 0, 0, 0, 0, 108000, 54000, 0, 0, 43200, 43200, 0, 0, 43200, 43200, 43200, 0, 108000, 43200, 43200), start = c(2014, 6), frequency = 12)
testsku2 <- ts( c(54000, 43200, 43200, 0, 0, 97200, 0, 54000, 0, 54000, 129600, 0, start = c(2017, 7), frequency = 12)

1 个答案:

答案 0 :(得分:1)

trainlstsampletestlstsample的定义更改为嵌套列表:

trainlstsample <- list(list(trainsku1), list(trainsku2))
testlstsample <- list(list(testsku1), list(testsku2))

然后,您可以将pmap调用嵌套在对这些对象进行迭代的map2调用中:

map2( .x = trainlstsample, .y = testlstsample,
    ~pmap(list(fcns, .x, .y, 12), mape_fcn) )
# [[1]]
# [[1]][[1]]
# [1] 0.4552366

# [[1]][[2]]
# [1] 0.364658

# [[1]][[3]]
# [1] 0.4256295

# [[2]]
# [[2]][[1]]
# [1] 0.7338271

# [[2]][[2]]
# [1] 1.055283

# [[2]][[3]]
# [1] 0.6990185