id.iv: Identification of SVAR models by means of proxy variables

View source: R/id.R

id.ivR Documentation

Identification of SVAR models by means of proxy variables

Description

Given an estimated VAR model, this function uses proxy variables to partially identify the structural impact matrix B of the corresponding SVAR model

y_{t} = c_{t} + A_{1} y_{t-1} + ... + A_{p} y_{t-p} + u_{t}

= c_{t} + A_{1} y_{t-1} + ... + A_{p} y_{t-p} + B \epsilon_{t}.

In general, identification procedures determine B up to column ordering, scale, and sign. For a unique solution, id.iv follows the literature on proxy SVAR. The S columns in B = [B_1 : B_2] of the identified shocks \epsilon_{ts}, s=1,\ldots,S, are ordered first, and the variance \sigma^2_{\epsilon,s} = 1 is normalized to unity (see e.g. Lunsford 2015:6, Eq. 9). Further, the sign is fixed to a positive correlation between proxy and shock series. A normalization of the impulsed shock that may fix the size of the impact response in the IRF can be imposed subsequently via 'normf' in irf.varx and sboot.mb.

Usage

id.iv(x, iv, S2 = c("MR", "JL", "NQ"), cov_u = "OMEGA", R0 = NULL)

Arguments

x

VAR object of class 'varx' or any other that will be coerced to 'varx'.

iv

Matrix. A (L \times T) data matrix of the L proxy time series m_t.

S2

Character. Identification within multiple proxies m_t via 'MR' for lower-triangular [I_S : -B_{11} B_{12}^{-1} ] B_{1} by Mertens, Ravn (2013), via 'JL' for chol(\Sigma_{mu} \Sigma_{u}^{-1} \Sigma_{um}) by Jentsch, Lunsford (2021), or via 'NQ' for the nearest orthogonal matrix from svd decomposition by Empting et al. (2025). In case of S=L=1 proxy, all three choices provide identical results on B_1.

cov_u

Character. Selection of the estimated residual covariance matrix \hat{\Sigma}_{u} to be used in the identification procedure. Either 'OMEGA' (the default) for \hat{U} \hat{U}'/T_i as used in Mertens, Ravn (2013) and Jentsch, Lunsford (2021) or 'SIGMA' for \hat{U}\hat{U}'/(T-n_{z}), which corrects for the number of regressors n_z. Both character options refer to the name of the respective estimate in the 'varx' object.

R0

Matrix. A (L \times S) selection matrix for 'NQ' that governs the attribution of the L proxies to their specific S structural shock series. If NULL (the default), R0 = I_S will be used such that the S=L columns of B_1 are one-by-one estimated from the S=L proxy series 'iv' available.

Value

List of class 'id'.

References

Mertens, K., and Ravn, M. O. (2013): "The Dynamic Effects of Personal and Corporate Income Tax Changes in the United States", American Economic Review, 103, pp. 1212-1247.

Lunsford, K. G. (2015): "Identifying Structural VARs with a Proxy Variable and a Test for a Weak Proxy", Working Paper, No 15-28, Federal Reserve Bank of Cleveland.

Jentsch, C., and Lunsford, K. G. (2019): "The Dynamic Effects of Personal and Corporate Income Tax Changes in the United States: Comment", American Economic Review, 109, pp. 2655-2678.

Jentsch, C., and Lunsford, K. G. (2021): "Asymptotically Valid Bootstrap Inference for Proxy SVARs", Journal of Business and Economic Statistics, 40, pp. 1876-1891.

Empting, L. F. T., Maxand, S., Oeztuerk, S., and Wagner, K. (2025): "Inference in Panel SVARs with Cross-Sectional Dependence of Unknown Form".

See Also

... the individual identification approaches by Lange et al. (2021) in svars.

Other identification functions: id.grt()

Examples

### reproduce Jentsch,Lunsford 2019:2668, Ch.III ###
data("PCIT")
names_k = c("APITR", "ACITR", "PITB", "CITB", "GOV", "RGDP", "DEBT")
names_l = c("m_PI", "m_CI")  # proxy names
names_s = paste0("epsilon[ ", c("PI", "CI"), " ]")  # shock names
dim_p   = 4  # lag-order

# estimate and identify under ordering "BLUE" of Fig.1 and 2 #
R.vars = vars::VAR(PCIT[ , names_k], p=dim_p, type="const")
R.idBL = id.iv(R.vars, iv=PCIT[-(1:dim_p), names_l], S2="MR", cov_u="OMEGA")
colnames(R.idBL$B) = names_s  # labeling

# estimate and identify under ordering "RED" of Fig.1 and 2 #
R.vars = vars::VAR(PCIT[ , names_k[c(2:1, 3:7)]], p=dim_p, type="const")
R.idRD = id.iv(R.vars, iv=PCIT[-(1:dim_p),names_l[2:1]], S2="MR", cov_u="OMEGA")
colnames(R.idRD$B) = names_s[2:1]  # labeling


# select minimal or full example #
is_min = TRUE
n.boot = ifelse(is_min, 5, 10000)

# bootstrap both under 1%-response normalization #
set.seed(2389)
R.norm = function(B) B / matrix(-diag(B), nrow(B), ncol(B), byrow=TRUE)
R.sbBL = sboot.mb(R.idBL, b.length=19, n.boot=n.boot, normf=R.norm)
R.sbRD = sboot.mb(R.idRD, b.length=19, n.boot=n.boot, normf=R.norm)

# plot IRF of Fig.1 and 2 with 68%-confidence levels #
library("ggplot2")
L.idx = list(BLUE1=c(1, 11, 5, 7, 3,  9)+0.1,
             RED1 =c(4, 12, 6, 8, 2, 10)+0.1, 
             RED2 =c(1, 11, 7, 5, 3,  9)+0.1, 
             BLUE2=c(4, 12, 8, 6, 2, 10)+0.1)
# Indexes to subset and reorder sub-plots in plot.sboot(), where 
# the 14 IRF-subplots in the 2D-panel are numbered as a 1D-sequence 
# vectorized by row. '+0.1' makes sub-setting robust against 
# truncation errors from as.integer(). In a given figure, the plots
# RED and BLUE display the same selection of IRF-subplots. 

R.fig1 = as.pplot(
 BLUE=plot(R.sbBL, lowerq=0.16, upperq=0.84, selection=list(1, L.idx[[1]])),
 RED =plot(R.sbRD, lowerq=0.16, upperq=0.84, selection=list(1, L.idx[[2]])),
 names_g=c("APITR first", "ACITR first"), color_g=c("blue", "red"), n.rows=3)

R.fig2 = as.pplot(
 RED =plot(R.sbRD, lowerq=0.16, upperq=0.84, selection=list(1, L.idx[[3]])), 
 BLUE=plot(R.sbBL, lowerq=0.16, upperq=0.84, selection=list(1, L.idx[[4]])),
 names_g=c("ACITR first", "APITR first"), color_g=c("red", "blue"), n.rows=3)

R.fig1$F.plot + labs(x="Quarters", color="Ordering", fill="Ordering")
R.fig2$F.plot + labs(x="Quarters", color="Ordering", fill="Ordering")



pvars documentation built on Nov. 5, 2025, 6:57 p.m.