| Type: | Package |
| Title: | Transmission Channel Analysis in Structural VAR Models |
| Version: | 1.0.3 |
| Date: | 2026-09-30 |
| Description: | Implements Transmission Channel Analysis (TCA) for structural vector autoregressive (SVAR) models following the methodology of Wegner, Lieb, Smeekes and Wilms (2025) <doi:10.48550/arXiv.2405.18987>. TCA decomposes impulse response functions (IRFs) into contributions from distinct transmission channels using a systems form representation and directed acyclic graph (DAG) path analysis. Supports overlapping channels, exhaustive 3-way and 4-way decompositions via inclusion-exclusion principle. This is a parallel R implementation of the 'tca-matlab-toolbox' (https://github.com/enweg/tca-matlab-toolbox). |
| License: | MIT + file LICENSE |
| URL: | https://github.com/muhammedalkhalaf/SVARtca |
| BugReports: | https://github.com/muhammedalkhalaf/SVARtca/issues |
| Encoding: | UTF-8 |
| RoxygenNote: | 7.3.2 |
| Depends: | R (≥ 3.5.0) |
| Imports: | Matrix, ggplot2, rlang |
| Suggests: | testthat (≥ 3.0.0), knitr, rmarkdown, vars |
| Config/testthat/edition: | 3 |
| NeedsCompilation: | no |
| Packaged: | 2026-09-30 23:09:58 UTC; root |
| Author: | Muhammad Alkhalaf |
| Maintainer: | Muhammad Alkhalaf <muhammedalkhalaf@gmail.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-10-01 08:30:27 UTC |
Transmission Channel Analysis in Structural VAR Models
Description
The SVARtca package implements Transmission Channel Analysis (TCA) for decomposing impulse response functions in structural vector autoregressive (SVAR) models. The package follows the methodology presented in Wegner, Lieb, Smeekes and Wilms (2025).
TCA enables researchers to decompose the total impulse response to a shock into contributions from different transmission channels. Supported channels include effects passing through specific intermediate variables, allowing analysts to distinguish direct effects from indirect effects that operate through identified transmission mechanisms.
Key features:
Multiple decomposition modes: overlapping, exhaustive 3-way, and exhaustive 4-way.
Support for VAR and SVAR models via integration with the vars package.
Visualization of channel contributions using ggplot2.
Diagnostic tools for validating decomposition accuracy.
Main Functions
tca_systems_formBuild the systems form representation (B and Omega matrices) from VAR coefficients and structural impact matrix.
tca_analyzeRun the main TCA analysis with specified decomposition mode.
tca_decompose_binaryDecompose IRF into "through" and "not_through" components for a single variable.
tca_validate_additivityValidate that the binary decomposition satisfies exact additivity.
tca_from_varConvenience wrapper to run TCA directly from a fitted VAR model object.
plot_tcaCreate publication-quality visualizations of channel contributions.
Identification
The package supports two identification schemes:
-
Cholesky: Lower-triangular Cholesky decomposition of the residual covariance matrix. Set
Phi0 = t(chol(Sigma)). -
Manual: User-supplied structural impact matrix for alternative identifications (e.g., sign restrictions, zero restrictions).
Citation
If you use the SVARtca package in your research, please cite the original methodology paper:
Wegner, E., Lieb, L., Smeekes, S. and Wilms, I. (2025). Transmission Channel Analysis in Dynamic Models. arXiv:2405.18987, doi:10.48550/arXiv.2405.18987. https://github.com/enweg/tca-matlab-toolbox
Author(s)
Muhammad Alkhalaf
References
Wegner, E., Lieb, L., Smeekes, S. and Wilms, I. (2025). Transmission Channel Analysis in Dynamic Models. arXiv:2405.18987, doi:10.48550/arXiv.2405.18987.
Plot TCA Channel Decomposition
Description
Creates a stacked bar chart (for exhaustive modes) or a line chart (for overlapping mode) showing channel contributions over horizons.
Usage
plot_tca(x, target = NULL, type = NULL, title = NULL,
colors = NULL)
Arguments
x |
A |
target |
Integer index of the response variable to plot (default: first variable after shock). |
type |
Plot type: |
title |
Custom plot title (optional). |
colors |
Named character vector of colours for channels (optional). |
Value
A ggplot object.
Examples
K <- 4
A1 <- matrix(c(0.7,-0.1,0.05,-0.05, -0.3,0.6,0.10,-0.10,
-0.2,0.1,0.70,0.05, -0.1,0.2,0.05,0.65), K, K, byrow=TRUE)
Sigma <- matrix(c(1,0.3,0.2,0.1, 0.3,1.5,0.25,0.15,
0.2,0.25,0.8,0.1, 0.1,0.15,0.1,0.6), K, K, byrow=TRUE)
Phi0 <- t(chol(Sigma))
sf <- tca_systems_form(Phi0, list(A1), h = 20)
res <- tca_analyze(from = 1, B = sf$B, Omega = sf$Omega,
intermediates = c(2, 4), K = K, h = 20,
order = 1:K, mode = "exhaustive_4way",
var_names = c("IntRate","GDP","Inflation","Wages"))
plot_tca(res, target = 3)
Print TCA Result
Description
S3 print method for tca_result objects. Displays a formatted
table of transmission channel contributions across horizons.
Usage
## S3 method for class 'tca_result'
print(x, target = NULL, ...)
Arguments
x |
A |
target |
Integer index (original ordering) of the response variable
to display. Default |
... |
Additional arguments (ignored). |
Value
Invisibly returns x.
Transmission Channel Analysis
Description
Decomposes impulse response functions into transmission channel contributions using the methodology of Wegner, Lieb, Smeekes and Wilms (2025), doi:10.48550/arXiv.2405.18987.
Three decomposition modes are supported:
"overlapping"Each channel is through(j) = total - not_through(j). Channels may overlap, so their sum may differ from the total.
"exhaustive_3way"(2 intermediates only) Non-overlapping: (1) through var1 inclusive, (2) through var2 only, (3) direct. Sum equals total.
"exhaustive_4way"(2 intermediates only) Full inclusion-exclusion: (1) var1 only, (2) var2 only, (3) both, (4) direct. Sum equals total.
Usage
tca_analyze(from, B, Omega, intermediates, K, h, order,
mode = "overlapping", var_names = NULL)
Arguments
from |
Shock variable number (1-based). |
B |
Systems form B matrix (from |
Omega |
Systems form Omega matrix. |
intermediates |
Integer vector of intermediate variable numbers (1-based, original ordering). |
K |
Number of variables. |
h |
Maximum horizon. |
order |
Transmission ordering vector. |
mode |
Decomposition mode: |
var_names |
Character vector of variable names (optional). |
Value
A list of class "tca_result" with components:
- irf_total
Matrix (h+1) x K of total IRFs.
- irf_channels
Named list of channel IRF matrices, each (h+1) x K.
- channel_names
Character vector of channel names.
- mode
Decomposition mode used.
- from
Shock variable number.
- K
Number of variables.
- h
Maximum horizon.
- order
Transmission ordering.
- var_names
Variable names.
References
Wegner, E., Lieb, L., Smeekes, S. and Wilms, I. (2025). Transmission Channel Analysis in Dynamic Models. arXiv:2405.18987, doi:10.48550/arXiv.2405.18987.
Examples
# Monetary policy model
K <- 4
A1 <- matrix(c(0.7,-0.1,0.05,-0.05, -0.3,0.6,0.10,-0.10,
-0.2,0.1,0.70,0.05, -0.1,0.2,0.05,0.65), K, K, byrow=TRUE)
Sigma <- matrix(c(1,0.3,0.2,0.1, 0.3,1.5,0.25,0.15,
0.2,0.25,0.8,0.1, 0.1,0.15,0.1,0.6), K, K, byrow=TRUE)
Phi0 <- t(chol(Sigma))
sf <- tca_systems_form(Phi0, list(A1), h = 20)
result <- tca_analyze(from = 1, B = sf$B, Omega = sf$Omega,
intermediates = c(2, 4), K = K, h = 20,
order = 1:K, mode = "exhaustive_4way",
var_names = c("IntRate","GDP","Inflation","Wages"))
print(result)
Binary Decomposition: Total = Through + Not-Through
Description
Decomposes the total IRF into the effect passing through a variable
and the effect not passing through it. The not-through effect is
obtained by blocking every node of the variable (NOT condition) and the
through effect is defined as total - not_through, so the three
matrices satisfy total = through + not_through by construction.
Use tca_validate_additivity to check the decomposition
against an independent computation of the through effect.
Usage
tca_decompose_binary(from, B, Omega, var_idx, K, h, order)
Arguments
from |
Shock variable (1-based). |
B |
Systems form B matrix. |
Omega |
Systems form Omega matrix. |
var_idx |
Variable to decompose through (1-based). |
K |
Number of variables. |
h |
Maximum horizon. |
order |
Transmission ordering. |
Value
A list with matrices total, through,
not_through (each (h+1) x K).
Run TCA from a VAR Estimation Object
Description
Extracts coefficient matrices and residual covariance from a fitted VAR model (from the vars package) and runs TCA.
Usage
tca_from_var(var_model, from, intermediates, h = 20,
order = NULL, mode = "overlapping",
identification = "cholesky", Phi0 = NULL)
Arguments
var_model |
A fitted VAR model object from |
from |
Shock variable (integer or name). |
intermediates |
Integer vector or character vector of intermediate variable names. |
h |
Maximum horizon (default: 20). |
order |
Transmission ordering (default: variable ordering in the VAR). |
mode |
Decomposition mode: |
identification |
Identification scheme: |
Phi0 |
Manual impact matrix. Required if |
Value
A tca_result object (see tca_analyze).
Examples
library(vars)
data(Canada)
var_est <- VAR(Canada, p = 2, type = "const")
result <- tca_from_var(var_est, from = "e",
intermediates = c("prod", "rw"),
h = 20, mode = "exhaustive_4way")
plot_tca(result, target = "U")
Build Complete Systems Form
Description
Constructs both B and Omega matrices for the systems form representation x = Bx + Omega*epsilon, following the methodology of Wegner, Lieb, Smeekes and Wilms (2025).
Usage
tca_systems_form(Phi0, As, h, order = NULL, Psis = NULL)
Arguments
Phi0 |
Structural impact matrix (K x K). For Cholesky
identification, use |
As |
List of VAR coefficient matrices (A_1, A_2, ..., A_p). |
h |
Maximum IRF horizon. |
order |
Transmission ordering vector (default: |
Psis |
Optional list of reduced-form MA coefficient matrices
(Psi_1, ..., Psi_q), each K x K, for VARMA or DSGE models. See
Details. Default |
Details
Note on Psis. For a pure VAR or SVAR model leave
Psis at its default (NULL, treated as an empty list): the
moving-average dynamics are generated by (I - B)^{-1}. Only
VARMA or DSGE models with a moving-average component pass Psis.
The matrices in Psis must be the reduced-form MA
coefficient matrices, that is, the coefficients on the lagged
reduced-form errors u_t = Phi0 %*% epsilon_t in
y_t = A_1 y_{t-1} + ... + u_t + Psi_1 u_{t-1} + .... If the model
is written with structural MA matrices on the structural shocks,
y_t = ... + Phi0 %*% (epsilon_t + Psi^s_1 epsilon_{t-1} + ...),
convert them first: Psi_j = Phi0 %*% Psi^s_j %*% solve(Phi0).
Passing the structural matrices directly gives wrong impulse responses
at horizons 1 and above, because makeOmega_systems multiplies
each Psi_j by Phi0 on the right, so that
Psi_j %*% Phi0 is the horizon-j structural MA coefficient.
Value
A list with components:
- B
Systems form B matrix (K*(h+1) x K*(h+1)).
- Omega
Systems form Omega matrix (K*(h+1) x K*(h+1)).
References
Wegner, E., Lieb, L., Smeekes, S. and Wilms, I. (2025). Transmission Channel Analysis in Dynamic Models. arXiv:2405.18987, doi:10.48550/arXiv.2405.18987. https://github.com/enweg/tca-matlab-toolbox
Examples
# 2-variable VAR(1)
Phi0 <- matrix(c(1, 0.3, 0, 0.95), 2, 2)
As <- list(matrix(c(0.5, -0.1, 0.2, 0.4), 2, 2))
sf <- tca_systems_form(Phi0, As, h = 10)
dim(sf$B) # 22 x 22
Validate Binary Additivity
Description
Checks Theorem 2(ii) of Wegner, Lieb, Smeekes and Wilms (2025): the
effects of disjoint transmission channels sum to the total effect.
For every variable j, the effect of the paths passing through
j (at any horizon) is computed independently of the identity
through = total - not_through, by partitioning those paths by the
first node of j they visit and summing the AND-conditioned
effects of the parts (see tca_analyze for the AND and NOT
conditions). This independent through effect plus the NOT-conditioned
not-through effect is then compared with the total effect. The residual
is evaluated at all response variables other than j itself,
because the AND condition sets the effect on the conditioning node to
zero while the effect on j counts entirely as "through j"
in the total - not_through convention.
If pair is given, the inclusion-exclusion identity used by the
"exhaustive_4way" mode of tca_analyze,
through(v1 and v2) = through(v1) + through(v2) - through(v1 or v2),
is also checked: the left-hand side is computed directly with AND
conditions on both variables (a double first-passage sum of
(h+1)^2 linear solves, so keep h moderate), the right-hand
side from the independent single-variable through effects and
total - not_through(v1, v2). The residual is evaluated at all
response variables other than v1 and v2.
The function also reports whether B is strictly lower triangular
(entries on and above the diagonal at most 1e-12 times the
largest absolute entry), which the systems form requires for the graph
to be acyclic. Before
version 1.0.3 the residual was computed as
total - ((total - not_through) + not_through), which is zero by
construction and could not detect any error.
Usage
tca_validate_additivity(from, B, Omega, K, h, order,
var_names = NULL, verbose = TRUE, pair = NULL, tol = 1e-10)
Arguments
from |
Shock variable (1-based). |
B |
Systems form B matrix. |
Omega |
Systems form Omega matrix. |
K |
Number of variables. |
h |
Maximum horizon. |
order |
Transmission ordering. |
var_names |
Character vector of variable names (optional). |
verbose |
Logical; print results? Default |
pair |
Optional integer vector of two distinct variable numbers (1-based) for which the inclusion-exclusion identity is checked. |
tol |
Tolerance for the maximum absolute residual. Default
|
Value
Invisibly returns a logical, TRUE if B is strictly
lower triangular and every residual is below tol, with
attributes residuals (named numeric vector, the maximum absolute
additivity residual for each variable), pair_residual (the
maximum absolute inclusion-exclusion residual, or NA if
pair is NULL), max_residual (the largest of these)
and lower_triangular (logical).
References
Wegner, E., Lieb, L., Smeekes, S. and Wilms, I. (2025). Transmission Channel Analysis in Dynamic Models. arXiv:2405.18987, doi:10.48550/arXiv.2405.18987.
Examples
Phi0 <- matrix(c(1, 0.3, 0, 0.95), 2, 2)
As <- list(matrix(c(0.5, -0.1, 0.2, 0.4), 2, 2))
sf <- tca_systems_form(Phi0, As, h = 5)
ok <- tca_validate_additivity(1, sf$B, sf$Omega, K = 2, h = 5,
order = 1:2, pair = c(1, 2))
attr(ok, "max_residual")
# A backward edge breaks the acyclic structure and is detected
Bc <- sf$B; Bc[1, 4] <- 0.2
tca_validate_additivity(1, Bc, sf$Omega, K = 2, h = 5, order = 1:2)