在Forecast()和ar()中传递参数时预测R中的错误

Cry*_*koo 5 r time-series forecasting

当尝试使用Rob Hyndman的预测库从较小的函数编写函数时,如下所示:

> library('forecast')
> arf <- function(data, ...) forecast(ar(data, order.max=1, method="ols"), ...)
Run Code Online (Sandbox Code Playgroud)

尝试插入一些数据时出错:

> arf(ts(1:100, start=c(2000,1), frequency=4))
Error in ts(x, frequency = 1, start = 1) : object is not a matrix
Run Code Online (Sandbox Code Playgroud)

但是,使用arf的主体可以直接使用:

> forecast(ar(ts(1:100, start=c(2000,1), frequency=4), order.max=1,method="ols"))
        Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
2025 Q1            101   101   101   101   101
2025 Q2            102   102   102   102   102
2025 Q3            103   103   103   103   103
2025 Q4            104   104   104   104   104
2026 Q1            105   105   105   105   105
2026 Q2            106   106   106   106   106
2026 Q3            107   107   107   107   107
2026 Q4            108   108   108   108   108
2027 Q1            109   109   109   109   109
2027 Q2            110   110   110   110   110
Run Code Online (Sandbox Code Playgroud)

为什么arf不能正常工作?

Rob*_*man 4

这是一个问题(不是真正的错误)forecast.ar()。所有forecast.xxx()函数都尝试存储用于估计时间序列模型的数据,因为绘图和精度计算需要这些数据。但是,ar()不会返回数据,因此forecast.ar()会尝试在调用环境或父环境中查找数据。当您直接调用时forecast(ar(...)),该函数会设法找到数据,但arf()会将调用置于ar()更深的一层,从而使弄清楚forecast正在使用哪些数据变得更加困难。

我可以修改该函数以使其更难查找数据(即也在祖父母环境中查找),但构造仍然会失败,因为predict.ar()(包的一部分stats)将导致类似的错误。如果返回数据会更好,但它是包的一部分,我无法控制它。ar()ar()stats

有几种可能的解决方案。

  1. 您可以替换arArima

    arf <- function(dat, ...) forecast(Arima(dat, order=c(1,0,0)), ...)
    
    Run Code Online (Sandbox Code Playgroud)

    如果数据是固定的,那么应该返回相同的模型(尽管参数估计值会略有不同)。对于您问题中的示例,它不会返回相同的答案,因为时间序列是非平稳的。

  2. auto.arima()如果您愿意使用比 AR(1) 更通用的 ARIMA 模型,则可以使用它。

    arf <- function(dat, ...) forecast(auto.arima(dat, ...)
    
    Run Code Online (Sandbox Code Playgroud)
  3. (基于@agstudy 的建议)。解决方法是确保数据存储在ar对象内:

    arf <- function(dat, ...) 
    {
      object <- ar(dat, order.max=1, method="ols")
      object$x <- dat
      forecast(object,...)
    }
    
    Run Code Online (Sandbox Code Playgroud)