robjhyndman / forecast

Forecasting Functions for Time Series and Linear Models
http://pkg.robjhyndman.com/forecast
1.1k stars 340 forks source link

hfitted bug #924

Closed danigiro closed 1 year ago

danigiro commented 1 year ago

Multi-step fitted arima

library(forecast)

mod <- Arima(log(AirPassengers), c(0,1,1), include.drift = TRUE)
mod
# > Series: log(AirPassengers) 
# > ARIMA(0,1,1) with drift 
# > 
# > Coefficients:
# >          ma1   drift
# >       0.2721  0.0097
# > s.e.  0.0947  0.0110
# > 
# > sigma^2 = 0.01081:  log likelihood = 121.75
# > AIC=-237.51   AICc=-237.33   BIC=-228.62

head(fitted(mod, h = 1)) # ok
# >           Jan      Feb      Mar      Apr      May      Jun
# > 1949 4.713790 4.729717 4.791402 4.917329 4.853888 4.789706

head(fitted(mod, h = 2)) # Only NA
# >           Jan      Feb      Mar      Apr      May      Jun
# > 1949       NA       NA       NA       NA       NA       NA

I solved the problem by fixing the forecast function hfitted()

head(fitted(mod, h = 2))
# >           Jan      Feb      Mar      Apr      May      Jun
# > 1949       NA       NA       NA 4.800895 4.927066 4.863615

Where did I find the problem?

In function hfitted() line 486-489

if (!is.null(object$xreg)) {
  refitarg$xreg <- ts(object$xreg[1:i, ], start = tspx[1], frequency = tspx[3])
  fcarg$xreg <- ts(object$xreg[(i + 1):(i + h), ], start = tspx[1] + i / tspx[3], frequency = tspx[3])
}

The object refitarg$xreg has two drifts instead of just one, and so the fitting function gives an error because there are too many regressors (one more than the previous fitting). The solution I found is to delete the drift column in the old xreg.

if(!is.null(object$xreg) & any(colnames(object$xreg)!="drift")){
  if(any(colnames(object$xreg)=="drift")){
    idx <- which(colnames(object$xreg)=="drift")
    refitarg$xreg <- ts(object$xreg[1:i, -idx], start = tspx[1], frequency = tspx[3])
    fcarg$xreg <- ts(object$xreg[(i + 1):(i + h), -idx], start = tspx[1] + i / tspx[3], frequency = tspx[3])
  }else{
    refitarg$xreg <- ts(object$xreg[1:i, ], start = tspx[1], frequency = tspx[3])
    fcarg$xreg <- ts(object$xreg[(i + 1):(i + h), ], start = tspx[1] + i / tspx[3], frequency = tspx[3])
  }
}