When trying to compose a function from smaller ones using Rob Hyndman's forecast library, like so:
> library('forecast')
> arf <- function(data, ...) forecast(ar(data, order.max=1, method="ols"), ...)
I get an error when trying to plug in some data:
> arf(ts(1:100, start=c(2000,1), frequency=4))
Error in ts(x, frequency = 1, start = 1) : object is not a matrix
However, using the body of arf directly works perfectly:
> 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
Why does arf not work as it should?
the problem is a bug in the S3 method predict for
ar
class.predict.ar
try to evaluate the newdata parameter usingar
object. Showing the first lines ofgetS3method('predict','ar')
the relevant/bugged line is:
But object$series don't have the right expression/character. since it is hidden by the new level of wrapper function arf. Here a workaround, is to set the right expression for this term:
Note that ; this solution works also with:
This is a problem (not really a bug) in
forecast.ar()
. Allforecast.xxx()
functions try to store the data used to estimate the time series model as it is required for plots and accuracy calculations. However,ar()
does not return the data, soforecast.ar()
attempts to find the data in the calling environment, or in the parent environment. When you callforecast(ar(...))
directly, the function manages to find the data, butarf()
places the call toar()
one level deeper making it that much harder forforecast
to figure out what data was being used.I can modify the function to make it look harder for the data (i.e., look in the grandparent environment also), but the construction will still fail because
predict.ar()
(part of thestats
package) will then cause a similar error. It would be much better ifar()
returned the data, butar()
is part of thestats
package and I have no control over it.There are several possible solutions.
You could replace
ar
withArima
:That should return the same model if the data are stationary (although the parameter estimates will be slightly different). It won't return the same answer for the example in your question because the time series is non-stationary.
You could use
auto.arima()
instead if you were willing to use more general ARIMA models than AR(1).(Based on a suggestion from @agstudy). A workaround is to ensure the data is stored within the
ar
object: