Nothing
#' Updating functional demographic models and coherent functional demographic models.
#'
#' \code{update.fmforecast()} updates \code{fdm} forecasts. The argument \code{object} is the output from \code{\link{forecast.fdm}} which has been subsequently modified with new coefficient forecasts. These new forecasts are used when re-calculating the forecast of the mortality or fertility rates, or net migration numbers.
#' \code{update.fmforecast2()} updates \code{fdmpr} forecasts. The argument \code{object} is the output from \code{\link{forecast.fdmpr}} which has been subsequently modified with new coefficient forecasts.
#'
#' @param object Output from either \code{\link{fdm}} or \code{\link{coherentfdm}}.
#' @param ... Extra arguments currently ignored.
#'
#' @return A list of the same class as \code{object}.
#' @author Rob J Hyndman.
#' @seealso \code{\link{forecast.fdm}}, \code{\link{forecast.fdmpr}}
#' @examples
#' \dontrun{
#' france.fit <- fdm(fr.mort,order=2)
#' france.fcast <- forecast(france.fit,50)
#' # Replace first coefficient model with ARIMA(0,1,2)+drift
#' france.fcast$coeff[[2]] <- forecast(Arima(france.fit$coeff[,2],
#' order=c(0,1,2), include.drift=TRUE), h=50, level=80)
#' france.fcast <- update(france.fcast)
#'
#' fr.short <- extract.years(fr.sm,1950:2006)
#' fr.fit <- coherentfdm(fr.short)
#' fr.fcast <- forecast(fr.fit)
#' par(mfrow=c(1,2))
#' plot(fr.fcast$male)
#' # Replace first coefficient model in product component with a damped ETS model:
#' fr.fcast$product$coeff[[2]] <- forecast(ets(fr.fit$product$coeff[,2], damped=TRUE),
#' h=50, level=80)
#' fr.fcast <- update(fr.fcast)
#' plot(fr.fcast$male)
#' }
#' @keywords models
#' @name update
NULL
# Update fmforecast object
# Original object from forecast.fdm
# Assumed that the coefficient forecasts have been subsequently changed
# Object needs to be updated to reflect those changes.
#' @rdname update
#' @export
update.fmforecast <- function(object, ...)
{
if(!is.element("fmforecast",class(object)))
stop("object must be of class fmforecast")
h <- length(object$year)
nb <- ncol(object$model$basis)
adjust <- length(object$var$adj.factor) > 1
objnames <- dimnames(object$rate[[1]])
# Update in-sample fitted values and errors.
fitted <- matrix(NA,length(object$model$year),nb)
meanfcast <- varfcast <- matrix(NA, nrow = h, ncol = nb)
qconf <- stats::qnorm(0.5 + object$coeff[[2]]$level[1]/200)
fitted[,1] <- 1
meanfcast[,1] <- 1
varfcast[,1] <- 0
for(i in 2:nb)
{
fitted[,i] <- fitted(object$coeff[[i]]$model)
meanfcast[,i] <- object$coeff[[i]]$mean
varfcast[,i] <- ((object$coeff[[i]]$upper - object$coeff[[i]]$lower)/(2*qconf))^2
}
object$fitted$y <- object$model$basis %*% t(fitted)
object$error$y <- object$model$y$y - object$fitted$y
object$coeff.error <- object$model$coeff - fitted
# Update point forecasts
object$rate[[1]] <- object$model$basis %*% t(meanfcast)
dimnames(object$rate[[1]]) <- objnames
# Update forecast variances
# Only model variance should have changed
modelvar <- object$model$basis^2 %*% t(varfcast)
totalvar <- sweep(modelvar, 1, object$var$error + object$var$mean, "+")
if (adjust & nb > 1)
{
object$var$adj.factor <- rowMeans(object$error$y^2, na.rm = TRUE)/totalvar[,1]
totalvar <- sweep(totalvar, 1, object$var$adj.factor, "*")
}
# Add observational variance to total variance
object$var$total <- sweep(totalvar,1,object$var$observ,"+")
# Update forecast intervals
# Only parametric intervals computed here.
tmp <- qconf * sqrt(object$var$total)
object$rate$lower <- InvBoxCox(object$rate[[1]] - tmp, object$lambda)
object$rate$upper <- InvBoxCox(object$rate[[1]] + tmp, object$lambda)
object$rate[[1]] <- InvBoxCox(object$rate[[1]], object$lambda)
if(object$type != "migration")
{
object$rate[[1]] <- pmax(object$rate[[1]],0.000000001)
object$rate$lower <- pmax(object$rate$lower,0.000000001)
object$rate$lower[is.na(object$rate$lower)] <- 0
object$rate$upper <- pmax(object$rate$upper,0.000000001)
}
# Return updated object
return(object)
}
# Function to combine product and ratio forecasts
# object is output from forecast.fdmpr, but with modified forecasts
# This function simply recombines them again.
#' @rdname update
#' @export
update.fmforecast2 <- function(object, ...)
{
if(!is.element("fmforecast2",class(object)))
stop("object must be of class fmforecast2")
J <- length(object$ratio)
ny <- length(object$ratio[[1]]$year)
# GM model
object$product <- update(object$product)
# Obtain forecasts for each group
is.mortality <- (object$product$type=="mortality")
y <- as.numeric(is.mortality) #=1 for mortality and 0 for migration
for (j in 1:J)
{
object$ratio[[j]] <- update(object$ratio[[j]])
if(is.mortality)
object[[j]]$rate[[1]] <- object$product$rate$product * object$ratio[[j]]$rate[[1]]
else
object[[j]]$rate[[1]] <- object$product$rate$product + object$ratio[[j]]$rate[[1]]
if(is.mortality)
y <- y * object[[j]]$rate[[1]]
else
y <- y + object[[j]]$rate[[1]]
}
# Adjust forecasts so they multiply appropriately.
if(is.mortality)
{
y <- y^(1/J)/object$product$rate$product
for(j in 1:J)
object[[j]]$rate[[1]] <- object[[j]]$rate[[1]]/y
}
else
{
y <- y/J - object$product$rate$product
for(j in 1:J)
object[[j]]$rate[[1]] <- object[[j]]$rate[[1]]-y
}
# Variance of forecasts
qconf <- 2 * stats::qnorm(0.5 + object$product$coeff[[1]]$level/200)
for (j in 1:J)
{
vartotal <- object$product$var$total + object$ratio[[j]]$var$total
tmp <- qconf * sqrt(vartotal)
object[[j]]$rate$lower <- InvBoxCox(BoxCox(object[[j]]$rate[[1]],object$product$lambda) - tmp, object$product$lambda)
object[[j]]$rate$upper <- InvBoxCox(BoxCox(object[[j]]$rate[[1]],object$product$lambda) + tmp, object$product$lambda)
}
return(object)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.