diff --git a/R/arima.R b/R/arima.R index 1f30d004..2bcc5419 100644 --- a/R/arima.R +++ b/R/arima.R @@ -964,3 +964,30 @@ is.Arima <- function(x) { fitted.ar <- function(object, ...) { getResponse(object) - residuals(object) } + +hfitted.Arima <- function(object, h, ...) { + # As implemented in Fable + if(h == 1){ + return(object$fitted) + } + y <- object$fitted+residuals(object, "innovation") + yx <- residuals(object, "regression") + # Get fitted model + mod <- object$model + # Reset model to initial state + mod <- stats::makeARIMA(mod$phi, mod$theta, mod$Delta) + # Calculate regression component + xm <- y - yx + fits <- rep_len(NA_real_, length(y)) + + start <- length(mod$Delta) + 1 + end <- length(yx) - h + idx <- if(start > end) integer(0L) else start:end + for(i in idx) { + fc_mod <- attr(stats::KalmanRun(yx[seq_len(i)], mod, update = TRUE), "mod") + fits[i + h] <- stats::KalmanForecast(h, fc_mod)$pred[h] + xm[i+h] + } + fits <- ts(fits) + tsp(fits) <- tsp(object$x) + fits +} diff --git a/R/forecast.R b/R/forecast.R index c1ef40da..a01ef319 100644 --- a/R/forecast.R +++ b/R/forecast.R @@ -451,6 +451,10 @@ predict.default <- function(object, ...) { } hfitted <- function(object, h=1, FUN=NULL, ...) { + UseMethod("hfitted") +} + +hfitted.default <- function(object, h=1, FUN=NULL, ...) { if (h == 1) { return(fitted(object)) }