Compute the Banbura and Modugno (2014) news decomposition of forecast updates.
Given an old vintage and an updated vintage, the function decomposes the
forecast revision at t.fcst into contributions from new releases.
Usage
news(object, ...)
# S3 method for class 'dfm'
news(
object,
comparison,
t.fcst = nrow(object$X_imp),
target.vars = NULL,
series = NULL,
standardized = FALSE,
...
)
# S3 method for class 'dfm_news'
print(x, digits = 4L, ...)
# S3 method for class 'dfm_news_list'
print(x, digits = 4L, ...)
# S3 method for class 'dfm_news_list'
x$name
# S3 method for class 'dfm_news_list'
x[[i]]
# S3 method for class 'dfm_news_list'
x[i]
# S3 method for class 'dfm_news_list'
as.data.frame(x, ...)Arguments
- object
a
dfmobject for the old vintage.- ...
not used.
- comparison
a
dfmobject or a new dataset for the updated vintage.- t.fcst
integer. Forecast target time index.
- target.vars
Integer or character identifying target variables. Defaults to all variables.
- series
optional character vector for naming variables.
- standardized
logical. Return results on standardized scale?
- x
an object of class 'dfm_news' or 'dfm_news_list'.
- digits
integer. Number of digits to print.
- name
character. Element name.
- i
index. Element position or name.
Value
For a single target, a dfm_news object with elements:
y_old: old forecast for the target variable att.fcst.y_new: new forecast for the target variable att.fcst.news_df: data frame with one row per series and columns:series: series name.actual: actual release (if any).forecast: old-vintage forecast of the release.news: total innovation for the series on the output scale. If there is a single release,newsequalsactual - forecast. With multiple releases,newsaggregates those innovations for the series.gain: effective weight onnewssuch thatimpact = news * gain(on the output scale).gain_std: effective weight on the standardized innovations.impact: contribution of the series to the target revision.
If target.vars selects multiple targets, a dfm_news_list object is returned,
where each element is a dfm_news object and list names correspond to targets.
Details
Let \(y_t^{old}\) and \(y_t^{new}\) be the old and new forecasts of a target series at \(t = t_{fcst}\). For each new release \(i\) (a previously missing observation that becomes observed), the innovation is $$\nu_i = x_i^{new} - \hat{x}_i^{old},$$ where \(\hat{x}_i^{old}\) is the smoothed estimate from the old vintage. The revision is decomposed as $$y_t^{new} - y_t^{old} = \sum_i g_i \nu_i,$$ with gain weights computed from Kalman smoother covariances: $$g = \sigma_y C_y P_1 P_2^{-1}.$$ Here \(\sigma_y\) is the target series standard deviation, \(C_y\) is the loading row for the target series, \(P_1\) collects cross-covariances between the target and each news item, and \(P_2\) is the covariance matrix of the news items (including measurement error where appropriate). See Section 2.3 and Appendix D in Banbura and Modugno (2014).
The function uses the system matrices and scaling from the new vintage. The old
data are re-standardized to the new-vintage scale before smoothing so that
innovations and gains are computed on a consistent scale. Set
standardized = FALSE to report results on the original data scale.
Note
This implementation is translated from the original MATLAB codes and is
consistent with the BM2014 news decomposition formulas.
If the model was estimated with max.missing < 1 and
na.rm.method = "LE" in tsnarmimp (called by DFM()), leading or trailing rows with many missing values
may be removed by DFM(). If old and new vintages are both dfm objects, and they drop different rows,
then t.fcst can become out of bounds. When comparison is provided
as raw data, news() drops object$rm.rows from the new dataset (if present) and
forces max.missing = 1 for the re-estimation call to keep row alignment.
To avoid issues, estimate both vintages with max.missing = 1.
For mixed-frequency or idiosyncratic AR(1) models, news() relies on the full
state-space matrices stored in dfm$ss_full.
References
Banbura, M., & Modugno, M. (2014). Maximum likelihood estimation of factor models on datasets with arbitrary pattern of missing data. Journal of Applied Econometrics, 29(1), 133-160.
Examples
# \donttest{
# (1) Monthly DFM example
X <- collapse::qM(BM14_M)[, BM14_Models$medium[BM14_Models$freq == "M"]]
X_old <- X
# Creating earlier vintage
X_old[nrow(X) - 1, sample(which(is.finite(X[nrow(X) - 1, ]) & is.na(X[nrow(X), ])), 5)] <- NA
X_old[nrow(X), sample(which(is.finite(X[nrow(X), ])), 5)] <- NA
# Estimating DFM
dfm <- DFM(X_old, r = 2, p = 2, em.method = "none")
# News computation (second DFM fit internally with same settings and rows)
res <- news(dfm, X, target.vars = c("ip_tot_cstr", "orders", "urx"))
# See results
print(res)
#> DFM News (Multiple Targets)
#> Target time: 357
#> Targets: 3
#> Standardized: FALSE
#> y_old y_new revision
#> ip_tot_cstr 94.3574 94.7225 0.3650
#> orders 96.6193 96.9593 0.3401
#> urx 8.7623 8.7335 -0.0288
head(res$news_df)
#> NULL
# (2) MQ nowcast of GDP (idio.ar1 = FALSE for speed)
library(magrittr)
library(xts)
# Creating MQ dataset
BM14 <- merge(BM14_M, BM14_Q)
BM14[, BM14_Models$log_trans] %<>% log()
BM14[, BM14_Models$freq == "M"] %<>% diff()
BM14[, BM14_Models$freq == "Q"] %<>% diff(3)
X <- BM14[-1, BM14_Models$small]
quarterly.vars <- BM14_Models$series[BM14_Models$small & BM14_Models$freq == "Q"]
# Creating earlier vintage
X_old <- X
X_old[355, c("ip_tot_cstr", "new_cars")] <- NA
X_old[356, c("new_cars", "pms_pmi", "euro325", "capacity")] <- NA
# Estimating DFM
dfm <- DFM(X_old, r = 2, p = 2, quarterly.vars = quarterly.vars, max.missing = 1)
#> Converged after 26 iterations.
# News computation (second DFM fit internally with same settings and rows)
res_mq <- news(dfm, X, t.fcst = 356, target.vars = "gdp")
#> Converged after 26 iterations.
# See results
print(res_mq)
#> DFM News
#> Target variable: gdp
#> Target time: 356
#> Old forecast: 0.0064
#> New forecast: 0.0062
#> Revision: -2e-04
#> Standardized: FALSE
head(res_mq$news_df)
#> series actual forecast news gain
#> 1 ip_tot_cstr 0.009399179 0.006538173 0.002861006 0.0218073085
#> 2 new_cars -0.008605272 0.004274292 -0.008834552 0.0002129116
#> 3 orders NA NA 0.000000000 0.0000000000
#> 4 ret_turnover_defl NA NA 0.000000000 0.0000000000
#> 5 ecs_ec_sent_ind NA NA 0.000000000 0.0000000000
#> 6 pms_pmi 1.050000000 2.120030865 -1.070030865 0.0001220146
#> gain_std impact
#> 1 2.022429e-04 6.239084e-05
#> 2 1.071131e-05 -1.880979e-06
#> 3 0.000000e+00 0.000000e+00
#> 4 0.000000e+00 0.000000e+00
#> 5 0.000000e+00 0.000000e+00
#> 6 1.586910e-04 -1.305593e-04
# }
