| Title: | Penalized Estimation of Multiple-Subject Vector Autoregressive Models |
|---|---|
| Description: | Simulate, estimate, and forecast vector autoregressive (VAR) models for multiple-subject data using structured penalization. Decomposes dynamics into shared (common) and subject-specific (unique) components via adaptive LASSO with FISTA optimization. Supports cross-validation and extended BIC model selection and subgroup detection, and time-varying parameters. |
| Authors: | Zachary Fisher [aut, cre], Christopher Crawford [aut], Younghoon Kim [ctb], Vladas Pipiras [ctb] |
| Maintainer: | Zachary Fisher <[email protected]> |
| License: | GPL (>= 2) |
| Version: | 1.4.0 |
| Built: | 2026-06-04 07:15:10 UTC |
| Source: | https://github.com/cran/multivar |
Simulate, estimate, and forecast vector autoregressive (VAR) models for multiple-subject data using structured penalization. Decomposes dynamics into shared (common) and subject-specific (unique) components via adaptive LASSO with FISTA optimization. Supports cross-validation and extended BIC model selection and subgroup detection, and time-varying parameters.
multivar is an R package for simulating, estimating and forecasting stationary Vector Autoregressive (VAR) models for multiple subject data using the penalized multi-VAR framework.
Maintainer: Zachary Fisher [email protected]
Authors:
Christopher Crawford
Other contributors:
Younghoon Kim [contributor]
Vladas Pipiras [contributor]
Creates a specification object that defines the column and row structure of the design matrix A. This is the single source of truth for all downstream functions that need to know column indices.
build_matrix_spec( k, d, n, tvp = FALSE, common_effects = TRUE, subgroup = FALSE, common_tvp_effects = FALSE, breaks = NULL, subgroup_membership = NULL )build_matrix_spec( k, d, n, tvp = FALSE, common_effects = TRUE, subgroup = FALSE, common_tvp_effects = FALSE, breaks = NULL, subgroup_membership = NULL )
k |
Integer. Number of subjects. |
d |
Integer. Number of variables. |
n |
Integer vector. Timepoints per subject (length k). |
tvp |
Logical. Whether time-varying parameters are used. |
common_effects |
Logical. Whether common effects are included. |
subgroup |
Logical. Whether subgroup structure is present. |
common_tvp_effects |
Logical. Whether common TVP effects are included. |
breaks |
List. Period definitions for TVP models (length k). |
subgroup_membership |
Integer vector. Subgroup assignments (length k). |
The design matrix A has the following column structure depending on model type:
k=1, non-TVP:
[d columns]
k=1, TVP, common_effects=TRUE:
[d common | d*P unique_tvp]
k=1, TVP, common_effects=FALSE:
[d*P unique_tvp]
k>1, non-TVP, no subgroup:
[d common | d unique_1 | ... | d unique_k]
k>1, non-TVP, with subgroup:
[d common | d subgrp_1 | ... | d subgrp_S | d unique_1 | ... | d unique_k]
k>1, TVP, common_effects=TRUE, common_tvp_effects=TRUE:
[d common | d unique_1 | ... | d unique_k | d*P common_tvp | d*P unique_tvp_1 | ... | d*P unique_tvp_k]
A list with class "matrix_spec" containing:
params: Model parameters (k, d, n, flags)
cols: Column index ranges for each effect type
rows: Row index ranges for subjects and periods
This matches the logic in est_base_weight_mat(): we expand ratios_unique, and (optionally) ratios_subgroup and ratios_unique_tvp into a list of S scenarios, where S = dim(W)[3].
build_scenario_table(object)build_scenario_table(object)
object |
multivar object built using |
Canonical VAR Fitting Function for multivar
canonical.multivar(object)canonical.multivar(object)
object |
multivar object built using |
A function to fit a canonical VAR model to each individual dataset.
A list of results.
# example 1 (run) sim1 <- multivar_sim( k = 2, # individuals d = 5, # number of variables n = 20, # number of timepoints prop_fill_com = 0.1, # proportion of paths common prop_fill_ind = 0.05, # proportion of paths unique lb = 0.1, # lower bound on coefficient magnitude ub = 0.5, # upper bound on coefficient magnitude sigma = diag(5) # noise ) model1 <- constructModel(data = sim1$data, weightest = "ols") fit1 <- canonical.multivar(model1)# example 1 (run) sim1 <- multivar_sim( k = 2, # individuals d = 5, # number of variables n = 20, # number of timepoints prop_fill_com = 0.1, # proportion of paths common prop_fill_ind = 0.05, # proportion of paths unique lb = 0.1, # lower bound on coefficient magnitude ub = 0.5, # upper bound on coefficient magnitude sigma = diag(5) # noise ) model1 <- constructModel(data = sim1$data, weightest = "ols") fit1 <- canonical.multivar(model1)
Core computation of the Extended Bayesian Information Criterion (EBIC)
for each scenario in a beta array. Used internally by cv.multivar
when selection = "ebic" and by select_by_ebic for post-hoc
reselection.
compute_ebic(beta_array, Z, Y, d, gamma = 0.5, spec = NULL)compute_ebic(beta_array, Z, Y, d, gamma = 0.5, spec = NULL)
beta_array |
3D array (d x p x n_scenarios) of fitted coefficients. |
Z |
Design matrix (transposed), p x n. |
Y |
Response matrix (transposed), d x n. |
d |
Number of response variables. |
gamma |
EBIC tuning parameter. |
spec |
Optional matrix_spec object. When provided, degrees of freedom are counted per coefficient position within each block (common, unique, TVP), following Chen & Chen (2008). Each d x d position that has any nonzero entry counts as one degree of freedom, regardless of how many subjects share that position. This avoids over-penalizing shared structure. When NULL, falls back to raw nonzero counting. |
With spec = NULL (legacy behavior), EBIC counts every nonzero entry
in B as one degree of freedom:
With a spec object, degrees of freedom are counted per position:
for each d x d coefficient position (i,j), the position contributes 1 df
if any block (common, any unique, any TVP) has a nonzero entry at that
position. The eBIC extension uses p = d (predictors per equation)
instead of the full design matrix width, and employs the Chen & Chen (2008)
lchoose(p, df) formulation per equation.
Numeric vector of EBIC values, one per scenario.
Construct an object of class multivar
constructModel( data = NULL, lag = 1, horizon = 0, t1 = NULL, t2 = NULL, lambda1 = NULL, nlambda1 = 30, n_ratios_subgroup = 30, depth = NULL, tol = 1e-04, window = 1, standardize = TRUE, weightest = "maity", canonical = FALSE, threshold = FALSE, lassotype = "adaptive", intercept = FALSE, W = NULL, ratios_unique = NULL, ratios_subgroup = NULL, ratios_unique_tvp = NULL, cv = "blocked", nfolds = 10, lamadapt = FALSE, subgroup_membership = NULL, subgroup = FALSE, B = NULL, pendiag = TRUE, tvp = FALSE, inittvpcoefs = list(), breaks = list(), lambda_choice = "lambda.min", common_effects = TRUE, common_tvp_effects = NULL, save_beta = TRUE, ncores = 1, max_grid_size = NULL, eps = 0.001, warmstart = TRUE, stopping_crit = "absolute", selection = "cv", ebic_gamma = 0.5, weight_type = "standard", maity_opts = list() )constructModel( data = NULL, lag = 1, horizon = 0, t1 = NULL, t2 = NULL, lambda1 = NULL, nlambda1 = 30, n_ratios_subgroup = 30, depth = NULL, tol = 1e-04, window = 1, standardize = TRUE, weightest = "maity", canonical = FALSE, threshold = FALSE, lassotype = "adaptive", intercept = FALSE, W = NULL, ratios_unique = NULL, ratios_subgroup = NULL, ratios_unique_tvp = NULL, cv = "blocked", nfolds = 10, lamadapt = FALSE, subgroup_membership = NULL, subgroup = FALSE, B = NULL, pendiag = TRUE, tvp = FALSE, inittvpcoefs = list(), breaks = list(), lambda_choice = "lambda.min", common_effects = TRUE, common_tvp_effects = NULL, save_beta = TRUE, ncores = 1, max_grid_size = NULL, eps = 0.001, warmstart = TRUE, stopping_crit = "absolute", selection = "cv", ebic_gamma = 0.5, weight_type = "standard", maity_opts = list() )
data |
List. A list (length = k) of T by d multivariate time series |
lag |
Numeric. The VAR order. Default is 1. |
horizon |
Numeric. Desired forecast horizon. Default is 1. |
t1 |
Numeric. Index of time series in which to start cross validation. If NULL, default is floor(nrow(n)/3) where nk is the time series length for individual k. |
t2 |
Numeric. Index of times series in which to end cross validation. If NULL, default is floor(2*nrow(n)/3) where nk is the time series length for individual k. |
lambda1 |
Matrix. Regularization parameter grid. Default is NULL (auto-generated). |
nlambda1 |
Numeric. Number of lambda1 values to search over. Default is 30. |
n_ratios_subgroup |
Numeric. Number of ratios_subgroup values to search over. Default is 30. |
depth |
Numeric. Depth of lambda1 grid construction (lambda_min = lambda_max / depth). Default is 10000. |
tol |
Numeric. Optimization tolerance (default 1e-4). |
window |
Numeric. Size of rolling window. |
standardize |
Logical. Default is true. Whether to standardize the individual data. Note, if intercept = TRUE and standardize = TRUE, the data is scaled but not de-meaned. |
weightest |
Character. How to estimate initial coefficients for adaptive weights. Default is "maity". Other options include "lasso", "alasso" (adaptive LASSO: two-stage procedure using LASSO pilot then adaptive reweighting for sparser estimates), "ridge", "ols", and "multivar". The "multivar" option fits a standard lasso multivar model first to get structured initial estimates. Note: for k=1 TVP models, "multivar" works well with common_effects=TRUE but not with common_effects=FALSE (use "lasso" instead). Only used when lassotype = "adaptive" (ignored for standard LASSO). |
canonical |
Logical. Default is false. If true, individual datasets are fit to a VAR(1) model. |
threshold |
Logical. Default is false. If true, and canonical is true, individual transition matrices are thresholded based on significance. |
lassotype |
Character. Default is "adaptive". Choices are "standard" or "adaptive" lasso. |
intercept |
Logical. Default is FALSE. |
W |
Matrix. Default is NULL. |
ratios_unique |
Numeric vector. Penalty ratio for unique effects. Default is NULL. |
ratios_subgroup |
Numeric vector. Penalty ratio for subgroup effects. Default is NULL. |
ratios_unique_tvp |
Numeric vector. Default is NULL. |
cv |
Character. Default is "blocked" for blocked folds cross-validation. "rolling" is also available for rolling window cross-validation. If "blocked" is selected the nfolds argument should be specified. |
nfolds |
Numeric. The number of folds for use with "blocked" cross-validation. |
lamadapt |
Logical. Should the lambdas be calculated adaptively. Default is FALSE. |
subgroup_membership |
Numeric. Vector of subgroup assignments. |
subgroup |
Logical. Internal argument whether to run subgrouping algorithm. |
B |
Matrix. Default is NULL. |
pendiag |
Logical. Logical indicating whether autoregressive parameters should be penalized. Default is TRUE. |
tvp |
Logical. Default is FALSE. |
inittvpcoefs |
List. |
breaks |
List. A list of length K indicating structural breaks in the time series. |
lambda_choice |
Character. Which lambda to use for initial coefficient estimation: "lambda.min" (default) or "lambda.1se". lambda.min provides better coefficient recovery, especially for small samples and TVP models; lambda.1se may be too conservative, causing all-zero initial estimates. |
common_effects |
Logical. Whether to include common effects in TVP models. Only applies when tvp = TRUE. Default is TRUE (include common effects). When FALSE, the model becomes Total = Unique + TVP instead of Total = Common + Unique + TVP. This can be useful when you expect no shared dynamics across subjects. |
common_tvp_effects |
Logical. Whether to include time-varying common effects in TVP models. Default is NULL, which automatically sets to TRUE when tvp = TRUE and FALSE when tvp = FALSE. Only meaningful when tvp = TRUE. |
save_beta |
Logical. Whether to retain the full beta coefficient array in the cv.multivar result. Default is TRUE. Set to FALSE to reduce memory usage when only the best-model coefficients (in mats) are needed. |
ncores |
Numeric. Number of cores for parallel cross-validation. Default is 1. |
max_grid_size |
Numeric. Maximum number of hyperparameter combinations. If the full grid exceeds this, dimensions are coarsened proportionally. Default is NULL (no limit). |
eps |
Numeric. FISTA convergence tolerance. Default is 1e-3. Smaller values yield more precise solutions but increase computation time. |
warmstart |
Logical. Whether to use the previous lambda's solution as the starting point for the next lambda in the FISTA solver. Default is TRUE. Reduces computation time with negligible effect on accuracy. |
stopping_crit |
Character. FISTA convergence criterion. One of "absolute" (default), "relative", or "objective". "absolute" checks max|B_new - B_old| < eps; "relative" normalizes by max|B_old|; "objective" checks relative change in the objective function. |
selection |
Character. Model selection criterion. |
ebic_gamma |
Numeric. EBIC tuning parameter, used when |
weight_type |
Character. Adaptive weight function type. |
maity_opts |
List. Options for Maity et al. (2022) MrLasso initial estimation. Supports |
sim <- multivar_sim( k = 2, # individuals d = 3, # number of variables n = 20, # number of timepoints prop_fill_com = 0.1, # proportion of paths common prop_fill_ind = 0.1, # proportion of paths unique lb = 0.1, # lower bound on coefficient magnitude ub = 0.9, # upper bound on coefficient magnitude sigma = diag(3) # noise ) plot_sim(sim, plot_type = "common") model <- constructModel(data = sim$data, weightest = "ols")sim <- multivar_sim( k = 2, # individuals d = 3, # number of variables n = 20, # number of timepoints prop_fill_com = 0.1, # proportion of paths common prop_fill_ind = 0.1, # proportion of paths unique lb = 0.1, # lower bound on coefficient magnitude ub = 0.9, # upper bound on coefficient magnitude sigma = diag(3) # noise ) plot_sim(sim, plot_type = "common") model <- constructModel(data = sim$data, weightest = "ols")
Performs k-fold blocked cross-validation for time series data.
cv_blocked( B, Z, Y, W, Ak, k, d, lambda1, t1, t2, eps, intercept = FALSE, cv, nfolds, tvp = FALSE, breaks = NULL, spec = NULL, ncores = 1, warmstart = FALSE, stopping_crit = 0L )cv_blocked( B, Z, Y, W, Ak, k, d, lambda1, t1, t2, eps, intercept = FALSE, cv, nfolds, tvp = FALSE, breaks = NULL, spec = NULL, ncores = 1, warmstart = FALSE, stopping_crit = 0L )
B |
Initial coefficient array |
Z |
Design matrix (transposed, d x n) |
Y |
Response matrix (transposed, d x n) |
W |
Weight array for adaptive LASSO |
Ak |
List of design matrices per subject (used to build row spec if spec not provided) |
k |
Number of subjects |
d |
Number of variables |
lambda1 |
Lambda grid matrix |
t1 |
Start indices (unused, kept for API compatibility) |
t2 |
End indices (unused, kept for API compatibility) |
eps |
Convergence tolerance |
intercept |
Whether model includes intercepts |
cv |
CV method (unused here, always "blocked") |
nfolds |
Number of CV folds |
tvp |
Whether time-varying parameters are used |
breaks |
List of period indices per subject (required if tvp=TRUE) |
spec |
Optional matrix_spec object. If not provided, a minimal spec is built from Ak and breaks. |
ncores |
Numeric. Number of cores for parallel computation. Default is 1. |
warmstart |
Logical. Whether to use warm starts in the FISTA solver. Default is FALSE. |
stopping_crit |
Integer. Stopping criterion flag passed to the C++ solver. Default is 0. |
List with beta coefficients and MSFE matrix
Routes to the appropriate CV method (blocked or rolling).
cv_multivar( B, Z, Y, W, Ak, bk, k, d, lambda1, t1, t2, eps, intercept = FALSE, cv, nfolds, tvp = FALSE, breaks = NULL, spec = NULL, ncores = 1, warmstart = FALSE, stopping_crit = 0L )cv_multivar( B, Z, Y, W, Ak, bk, k, d, lambda1, t1, t2, eps, intercept = FALSE, cv, nfolds, tvp = FALSE, breaks = NULL, spec = NULL, ncores = 1, warmstart = FALSE, stopping_crit = 0L )
B |
Initial coefficient array |
Z |
Design matrix (transposed) |
Y |
Response matrix (transposed) |
W |
Weight array |
Ak |
List of design matrices per subject |
bk |
List of response matrices per subject |
k |
Number of subjects |
d |
Number of variables |
lambda1 |
Lambda grid |
t1 |
Start indices |
t2 |
End indices |
eps |
Convergence tolerance |
intercept |
Whether model includes intercepts |
cv |
CV method: "blocked" or "rolling" |
nfolds |
Number of CV folds |
tvp |
Whether time-varying parameters are used |
breaks |
List of period indices per subject |
spec |
Optional matrix_spec object for row/column indices |
ncores |
Numeric. Number of cores for parallel computation. Default is 1. |
warmstart |
Logical. Whether to use warm starts in the FISTA solver. Default is FALSE. |
stopping_crit |
Integer. Stopping criterion flag passed to the C++ solver. Default is 0. |
List with beta coefficients and MSFE matrix
Cross Validation for multivar
cv.multivar(object)cv.multivar(object)
object |
multivar object built using |
The main function of the multivar package. Performs cross validation to select penalty parameters over a training sample and evaluates them over a test set.
An object of class multivar.results.
# example 1 (run) sim1 <- multivar_sim( k = 2, # individuals d = 5, # number of variables n = 20, # number of timepoints prop_fill_com = 0.1, # proportion of paths common prop_fill_ind = 0.05, # proportion of paths unique lb = 0.1, # lower bound on coefficient magnitude ub = 0.5, # upper bound on coefficient magnitude sigma = diag(5) # noise ) model1 <- constructModel(data = sim1$data) fit1 <- multivar::cv.multivar(model1)# example 1 (run) sim1 <- multivar_sim( k = 2, # individuals d = 5, # number of variables n = 20, # number of timepoints prop_fill_com = 0.1, # proportion of paths common prop_fill_ind = 0.05, # proportion of paths unique lb = 0.1, # lower bound on coefficient magnitude ub = 0.5, # upper bound on coefficient magnitude sigma = diag(5) # noise ) model1 <- constructModel(data = sim1$data) fit1 <- multivar::cv.multivar(model1)
This dataset contains multivariate time series data for k = 9 individuals with $d = 10$ variables collected at $t = 100$ equidistant time points. The data was generated such that each individual's VAR(1) transition matrix has 20 percent nonzero entries. This means, for example, each individual has 20 nonzero directed relationships in their data generating model. The position of non-zero elements in each individual's transition matrix was selected randomly given the following constraints: 2/3 of each individual's paths are shared by all individuals, and 1/3 are unique to each individual. For each individual, coefficient values between U(0,1, 0.9) were randomly drawn until stability conditions for the VAR model were satisfied.
dat_multivar_simdat_multivar_sim
A list containing
a common effects transition matrix
a list of unique (individual-specific) effect matrices
a list of total (common + individual-specific) effect matrices
a list of multivariate time series for all subjects
...
'estimate_initial_coefs' returns consistent initial estimates to be used for calculating adaptive weights in adaptive LASSO regularization.
estimate_initial_coefs( Ak, bk, d, k, lassotype, weightest, subgroup_membership, subgroup, nlambda1, tvp, breaks, intercept, nfolds, lambda_choice = "lambda.min", common_effects = TRUE, common_tvp_effects = TRUE, maity_opts = list() )estimate_initial_coefs( Ak, bk, d, k, lassotype, weightest, subgroup_membership, subgroup, nlambda1, tvp, breaks, intercept, nfolds, lambda_choice = "lambda.min", common_effects = TRUE, common_tvp_effects = TRUE, maity_opts = list() )
Ak |
List. A list (length = k) of lagged (T-lag-horizon) by d multivariate time series matrices. |
bk |
List. A list (length = k) of (T-lag-horizon) by d multivariate time series matrices. |
d |
Numeric vector. The number of variables for each dataset. |
k |
Numeric. The number of subjects. |
lassotype |
Character. Type of LASSO penalty: "standard" or "adaptive". |
weightest |
Character. How to estimate initial coefficients: "lasso", "ridge", or "ols". |
subgroup_membership |
Numeric vector. Vector of subgroup assignments for each subject. |
subgroup |
Logical. Whether to run subgrouping algorithm. |
nlambda1 |
Numeric. Not used (kept for API compatibility). |
tvp |
Logical. Whether to estimate time-varying parameters. |
breaks |
List. A list of length k indicating structural breaks in the time series. |
intercept |
Logical. Whether to include intercepts in the model. |
nfolds |
Numeric. The number of folds for cross-validation. |
lambda_choice |
Character. Which lambda to use from cv.glmnet: "lambda.min" or "lambda.1se". |
common_effects |
Logical. Whether to include common effects in TVP models. |
common_tvp_effects |
Logical. Whether to include common TVP effects (k>1 only). |
maity_opts |
List. Options for Maity et al. (2022) MrLasso initial estimation. |
A list containing:
common_effects: d x d matrix of common effects
subgroup_effects: list of d x d matrices per subgroup (if subgroup=TRUE)
unique_effects: list of d x d matrices per subject
tvp_effects: list of lists of d x d matrices per subject per period (if tvp=TRUE)
common_tvp_effects: list of d x d matrices per period (if tvp=TRUE and k>1)
total_effects: list of d x d matrices per subject
Compare estimated transition matrices to simulation truth, but only for components that actually exist in both 'sim_obj' and 'fit_obj'. For example, if 'fit_obj$mats' only contains 'total', only "total" rows are returned.
eval_multivar_performance( sim_obj, fit_obj, eps = 1e-08, reduced.output = TRUE, averages.only = TRUE, label = NULL, intercept = FALSE )eval_multivar_performance( sim_obj, fit_obj, eps = 1e-08, reduced.output = TRUE, averages.only = TRUE, label = NULL, intercept = FALSE )
sim_obj |
Output of multivar_sim() |
fit_obj |
Output of cv.multivar() / cv.fused() (or similar list with $mats) |
eps |
Small positive constant to stabilize relative errors |
reduced.output |
If TRUE, keep a reduced column set |
averages.only |
If TRUE, return only summary rows (unique_mean, total_mean) and the single 'common' row (if present) |
label |
Optional label for the fitted model; by default, uses the deparsed name of 'fit_obj' |
intercept |
Logical; if TRUE, evaluates intercepts separately from dynamics |
Converts a c(start, end) range to a full sequence.
expand_range(range)expand_range(range)
range |
Integer vector c(start, end) or NULL |
Integer vector or NULL
Creates a tidy dataframe with all tested hyperparameter combinations and their cross-validation error (MSFE). Each row represents one (lambda1, ratio) combination.
extract_multivar_hyperparams(object, fit)extract_multivar_hyperparams(object, fit)
object |
multivar model object used to call cv_multivar(...) |
fit |
result returned by cv_multivar(...); MSFE is assumed to be fit[[2]] |
The function averages MSFE across cross-validation folds and returns one row per hyperparameter combination. The dataframe can be used for:
Finding best hyperparameters: df[which.min(df$MSFE), ]
Plotting MSFE surface
Filtering/analyzing hyperparameter performance
A data frame with columns:
Index of ratio (1 to n_ratios)
Index of lambda1 (1 to n_lambda)
Flattened index using C++ ordering
Actual lambda1 penalty value
Actual ratio value
Computed lambda2 = lambda1 * ratio
Mean squared forecast error averaged across CV folds
Get Common Effect Columns
get_common_cols(spec)get_common_cols(spec)
spec |
A matrix_spec object |
Integer vector c(start, end) or NULL
Get Common TVP Columns for a Period
get_common_tvp_cols(spec, period)get_common_tvp_cols(spec, period)
spec |
A matrix_spec object |
period |
Integer. Period index (1 to P) |
Integer vector c(start, end) or NULL
Simplified functions for extracting dynamics matrices from fitted multivar models. These handle both TVP and non-TVP models transparently.
get_dynamics( fit, subject = NULL, period = NULL, type = c("total", "common", "unique") ) get_common_effects(fit, period = NULL) get_unique_effects(fit, subject = NULL, period = NULL) get_total_effects(fit, subject = NULL, period = NULL) get_dynamics_all_subjects( fit, period = NULL, type = c("total", "common", "unique") )get_dynamics( fit, subject = NULL, period = NULL, type = c("total", "common", "unique") ) get_common_effects(fit, period = NULL) get_unique_effects(fit, subject = NULL, period = NULL) get_total_effects(fit, subject = NULL, period = NULL) get_dynamics_all_subjects( fit, period = NULL, type = c("total", "common", "unique") )
fit |
A fitted multivar object (output from cv.multivar()) |
subject |
Subject index (1 to K). If NULL, returns all subjects. |
period |
Period index (for TVP models). If NULL, returns all periods. |
type |
Type of effects: "total", "common", or "unique" |
These helper functions simplify access to dynamics matrices by handling the different structures of TVP and non-TVP models automatically.
**For non-TVP models:** - 'fit$mats$common' is a single matrix (shared across all subjects) - 'fit$mats$unique' is a list of K matrices (one per subject) - 'fit$mats$total' is a list of K matrices (common + unique per subject)
**For TVP models:** - 'fit$mats$common' is a single matrix (time-invariant, shared across all subjects) - 'fit$mats$tvp' is a list of K lists, each containing P period matrices (time-varying per subject) - 'fit$mats$total' is a list of K lists of P matrices (common + tvp per subject per period)
The helper functions hide this complexity from the user.
## Not run: # Non-TVP model fit <- cv.multivar(object) get_dynamics(fit, subject = 1) # Subject 1 total effects get_common_effects(fit) # Common effects get_dynamics_all_subjects(fit) # All subjects # TVP model fit_tvp <- cv.multivar(object_tvp) get_dynamics(fit_tvp, subject = 1, period = 2) # Subject 1, Period 2 get_common_effects(fit_tvp, period = 2) # Common for Period 2 get_dynamics_all_subjects(fit_tvp, period = 2) # All subjects, Period 2 ## End(Not run)## Not run: # Non-TVP model fit <- cv.multivar(object) get_dynamics(fit, subject = 1) # Subject 1 total effects get_common_effects(fit) # Common effects get_dynamics_all_subjects(fit) # All subjects # TVP model fit_tvp <- cv.multivar(object_tvp) get_dynamics(fit_tvp, subject = 1, period = 2) # Subject 1, Period 2 get_common_effects(fit_tvp, period = 2) # Common for Period 2 get_dynamics_all_subjects(fit_tvp, period = 2) # All subjects, Period 2 ## End(Not run)
Returns the number of time-varying periods in a TVP model. Returns 1 for non-TVP models.
get_n_periods(fit)get_n_periods(fit)
fit |
A fitted multivar object |
Integer number of periods
## Not run: n_periods <- get_n_periods(fit) ## End(Not run)## Not run: n_periods <- get_n_periods(fit) ## End(Not run)
Get Row Range for a Subject's Period
get_period_rows(spec, subject, period)get_period_rows(spec, subject, period)
spec |
A matrix_spec object |
subject |
Integer. Subject index (1 to k) |
period |
Integer. Period index (1 to P_i) |
Integer vector c(start, end) or NULL
Get Subgroup Effect Columns
get_subgrp_cols(spec, subgroup)get_subgrp_cols(spec, subgroup)
spec |
A matrix_spec object |
subgroup |
Integer. Subgroup index (1 to S) |
Integer vector c(start, end) or NULL
Get Subgroup Columns for a Subject
get_subgrp_cols_for_subject(spec, subject)get_subgrp_cols_for_subject(spec, subject)
spec |
A matrix_spec object |
subject |
Integer. Subject index (1 to k) |
Integer vector c(start, end) or NULL
Get Row Range for a Subject
get_subject_rows(spec, subject)get_subject_rows(spec, subject)
spec |
A matrix_spec object |
subject |
Integer. Subject index (1 to k) |
Integer vector c(start, end)
Get Unique Effect Columns for a Subject
get_unique_cols(spec, subject)get_unique_cols(spec, subject)
spec |
A matrix_spec object |
subject |
Integer. Subject index (1 to k) |
Integer vector c(start, end) or NULL (for k=1 TVP)
Get Unique TVP Columns for a Subject and Period
get_unique_tvp_cols(spec, subject, period)get_unique_tvp_cols(spec, subject, period)
spec |
A matrix_spec object |
subject |
Integer. Subject index (1 to k) |
period |
Integer. Period index (1 to P_i) |
Integer vector c(start, end) or NULL
Returns TRUE if the model has time-varying parameters (TVP).
is_tvp(fit)is_tvp(fit)
fit |
A fitted multivar object |
Logical indicating if model is TVP
## Not run: if (is_tvp(fit)) { cat("Model has time-varying parameters\n") } ## End(Not run)## Not run: if (is_tvp(fit)) { cat("Model has time-varying parameters\n") } ## End(Not run)
Construct the sequence (path) of lambda1 values that will be used for cv.
lambda_grid( depth = 1000, nlam = 30, Y, Z, W = NULL, tol = 1e-04, intercept = FALSE, lamadapt = FALSE, k = NULL )lambda_grid( depth = 1000, nlam = 30, Y, Z, W = NULL, tol = 1e-04, intercept = FALSE, lamadapt = FALSE, k = NULL )
depth |
numeric. Default is 1000. Controls how wide the lambda1 path is. The top of the path is lambda_max (the largest penalty we think we need to zero everything out). The bottom is lambda_max / depth. Typical depth ~ 1000. |
nlam |
integer. Default is 30. Number of lambda1 values along the path (rows of the output). |
Y |
numeric outcome matrix. Matrix of outcomes. |
Z |
numeric matrix. Matrix of predictors. |
W |
numeric array of penalty weights. Shape: [ n_outcomes , n_predictors , n_scenarios ]. Interpretation: - W[,,i] is the penalty weight layout for scenario i. Different scenarios correspond to different relative penalization of global vs subgroup vs individual vs time-varying effects. |
tol |
numeric scalar. Default 1e-4. Tolerance used in the adaptive branch (lamadapt = TRUE) when binary-searching for the scenario-specific max lambda. If lamadapt = FALSE, tol is not used. |
intercept |
logical. Default FALSE. Whether the model includes an intercept column. Intercepts are usually unpenalized. In lamadapt = TRUE mode, we drop the first column of the fitted coefficient array when checking if everything is (approximately) zero, so we don't falsely call the intercept "nonzero". |
lamadapt |
logical. Default FALSE. If FALSE: We compute one proxy lambda_max from data (max(Y and then generate the same log-spaced path for every scenario. If TRUE: For each scenario i, we refine its own lambda_max using weighted penalized fits with W[,,i], using a binary search. That is closer to "adaptive lasso" logic: strong signals get downweighted and don't need as huge a lambda to kill them; weak ones get upweighted and do. |
k |
integer or NULL. Number of individuals. Only needed if lamadapt = TRUE, because we pass it to the solver (wlasso) inside the scenario-specific binary search. Ignored when lamadapt = FALSE. Notes on the returned object: |
In this package, lambda1 is the main sparsity / regularization strength applied to the common effects. Laer, we scaled these into the unique effects via ratios_unique. Importantly, we don't just pick a single lambda1 — we build a path of candidate lambda1 values, from very large (forces almost all penalized coefficients to zero) down to much smaller (less shrinkage).
This path is defined by a decreasing set of values, generated from lambda_max down to lambda_max / depth, so'depth' is used to control that span and the default value is 1,000.
Note: the models have multiple penalty scenarios as alluded to earlier. We call these scenarios, where each scenario encodes a different way to penalize the common and unique effects. Those scenarios live along the 3rd dimension of the array W are typically of length length(ratios_unique)*legnth(lambda1), such that
dim(W) = [ n_outcomes , n_predictors , n_scenarios ]
We build one lambda1 path per scenario. That’s why the return value is a matrix with:
rows = number of lambda1 values along the path columns = number of scenarios
- cv.multivar() stores this matrix in object@lambda1. - During CV, for each scenario column i and each row r in that column, the solver fits the model at that lambda1 and scores prediction error.
- We also have object@ratios_unique, where each ratio says how strong to penalize deviation blocks (individual/subgroup/time-varying) relative to the common effects. Conceptually this means lambda2 = ratio * lambda1.
- We use the ingredients: * lambda1 grid (here) * ratios_unique (constructModel) to construct the lambda2 grid..
Some notes on the arguments:
lambda1 matrix, dimension [nlam x n_scenarios].
Column i is the lambda1 path for scenario i. Row r is a particular lambda1 magnitude along that path
Later: - cv.multivar() stores this in object@lambda1, and cross-validates across [row r, column i]. - Combined with object@ratios_unique, you can reconstruct lambda2 via lambda2 = ratio * lambda1 and plot CV error surfaces.
Provides debiased, robustly-aggregated, analytically-thresholded initial
estimates for adaptive LASSO weights. Replaces the default median-based
decomposition when weightest = "maity" in constructModel.
Maity, S., Sun, Y., & Banerjee, M. (2022). Meta-analysis of heterogeneous data: integrative sparse regression in high-dimensions. JMLR, 23, 1-50.
Standard S3 methods for fitted multivar models.
## S3 method for class 'multivar_fit' print(x, ...) ## S3 method for class 'multivar_fit' summary(object, ...) ## S3 method for class 'multivar_fit' plot(x, type = c("dynamics", "prevalence"), ...) ## S3 method for class 'multivar_fit' coef( object, type = c("total", "common", "unique"), subject = NULL, period = NULL, ... )## S3 method for class 'multivar_fit' print(x, ...) ## S3 method for class 'multivar_fit' summary(object, ...) ## S3 method for class 'multivar_fit' plot(x, type = c("dynamics", "prevalence"), ...) ## S3 method for class 'multivar_fit' coef( object, type = c("total", "common", "unique"), subject = NULL, period = NULL, ... )
x |
A multivar_fit object (output from cv.multivar()). |
... |
Additional arguments (unused). |
object |
A multivar_fit object (output from cv.multivar()). |
type |
Character; one of '"total"', '"common"', '"unique"'. |
subject |
Optional integer subject index. |
period |
Optional integer period index (TVP only). |
print(multivar_fit): Print a fitted multivar model.
summary(multivar_fit): Summarize a fitted multivar model.
plot(multivar_fit): Plot fitted dynamics or prevalence.
coef(multivar_fit): Extract coefficient matrices.
Simulate multivar data.
multivar_sim( k, d, n, prop_fill_com, prop_fill_ind, lb, ub, sigma, unique_overlap = FALSE, mat_common = NULL, mat_unique = NULL, mat_total = NULL, diag = FALSE, intercept = NULL, standardize_output = FALSE )multivar_sim( k, d, n, prop_fill_com, prop_fill_ind, lb, ub, sigma, unique_overlap = FALSE, mat_common = NULL, mat_unique = NULL, mat_total = NULL, diag = FALSE, intercept = NULL, standardize_output = FALSE )
k |
Integer. The number of individuals (or datasets) to be generated. |
d |
Integer. The number of variables per dataset. For now this will be constant across individuals. |
n |
Integer. The time series length. |
prop_fill_com |
Numeric. The proportion of nonzero paths in the common transition matrix. |
prop_fill_ind |
Numeric. The proportion of nonzero unique (not in the common transition matrix or transition matrix of other individuals) paths in each individual transition matrix. |
lb |
Numeric. The lower bound for individual elements of the transition matrices. |
ub |
Numeric. The upper bound for individual elements of the transition matrices. |
sigma |
Matrix. The (population) innovation covariance matrix. |
unique_overlap |
Logical. Default is FALSE. Whether the unique portion should be completely unique (no overlap) or randomly chosen. |
mat_common |
Matrix. A common effects transition matrix (if known). |
mat_unique |
List. A list of unique effects transition matrix (if known). |
mat_total |
List. A list of total effects transition matrix (if known). |
diag |
Logical. Default is FALSE. Should diagonal elements be filled first for common elements. |
intercept |
List. Default is NULL. A list of length K containing numeric vectors of length d representing the intercept values. |
standardize_output |
Logical. Default is FALSE. If TRUE, scales each subject's data to have sample variance of 1 for each variable, and returns the transformed transition matrices and innovation covariances in standardized space. |
k <- 3 d <- 10 n <- 20 prop_fill_com <- .1 prop_fill_ind <- .05 lb <- 0.1 ub <- 0.5 sigma <- diag(d) data <- multivar_sim(k, d, n, prop_fill_com, prop_fill_ind, lb, ub,sigma)$datak <- 3 d <- 10 n <- 20 prop_fill_com <- .1 prop_fill_ind <- .05 lb <- 0.1 ub <- 0.5 sigma <- diag(d) data <- multivar_sim(k, d, n, prop_fill_com, prop_fill_ind, lb, ub,sigma)$data
Simulate multivar data with time-varying dynamics according to a latent growth curve.
multivar_sim_breaks( k, d, n, prop_fill_com, prop_fill_ind, prop_fill_com_growth, prop_fill_ind_growth, offset = 0, lb, ub, lb_int, ub_int, lb_slope, ub_slope, sigma, diag = FALSE, iters = 1, intercept = NULL )multivar_sim_breaks( k, d, n, prop_fill_com, prop_fill_ind, prop_fill_com_growth, prop_fill_ind_growth, offset = 0, lb, ub, lb_int, ub_int, lb_slope, ub_slope, sigma, diag = FALSE, iters = 1, intercept = NULL )
k |
Integer. The number of individuals (or datasets) to be generated. |
d |
Integer. The number of variables per dataset. For now this will be constant across individuals. |
n |
Integer. The time series length. |
prop_fill_com |
Numeric. The proportion of nonzero paths in the common transition matrix. |
prop_fill_ind |
Numeric. The proportion of nonzero unique (not in the common transition matrix or transition matrix of other individuals) paths in each individual transition matrix. |
prop_fill_com_growth |
Numeric. The proportion of nonzero time-varying paths in the common transition matrix. |
prop_fill_ind_growth |
Numeric. The proportion of nonzero time-varying unique (not in the common transition matrix or transition matrix of other individuals) paths in each individual transition matrix. |
offset |
Numeric. An offset dictating when dynamics should transition from time-invariant to time-varying. |
lb |
Numeric. The upper bound for individual elements of the transition matrices. |
ub |
Numeric. The lower bound for individual elements of the transition matrices. |
lb_int |
Numeric. The upper bound for individual elements of the intercepts. |
ub_int |
Numeric. The lower bound for individual elements of the intercepts. |
lb_slope |
Numeric. The upper bound for individual elements of the slopes. |
ub_slope |
Numeric. The lower bound for individual elements of the slopes. |
sigma |
Matrix. The (population) innovation covariance matrix. |
diag |
Logical. Default is FALSE. Should diagonal elements be filled first for common elements. |
iters |
Integer. Default is 1. Number of iterations |
intercept |
List. Default is NULL. A list of length K containing numeric vectors of length d representing the intercept values. If NULL, intercepts are set to 0. |
Simulate multivar data with time-varying dynamics according to a latent growth curve.
multivar_sim_growth( k, d, n, prop_fill_com, prop_fill_ind, prop_fill_com_growth, prop_fill_ind_growth, offset = 0, lb, ub, lb_int, ub_int, lb_slope, ub_slope, lb_quad = 0, ub_quad = 0, sigma, diag = FALSE, iters = 1, type = "linear", extreme_cutoff = 10, intercept = NULL )multivar_sim_growth( k, d, n, prop_fill_com, prop_fill_ind, prop_fill_com_growth, prop_fill_ind_growth, offset = 0, lb, ub, lb_int, ub_int, lb_slope, ub_slope, lb_quad = 0, ub_quad = 0, sigma, diag = FALSE, iters = 1, type = "linear", extreme_cutoff = 10, intercept = NULL )
k |
Integer. The number of individuals (or datasets) to be generated. |
d |
Integer. The number of variables per dataset. For now this will be constant across individuals. |
n |
Integer. The time series length. |
prop_fill_com |
Numeric. The proportion of nonzero paths in the common transition matrix. |
prop_fill_ind |
Numeric. The proportion of nonzero unique (not in the common transition matrix or transition matrix of other individuals) paths in each individual transition matrix. |
prop_fill_com_growth |
Numeric. The proportion of nonzero time-varying paths in the common transition matrix. |
prop_fill_ind_growth |
Numeric. The proportion of nonzero time-varying unique (not in the common transition matrix or transition matrix of other individuals) paths in each individual transition matrix. |
offset |
Numeric. An offset dictating when dynamics should transition from time-invariant to time-varying. |
lb |
Numeric. The upper bound for individual elements of the transition matrices. |
ub |
Numeric. The lower bound for individual elements of the transition matrices. |
lb_int |
Numeric. The upper bound for individual elements of the transition matrices. |
ub_int |
Numeric. The lower bound for individual elements of the transition matrices. |
lb_slope |
Numeric. The upper bound for linear growth coefficients. |
ub_slope |
Numeric. The lower bound for linear growth coefficients. |
lb_quad |
Numeric. The upper bound for quadratic growth coefficients. |
ub_quad |
Numeric. The lower bound for quadratic growth coefficients. |
sigma |
Matrix. The (population) innovation covariance matrix. |
diag |
Logical. Default is FALSE. Should diagonal elements be filled first for common elements. |
iters |
Integer. Default is 1. Number of iterations. |
type |
Character. Default is linear. |
extreme_cutoff |
Numericr. Default is 10. |
intercept |
List. Default is NULL. A list of length K containing numeric vectors of length d representing the intercept values. If NULL, intercepts are set to 0. |
Generates VAR data with a hierarchical structure: common effects (shared by all), subgroup effects (shared within groups), and unique effects (individual-specific). Importantly, these three components occupy NON-OVERLAPPING positions in the coefficient matrices, ensuring clean identifiability.
multivar_sim_subgroups( k, d, n, subgroup, p_com = d/d^2, p_sub = 0.05, p_ind = 0.05, sigma = NULL, lb = 0, ub = 1, intercept = NULL, max_attempts = 100, max_eig_threshold = 0.99 )multivar_sim_subgroups( k, d, n, subgroup, p_com = d/d^2, p_sub = 0.05, p_ind = 0.05, sigma = NULL, lb = 0, ub = 1, intercept = NULL, max_attempts = 100, max_eig_threshold = 0.99 )
k |
Total number of subjects (sum across all subgroups) |
d |
Number of variables |
n |
Number of timepoints |
subgroup |
Integer vector of length k indicating subgroup membership. For example, c(1,1,1,2,2,2) indicates 3 subjects in group 1 and 3 in group 2. |
p_com |
Proportion of positions allocated to common effects. Sampled from diagonal positions. Default: d/d^2 (i.e., diagonal only). |
p_sub |
Proportion of positions allocated to subgroup effects (per group). Sampled from off-diagonal positions excluding common. Default: 0.05. |
p_ind |
Proportion of positions allocated to unique effects (per individual). Sampled from remaining positions. Default: 0.05. |
sigma |
Innovation covariance matrix. If NULL, uses identity matrix. |
lb |
Lower bound for coefficient values. Default: 0. |
ub |
Upper bound for coefficient values. Default: 1. |
intercept |
Optional list of intercept vectors (one per subject). If NULL, no intercepts are used. Default: NULL. |
max_attempts |
Maximum number of attempts to generate stationary dynamics. Default: 100. |
max_eig_threshold |
Maximum absolute eigenvalue allowed for stationarity. Default: 0.99. |
The function generates a three-level hierarchical structure where:
Shared by all subjects, typically on diagonal positions
Shared within subgroups, on distinct off-diagonal positions
Individual-specific, on remaining positions
The key feature is that these three components occupy NON-OVERLAPPING positions in the coefficient matrices, which ensures identifiability of the decomposition:
The function repeatedly generates matrices until all subjects have stationary dynamics (maximum absolute eigenvalue < max_eig_threshold).
A list with the following components:
List of k data matrices (each n x d)
Vector of subgroup memberships
Common effect matrix (d x d)
List of k subgroup effect matrices (replicated within groups)
List of k unique effect matrices
List of k total effect matrices
List of intercept vectors (if provided)
## Not run: # Simulate 6 subjects in 2 subgroups sim <- multivar_sim_subgroups( k = 6, d = 4, n = 100, subgroup = c(1, 1, 1, 2, 2, 2), p_com = 0.2, p_sub = 0.1, p_ind = 0.05 ) # Fit model object <- constructModel(sim$data, subgroup_membership = sim$subgroup) fit <- cv.multivar(object) # Evaluate including subgroup effects perf <- eval_multivar_performance(sim, fit) print(perf) ## End(Not run)## Not run: # Simulate 6 subjects in 2 subgroups sim <- multivar_sim_subgroups( k = 6, d = 4, n = 100, subgroup = c(1, 1, 1, 2, 2, 2), p_com = 0.2, p_sub = 0.1, p_ind = 0.05 ) # Fit model object <- constructModel(sim$data, subgroup_membership = sim$subgroup) fit <- cv.multivar(object) # Evaluate including subgroup effects perf <- eval_multivar_performance(sim, fit) print(perf) ## End(Not run)
Simulate multivar TVP data (piecewise or continuous)
multivar_sim_tvp( k, d, n, sigma, phi_common_list, phi_unique_list = NULL, T_per_period = NULL, mat_tvp = NULL, type = c("piecewise", "continuous"), burn = 500, intercept = NULL )multivar_sim_tvp( k, d, n, sigma, phi_common_list, phi_unique_list = NULL, T_per_period = NULL, mat_tvp = NULL, type = c("piecewise", "continuous"), burn = 500, intercept = NULL )
k |
Integer. Number of subjects. |
d |
Integer. Number of variables per subject. |
n |
Integer. Total time series length per subject. |
sigma |
Matrix. Innovation covariance matrix (d x d). |
phi_common_list |
List of d x d common transition matrices. For piecewise: one per period. For continuous: one base matrix. |
phi_unique_list |
List of lists. phi_unique_list[[subject]][[period]] gives the unique effects matrix for that subject/period. For continuous: phi_unique_list[[subject]] is one matrix. |
T_per_period |
Integer vector. Observations per period (piecewise only). If NULL, periods are equal length. |
mat_tvp |
Logical matrix (d x d). Which elements are time-varying (continuous only). |
type |
Character. Either "piecewise" or "continuous". |
burn |
Integer. Burn-in period to discard. Default 500. |
intercept |
Intercept term. Can be: - NULL (zeros for all) - List of vectors: intercept[[subject]] is length d (constant over periods) - List of lists: intercept[[subject]][[period]] is length d (period-specific) |
List with components:
data |
List of T x d data matrices, one per subject |
mat_com |
Common transition matrix (piecewise: list per period; continuous: list per timepoint) |
mat_ind_unique |
List of unique effects (subject x period) |
mat_ind_final |
List of total effects (subject x period) |
T_per_period |
Observations per period |
breaks |
Break points for period changes |
# Piecewise TVP with 2 subjects, 2 periods d <- 3 phi_com1 <- matrix(0, d, d); phi_com1[1,2] <- 0.3 phi_com2 <- matrix(0, d, d); phi_com2[1,2] <- 0.3; phi_com2[2,3] <- 0.2 phi_uniq <- list( list(matrix(0, d, d), matrix(0, d, d)), # subject 1: no unique effects list(matrix(0, d, d), matrix(0, d, d)) # subject 2: no unique effects ) phi_uniq[[2]][[1]][3,1] <- 0.2 # subject 2, period 1 has unique edge sim <- multivar_sim_tvp( k = 2, d = d, n = 200, sigma = diag(d), phi_common_list = list(phi_com1, phi_com2), phi_unique_list = phi_uniq, T_per_period = c(100, 100), type = "piecewise" )# Piecewise TVP with 2 subjects, 2 periods d <- 3 phi_com1 <- matrix(0, d, d); phi_com1[1,2] <- 0.3 phi_com2 <- matrix(0, d, d); phi_com2[1,2] <- 0.3; phi_com2[2,3] <- 0.2 phi_uniq <- list( list(matrix(0, d, d), matrix(0, d, d)), # subject 1: no unique effects list(matrix(0, d, d), matrix(0, d, d)) # subject 2: no unique effects ) phi_uniq[[2]][[1]][3,1] <- 0.2 # subject 2, period 1 has unique edge sim <- multivar_sim_tvp( k = 2, d = d, n = 200, sigma = diag(d), phi_common_list = list(phi_com1, phi_com2), phi_unique_list = phi_uniq, T_per_period = c(100, 100), type = "piecewise" )
An object class to be used with cv.multivar
To construct an object of class multivar, use the function constructModel
kNumeric. The number of subjects (or groupings) in the dataset.
nNumeric Vector. Vector containing the number of timepoints for each dataset.
dNumeric Vector. Vector containing the number of variables for each dataset.
AkList. A list (length = k) of lagged (T-lag-horizon) by d multivariate time series.
bkList. A list (length = k) of (T-lag-horizon) by d multivariate time series.
Ak_origList. A list (length = k) of lagged (T-lag-horizon) by d unscaled multivariate time series.
bk_origList A list (length = k) of (T-lag-horizon) by d unscaled multivariate time series.
HkList. A list (length = k) of (horizon) by d multivariate time series.
AMatrix. A matrix containing the lagged ((T-lag-horizon)k) by (d+dk) multivariate time series.
bMatrix. A matrix containing the non-lagged ((T-lag-horizon)k) by (d) multivariate time series.
HMatrix. A matrix containing the non-lagged (horizon k) by d multivariate time series.
data_meansList. A list (length = k) of column means for each group's data, used for intercept recovery when intercept=TRUE.
lagNumeric. The VAR order. Currently only lag 1 is supported.
horizonNumeric. Forecast horizon.
t1Numeric vector. Index of time series in which to start cross validation for individual k.
t2Numeric vector. Index of time series in which to end cross validation for individual k.
t1kNumeric vector. Index of time series in which to start cross validation for individual k.
t2kNumeric vector. Index of time series in which to end cross validation for individual k.
ntkNumeric. Number of usable timepoints (rows of b) per individual k
ndkNumeric. Number of variables (cols of b) per individual k
lambda1Numeric vector. Regularization parameter grid.
nlambda1Numeric. Number of lambda1 values to search over. Default is 30.
n_ratios_subgroupNumeric. Number of ratios_subgroup values to search over. Default is 30.
gammaNumeric. Power for adaptive weighting (default 1). Controls how strongly initial estimates influence the penalty: weight = 1/|coef|^gamma.
tolNumeric. Convergence tolerance.
depthNumeric. Depth of grid construction. Default is 1000.
windowNumeric. Size of rolling window.
standardizeLogical. Default is true. Whether to standardize the individual data.
weightestCharacter. How to estimate initial coefficients for adaptive weights. Default is "lasso". Other options include "ridge" and "ols".
canonicalLogical. Default is false. If true, individual datasets are fit to a VAR(1) model.
thresholdLogical. Default is false. If true, and canonical is true, individual transition matrices are thresholded based on significance.
lassotypeCharacter. Default is "adaptive". Choices are "standard" or "adaptive" lasso.
interceptLogical. Default is FALSE.
WMatrix. Default is NULL.
ratios_uniqueNumeric vector. Penalty ratio for unique effects. Default is NULL.
ratios_subgroupNumeric vector. Penalty ratio for subgroup effects. Default is NULL.
ratios_unique_tvpNumeric vector. Default is NULL.
ratios_common_tvpNumeric vector. Penalty ratio for common TVP effects. Default is NULL.
cvCharacter. Default is "blocked" for k-folds blocked cross-validation. rolling window cross-validation also available using "rolling". If "blocked" is selected the nfolds argument should be specified.
nfoldsNumeric. The number of folds for use with "blocked" cross-validation.
lamadaptLogical. Should the lambdas be calculated adaptively. Default is FALSE.
subgroup_membershipNumeric. Vector of subgroup assignments.
subgroupLogical. Argument whether to run subgrouping algorithm.
BMatrix. Default is NULL.
initcoefsList. A list of initial consistent estimates for the total, subgroup, unique and common effects.
pendiagLogical. Logical indicating where autoregressive paramaters should be penalized. Default is true.
tvpLogical.
inittvpcoefsList. A list of initial tvp estimates.
breaksList. A list of length K indicating structural breaks in the time series.
lambda_choiceCharacter. Which lambda to use for initial coefficient estimation ("lambda.min" or "lambda.1se").
common_effectsLogical. Whether to include common effects in TVP models. Only applies when tvp = TRUE.
common_tvp_effectsLogical. Whether to include common TVP effects (shared time-varying patterns) in TVP models. Only applies when tvp = TRUE.
save_betaLogical. Whether to retain the full beta array in the cv.multivar result. Default is TRUE.
ncoresNumeric. Number of cores for parallel computation. Default is 1.
specList. Design matrix specification object created by build_matrix_spec. Single source of truth for column/row indices.
epsNumeric. FISTA convergence tolerance. Default is 1e-3.
warmstartLogical. Whether to use warm starts in the FISTA solver. Default is TRUE.
stopping_critCharacter. FISTA convergence criterion. One of "absolute", "relative", or "objective".
selectionCharacter. Model selection criterion: "cv" (default) for cross-validated MSFE, or "ebic" for Extended BIC.
ebic_gammaNumeric. EBIC tuning parameter, used when selection = "ebic". Default is 0.5.
weight_typeCharacter. Adaptive weight function type: "standard" (default) uses 1/|coef|^gamma, "bounded" uses 1/(1+|coef|/tau)^gamma.
maity_optsList. Options for Maity et al. (2022) MrLasso initial estimation when weightest = "maity". Supports eta (scale parameter for re-descending loss, default 2.0) and thresh_const (threshold multiplier, default 1.0).
Plot CV error over (lambda1, lambda2)
plot_cv_lambda_grid(fit, object = NULL, log_scale = TRUE, show_best = TRUE)plot_cv_lambda_grid(fit, object = NULL, log_scale = TRUE, show_best = TRUE)
fit |
result from cv.multivar(...) |
object |
OPTIONAL; only used if fit does NOT contain hyperparams or obj |
log_scale |
logical; plot on log10 scale? |
show_best |
logical; mark best pair? |
Creates heatmap visualizations of transition matrices from fitted multivar models. Supports plotting common effects, unique (subject-specific) effects, total effects, subgroup effects, and time-varying parameter (TVP) effects.
plot_results( x, plot_type = c("common", "unique", "total", "subgrp", "tvp", "common_tvp", "tvp_total"), facet_ncol = 3, subjects = "all", periods = "all", ub = 1, lb = -1, palette = "default", show_zeros = FALSE, ... )plot_results( x, plot_type = c("common", "unique", "total", "subgrp", "tvp", "common_tvp", "tvp_total"), facet_ncol = 3, subjects = "all", periods = "all", ub = 1, lb = -1, palette = "default", show_zeros = FALSE, ... )
x |
Object returned by |
plot_type |
Character. Type of effects to plot:
|
facet_ncol |
Numeric. Number of columns when faceting multiple matrices |
subjects |
Character "all" or numeric vector. Which subjects to plot for "unique", "total", or "tvp" types. Default is "all" |
periods |
Character "all" or numeric vector. Which time periods to plot for TVP models. Default is "all" |
ub |
Numeric. Upper bound for color scale. Default is 1 |
lb |
Numeric. Lower bound for color scale. Default is -1 |
palette |
Character. Color palette: "default", "viridis", or "greyscale" |
show_zeros |
Logical. If FALSE (default), zero values shown as white/NA |
... |
Additional arguments passed to plotting engine |
A ggplot2 object that can be further customized
## Not run: sim <- multivar_sim(k = 3, d = 5, n = 50, prop_fill_com = 0.2, prop_fill_ind = 0.1, sigma = diag(5)) model <- constructModel(sim$data) fit <- cv.multivar(model) # Plot common effects plot_results(fit, plot_type = "common") # Plot unique effects for first 2 subjects plot_results(fit, plot_type = "unique", subjects = 1:2) # For TVP models fit_tvp <- cv.multivar(constructModel(data, tvp = TRUE, breaks = list(c(50, 100)))) plot_results(fit_tvp, plot_type = "tvp") # TVP deviations by period plot_results(fit_tvp, plot_type = "tvp_total") # Total effects by period # Customize the plot p <- plot_results(fit, plot_type = "total") p + ggplot2::ggtitle("My Custom Title") + ggplot2::theme_minimal() ## End(Not run)## Not run: sim <- multivar_sim(k = 3, d = 5, n = 50, prop_fill_com = 0.2, prop_fill_ind = 0.1, sigma = diag(5)) model <- constructModel(sim$data) fit <- cv.multivar(model) # Plot common effects plot_results(fit, plot_type = "common") # Plot unique effects for first 2 subjects plot_results(fit, plot_type = "unique", subjects = 1:2) # For TVP models fit_tvp <- cv.multivar(constructModel(data, tvp = TRUE, breaks = list(c(50, 100)))) plot_results(fit_tvp, plot_type = "tvp") # TVP deviations by period plot_results(fit_tvp, plot_type = "tvp_total") # Total effects by period # Customize the plot p <- plot_results(fit, plot_type = "total") p + ggplot2::ggtitle("My Custom Title") + ggplot2::theme_minimal() ## End(Not run)
Creates heatmap visualizations of true transition matrices from multivar simulations. Supports plotting common effects, unique (subject-specific) effects, total effects, and subgroup effects.
plot_sim( x, plot_type = c("common", "unique", "total", "subgrp"), facet_ncol = 3, subjects = "all", ub = 1, lb = -1, palette = "default", show_zeros = FALSE, ... )plot_sim( x, plot_type = c("common", "unique", "total", "subgrp"), facet_ncol = 3, subjects = "all", ub = 1, lb = -1, palette = "default", show_zeros = FALSE, ... )
x |
Object returned by |
plot_type |
Character. Type of effects to plot:
|
facet_ncol |
Numeric. Number of columns when faceting multiple matrices |
subjects |
Character "all" or numeric vector. Which subjects to plot for "unique" or "total" types. Default is "all" |
ub |
Numeric. Upper bound for color scale. Default is 1 |
lb |
Numeric. Lower bound for color scale. Default is -1 |
palette |
Character. Color palette: "default", "viridis", or "greyscale" |
show_zeros |
Logical. If FALSE (default), zero values shown as white/NA |
... |
Additional arguments passed to plotting engine |
A ggplot2 object that can be further customized
plot_results, plot_transition_mat
## Not run: # Simulate data sim <- multivar_sim(k = 3, d = 5, n = 50, prop_fill_com = 0.2, prop_fill_ind = 0.1, lb = 0.1, ub = 0.9, sigma = diag(5)) # Plot true common effects plot_sim(sim, plot_type = "common") # Plot true unique effects for subjects 1-2 plot_sim(sim, plot_type = "unique", subjects = 1:2) # Simulate with subgroups sim_sub <- multivar_sim_subgroups(k = 4, d = 3, n = 40, subgroup = c(1, 1, 2, 2), p_com = 0.25, p_sub = 0.10, p_ind = 0.05, sigma = diag(3)) # Plot subgroup effects plot_sim(sim_sub, plot_type = "subgrp") ## End(Not run)## Not run: # Simulate data sim <- multivar_sim(k = 3, d = 5, n = 50, prop_fill_com = 0.2, prop_fill_ind = 0.1, lb = 0.1, ub = 0.9, sigma = diag(5)) # Plot true common effects plot_sim(sim, plot_type = "common") # Plot true unique effects for subjects 1-2 plot_sim(sim, plot_type = "unique", subjects = 1:2) # Simulate with subgroups sim_sub <- multivar_sim_subgroups(k = 4, d = 3, n = 40, subgroup = c(1, 1, 2, 2), p_com = 0.25, p_sub = 0.10, p_ind = 0.05, sigma = diag(3)) # Plot subgroup effects plot_sim(sim_sub, plot_type = "subgrp") ## End(Not run)
Creates a heatmap visualization of an arbitrary transition matrix. Useful for plotting custom matrices or comparing different estimates.
plot_transition_mat( x, title = NULL, subtitle = NULL, ub = 1, lb = -1, legend = TRUE, dimnames = TRUE, palette = "default", show_zeros = FALSE, ... )plot_transition_mat( x, title = NULL, subtitle = NULL, ub = 1, lb = -1, legend = TRUE, dimnames = TRUE, palette = "default", show_zeros = FALSE, ... )
x |
Matrix. A transition matrix to plot |
title |
Character. Main title for the plot |
subtitle |
Character. Subtitle for the plot |
ub |
Numeric. Upper bound for color scale. Default is 1 |
lb |
Numeric. Lower bound for color scale. Default is -1 |
legend |
Logical. Should a legend be included? Default TRUE |
dimnames |
Logical. Should variable names be shown? Default TRUE |
palette |
Character. Color palette: "default", "viridis", or "greyscale" |
show_zeros |
Logical. If FALSE (default), zero values shown as white/NA |
... |
Additional arguments passed to plotting engine |
A ggplot2 object that can be further customized
## Not run: # Plot random matrix plot_transition_mat(matrix(rnorm(25), 5, 5), title = "Random Matrix") # Plot with custom bounds mat <- matrix(runif(25, -0.5, 0.5), 5, 5) plot_transition_mat(mat, title = "Small Coefficients", lb = -0.5, ub = 0.5) # Without legend or dimension names plot_transition_mat(mat, legend = FALSE, dimnames = FALSE) ## End(Not run)## Not run: # Plot random matrix plot_transition_mat(matrix(rnorm(25), 5, 5), title = "Random Matrix") # Plot with custom bounds mat <- matrix(runif(25, -0.5, 0.5), 5, 5) plot_transition_mat(mat, title = "Small Coefficients", lb = -0.5, ub = 0.5) # Without legend or dimension names plot_transition_mat(mat, legend = FALSE, dimnames = FALSE) ## End(Not run)
Fits the common block using cv.glmnet on a block-diagonal design. Returns A_pre (d x (d+1)); if include_intercept = FALSE, the first column is 0.
pretrained_var_stage1_glmnet( object, include_intercept = FALSE, standardize = FALSE, foldid = NULL, lambda = NULL, lambest = "min" )pretrained_var_stage1_glmnet( object, include_intercept = FALSE, standardize = FALSE, foldid = NULL, lambda = NULL, lambest = "min" )
object |
multivar object with slots: A (N x p), b (N x d), d (length-1 or length-d), nfolds, etc. |
include_intercept |
logical; if TRUE, add one unpenalized intercept per outcome (default TRUE). |
standardize |
logical; passed to glmnet::cv.glmnet (default FALSE to mirror multivar defaults). |
foldid |
optional CV fold id. If length N, it will be replicated for each outcome (length N*d). If length N*d, used as-is. Otherwise ignored (glmnet will make its own). |
lambda |
optional numeric vector of lambdas to force glmnet to use (helps match multivar paths). |
lambest |
Character. Default is '"min"'. |
list(A_pre, lambda_best, cvfit, include_intercept)
Prints a dynamics matrix (or list of matrices) with clear row/column labels and formatting options. Handles matrices of different sizes gracefully. Can also accept a fit object directly (e.g., from cv.multivar()).
print_dynamics( dynamics, digits = 3, zero_char = ".", highlight_nonzero = TRUE, max_print = 15, time_labels = TRUE, subject_label = NULL, period_labels = NULL )print_dynamics( dynamics, digits = 3, zero_char = ".", highlight_nonzero = TRUE, max_print = 15, time_labels = TRUE, subject_label = NULL, period_labels = NULL )
dynamics |
A numeric matrix, a list of matrices (for multiple subjects), or a fit object from cv.multivar() (will automatically extract total effects) |
digits |
Number of decimal places to display (default: 3) |
zero_char |
Character to display for zero entries (default: ".") |
highlight_nonzero |
Logical; if TRUE, emphasize non-zero entries (default: TRUE) |
max_print |
Maximum number of rows/cols to print before truncating (default: 15) |
time_labels |
Logical; if TRUE, add subscripts like |
subject_label |
Optional label for the subject/matrix (e.g., "Subject 1") |
period_labels |
Optional character vector of period labels for TVP models |
Invisibly returns the input (for chaining)
# Simple 4x4 matrix phi <- matrix(c(0.3, 0, 0.4, 0, 0.4, 0.5, 0, 0.3, 0, 0.3, 0.2, 0, 0, 0, 0, 0.4), 4, 4) print_dynamics(phi) # List of matrices phi_list <- list(phi, phi * 0.8) print_dynamics(phi_list) # From fit object (automatic extraction) # fit <- cv.multivar(object) # print_dynamics(fit) # Automatically extracts and prints total effects # TVP fit object with period labels # fit_tvp <- cv.multivar(object_tvp) # print_dynamics(fit_tvp, period_labels = c("Pre", "During", "Post"))# Simple 4x4 matrix phi <- matrix(c(0.3, 0, 0.4, 0, 0.4, 0.5, 0, 0.3, 0, 0.3, 0.2, 0, 0, 0, 0, 0.4), 4, 4) print_dynamics(phi) # List of matrices phi_list <- list(phi, phi * 0.8) print_dynamics(phi_list) # From fit object (automatic extraction) # fit <- cv.multivar(object) # print_dynamics(fit) # Automatically extracts and prints total effects # TVP fit object with period labels # fit_tvp <- cv.multivar(object_tvp) # print_dynamics(fit_tvp, period_labels = c("Pre", "During", "Post"))
Prints dynamics for TVP models where dynamics vary across time periods. This is a specialized wrapper around print_dynamics() for TVP structures.
print_dynamics_tvp(dynamics_tvp, period_labels = NULL, ...)print_dynamics_tvp(dynamics_tvp, period_labels = NULL, ...)
dynamics_tvp |
A list of matrices (one per period), or a list of lists (for multiple subjects, each containing a list of period-specific matrices) |
period_labels |
Optional character vector of period labels (e.g., c("Pre", "During", "Post")) |
... |
Additional arguments passed to print_dynamics() |
Invisibly returns the input (for chaining)
# Three periods with different dynamics phi_period1 <- matrix(c(0.3, 0, 0.4, 0, 0.4, 0.5, 0, 0.3, 0, 0.3, 0.2, 0, 0, 0, 0, 0.4), 4, 4) phi_period2 <- matrix(c(0.4, 0.3, 0, 0.2, 0, 0.6, 0.4, 0, 0.3, 0, 0.3, 0, 0, 0.4, 0, 0.5), 4, 4) phi_period3 <- matrix(c(0.5, 0.2, 0, 0, 0, 0.4, 0.5, 0, 0.5, 0, 0.4, 0.2, 0, 0.5, 0, 0.3), 4, 4) # For single subject print_dynamics_tvp(list(phi_period1, phi_period2, phi_period3)) # With custom period labels print_dynamics_tvp(list(phi_period1, phi_period2, phi_period3), period_labels = c("Baseline", "Treatment", "Follow-up"))# Three periods with different dynamics phi_period1 <- matrix(c(0.3, 0, 0.4, 0, 0.4, 0.5, 0, 0.3, 0, 0.3, 0.2, 0, 0, 0, 0, 0.4), 4, 4) phi_period2 <- matrix(c(0.4, 0.3, 0, 0.2, 0, 0.6, 0.4, 0, 0.3, 0, 0.3, 0, 0, 0.4, 0, 0.5), 4, 4) phi_period3 <- matrix(c(0.5, 0.2, 0, 0, 0, 0.4, 0.5, 0, 0.5, 0, 0.4, 0.2, 0, 0.5, 0, 0.3), 4, 4) # For single subject print_dynamics_tvp(list(phi_period1, phi_period2, phi_period3)) # With custom period labels print_dynamics_tvp(list(phi_period1, phi_period2, phi_period3), period_labels = c("Baseline", "Treatment", "Follow-up"))
For models with multiple subjects (K>1), displays a matrix showing the proportion/percentage of subjects that have each edge (non-zero entry).
print_edge_prevalence( fit, type = c("proportion", "count"), digits = 2, zero_char = ".", threshold = 1e-10 )print_edge_prevalence( fit, type = c("proportion", "count"), digits = 2, zero_char = ".", threshold = 1e-10 )
fit |
A fitted multivar object (output from cv.multivar()) |
type |
Character; "proportion" (default) or "count" to show counts instead |
digits |
Number of decimal places (default: 2) |
zero_char |
Character to display for edges present in 0 subjects (default: ".") |
threshold |
Threshold for considering an edge as present (default: 1e-10) |
Invisibly returns the prevalence matrix
# fit <- cv.multivar(object) # K=2 or more subjects # print_edge_prevalence(fit)# fit <- cv.multivar(object) # K=2 or more subjects # print_edge_prevalence(fit)
Print method for matrix_spec
## S3 method for class 'matrix_spec' print(x, ...)## S3 method for class 'matrix_spec' print(x, ...)
x |
A matrix_spec object. |
... |
Additional arguments (ignored). |
After fitting the model on centered data, this function recovers the intercepts using the formula: c = mean(b) - Phi * mean(A). For multi-group models, it also decomposes intercepts into common and group-specific components.
recover_intercepts( mats, data_means, k, d, subgroup = FALSE, subgroup_membership = NULL, tvp = FALSE, breaks = NULL )recover_intercepts( mats, data_means, k, d, subgroup = FALSE, subgroup_membership = NULL, tvp = FALSE, breaks = NULL )
mats |
List. The fitted coefficient matrices from breakup_transition, containing: - common: Common effects matrix (Psi) - unique: List of unique effects matrices (Psi^(k)) - total: List of total effects matrices (Phi^(k) = Psi + Psi^(k)) - subgrp: List of subgroup effects matrices (if subgroups) |
data_means |
List. For each group, a list containing mean_b and mean_A from original data |
k |
Numeric. Number of groups |
d |
Numeric. Number of variables |
subgroup |
Logical. Whether subgroup structure is present |
subgroup_membership |
Numeric vector. Subgroup assignments for each subject |
tvp |
Logical. Whether time-varying parameters are present |
breaks |
List. Time period definitions for TVP models |
For each group k, the total intercept is recovered using:
where are the outcomes and are the predictors .
This is the same approach used by glmnet for intercept recovery.
For multi-group models (k > 1), intercepts are decomposed as:
# Common intercept
# Group-specific intercept
This decomposition ensures the constraint: sum_k(c^(k)) = 0
Note: This formula c = mean(b) - Phi * mean(A) is different from the steady-state
formula , which assumes mean(b) = mean(A) = mean(Y).
In finite samples they give similar but not identical results. The formula used
here is preferred as it matches standard practice in penalized regression (e.g., glmnet).
For TVP models, this function recovers time-varying intercepts c_t for each period. When data_means contains per-period means (mean_b_t, mean_A_t), time-specific intercepts are computed. Otherwise, falls back to base intercepts.
List containing: - intercepts_total: List of total intercepts for each group (c_total^(k)) - intercept_common: Common intercept (c) - intercepts_unique: List of group-specific intercepts (c^(k)) - intercepts_subgrp: List of subgroup-specific intercepts (if applicable) - intercepts_tvp: List of time-varying intercepts for TVP models (if applicable)
Takes the output of cv.multivar() and reselects the best penalty
scenario using the Extended Bayesian Information Criterion (EBIC) or
standard BIC. This can improve structure recovery (fewer false positives)
compared to prediction-based cross-validation, especially when n >> p.
select_by_ebic(fit, gamma = 0.5)select_by_ebic(fit, gamma = 0.5)
fit |
Output of |
gamma |
EBIC tuning parameter. |
A modified copy of fit with:
mats |
Transition matrices from the EBIC-selected scenario |
ebic |
Named list: |
The original MSFE results are preserved.
Default show method for an object of class multivar
## S4 method for signature 'multivar' show(object)## S4 method for signature 'multivar' show(object)
object |
|
Displays the following information about the multivar object:
To do.
Prints a summary of a fitted multivar model, including dataset information, model specifications, and key results.
summary_multivar(fit)summary_multivar(fit)
fit |
A fitted multivar object (output from cv.multivar()) |
Invisibly returns the input object
# fit <- cv.multivar(object) # summary_multivar(fit)# fit <- cv.multivar(object) # summary_multivar(fit)
Checks internal consistency of a matrix_spec object.
validate_matrix_spec(spec)validate_matrix_spec(spec)
spec |
A matrix_spec object |
TRUE if valid, otherwise throws an error
Simulate a time-varying VAR model (piecewise or continuous)
var_sim_tvp( n, sigma, phi_list, T_per_period = NULL, mat_tvp = NULL, type = c("piecewise", "continuous"), burn = 500, intercept = 0 )var_sim_tvp( n, sigma, phi_list, T_per_period = NULL, mat_tvp = NULL, type = c("piecewise", "continuous"), burn = 500, intercept = 0 )
n |
Integer. Total time series length. |
sigma |
Matrix. Innovation covariance matrix (d x d). |
phi_list |
List of d x d transition matrices. For piecewise: one per period. For continuous: one base matrix. |
T_per_period |
Integer vector. Observations per period (piecewise only). If NULL, periods are equal length. |
mat_tvp |
Logical matrix (d x d). Which elements are time-varying (continuous only). |
type |
Character. Either "piecewise" or "continuous". |
burn |
Integer. Burn-in period to discard. Default 500. |
intercept |
Intercept term. Can be: - Scalar (same for all variables and periods) - Vector of length d (different per variable, constant over periods) - List of vectors (different per period, for piecewise TVP) |
List with components:
data |
List containing the T x d data matrix |
mat_ind_final |
List containing the true transition matrices (list of period matrices) |
T_per_period |
Observations per period |
breaks |
Break points for period changes |
intercept |
Intercept values used |
# Piecewise TVP phi1 <- matrix(c(0.3, 0, 0, 0.3), 2, 2) phi2 <- matrix(c(0.3, 0.2, 0, 0.3), 2, 2) sim <- var_sim_tvp(n = 200, sigma = diag(2), phi_list = list(phi1, phi2), T_per_period = c(100, 100), type = "piecewise") # Piecewise with period-specific intercepts sim <- var_sim_tvp(n = 200, sigma = diag(2), phi_list = list(phi1, phi2), T_per_period = c(100, 100), type = "piecewise", intercept = list(c(1, 0), c(2, 1)))# Piecewise TVP phi1 <- matrix(c(0.3, 0, 0, 0.3), 2, 2) phi2 <- matrix(c(0.3, 0.2, 0, 0.3), 2, 2) sim <- var_sim_tvp(n = 200, sigma = diag(2), phi_list = list(phi1, phi2), T_per_period = c(100, 100), type = "piecewise") # Piecewise with period-specific intercepts sim <- var_sim_tvp(n = 200, sigma = diag(2), phi_list = list(phi1, phi2), T_per_period = c(100, 100), type = "piecewise", intercept = list(c(1, 0), c(2, 1)))