--- title: "6. Bayesian VAR and DSEM" output: rmarkdown::html_vignette: toc: true bibliography: references.bib link-citations: true vignette: > %\VignetteIndexEntry{6. Bayesian VAR and DSEM} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", message = FALSE, warning = FALSE, fig.width = 7, fig.height = 5.5 ) library(idiographic) data(srl) has_cograph <- requireNamespace("cograph", quietly = TRUE) ``` `fit_var_bayes()` estimates a single-person Bayesian vector autoregression of order one: an idiographic model, fitted to one individual's multivariate series, in which each occasion's measurements are predicted jointly by the values of all variables one occasion earlier and by the associations that remain among the variables within the same occasion. The estimands are the same two within-person networks the ordinary VAR of `fit_var()` returns. The temporal network is directed: an edge `from -> to` states that the value of `from` at occasion $t-1$ predicts the value of `to` at occasion $t$, holding the other lagged variables constant. The contemporaneous network is undirected: its edges are the partial correlations among the innovations, the within-occasion associations that lagged prediction does not account for. The Bayesian estimator places priors on the lagged coefficients and the innovation covariance and reports posterior distributions over these same quantities, so each edge carries a credible interval rather than a point estimate alone. The model presumes weak stationarity — constant mean, variance, and autocovariance across the observation window — linear lag-one dynamics, approximately Gaussian fluctuations, and equally spaced measurement occasions. `fit_mlvar_bayes()` and `fit_mlvar_mplus()` estimate the multilevel analogue, the Bayesian multilevel VAR in its dynamic structural equation modelling (DSEM) formulation. Where the single-person model describes one individual, the multilevel model pools a panel of individuals and separates the variance into layers: a population-level average within-person temporal network, a population-level average within-person contemporaneous network, and a between-person network — a partial-correlation network over the subject means, describing how people who are high on one variable on average tend to differ on the others. The between layer is a structure of stable individual differences, not a within-person process, and the two need not coincide; treating between-person associations as if they described anyone's dynamics is the ergodicity error the idiographic literature warns against. `fit_mlvar_mplus()` targets the Mplus DSEM backend for laboratories with a licensed Mplus installation that require its syntax and diagnostics; `fit_mlvar_bayes()` estimates a native model whose explicitly documented slices are validated against frozen Mplus outputs without requiring the external dependency. Bayesian estimation is appropriate when posterior intervals, prior regularization, or DSEM-style modelling is central to the analysis; when the goal is a fast point-estimate comparison, `fit_var()` and `fit_mlvar()` provide that baseline. The native Bayesian chunks below are evaluated during the build, so every printed result comes from the displayed call. Only the external Mplus call remains unevaluated because it requires licensed software. # Data and preprocessing The estimators expect long format: one row per person-occasion, an id column, and numeric time-varying indicators ordered within person. The bundled `srl` data hold self-regulated-learning indicators for 36 students measured over 156 occasions each. The single-person calls fit one student, Grace, on five indicators; the multilevel calls use the full panel of 36 students on the same variables. Because the estimators absorb assumption violations silently — a trend, for instance, inflates the autoregressive diagonal rather than producing an error — the stationarity screen precedes the fit. ```{r vars-audit} vars <- c("efficacy", "value", "planning", "monitoring", "effort") preprocess(srl, vars = vars, id = "name", subject = "Grace") ``` Grace's 156 ordered occasions yield 155 complete current/lagged pairs, and no series trips a trend, high-autoregression, drift, unit-root, or zero-variance flag, so the models are specified on the series as they stand. # Fitting the model The single-person call takes the data, the variable set, the id column, and the subject; `n_iter` sets the chain length, `n_chains` the number of chains, and `seed` fixes the random state for reproducibility. ```{r fit-var-bayes} var_bayes_fit <- fit_var_bayes( srl, vars = vars, id = "name", subject = "Grace", n_iter = 1000, n_chains = 2, seed = 1 ) var_bayes_fit ``` The evaluated fit uses two chains, retains 1,000 posterior draws after burn-in, and reports a maximum potential scale reduction statistic close to 1. No temporal 95% credible interval excludes zero in this run. The multilevel Bayesian call uses the same panel structure as `fit_mlvar()`. Setting `temporal = "fixed"` estimates the average lag-one matrix without subject-specific random deviations; `n_iter`, `n_chains`, and `seed` control the MCMC as before. ```{r fit-mlvar-bayes} mlvar_bayes_fit <- fit_mlvar_bayes( srl, vars = vars, id = "name", temporal = "fixed", n_iter = 1000, n_chains = 2, seed = 1 ) mlvar_bayes_fit ``` The evaluated multilevel fit also retains 1,000 posterior draws and has a maximum potential scale reduction statistic close to 1. Three of the 25 temporal 95% credible intervals exclude zero. The Mplus backend call is shown but not evaluated, because it requires the suggested `mlVAR` and `MplusAutomation` packages plus a licensed Mplus installation discoverable by `MplusAutomation::detectMplus()`. ```{r fit-mplus, eval=FALSE} mplus_fit <- fit_mlvar_mplus( srl, vars = vars, id = "name", temporal = "fixed", contemporaneous = "fixed" ) ``` # Reading the output The single-person posterior medians reproduce the ordinary VAR pattern. Monitoring at occasion $t-1$ predicts lower value at occasion $t$ (posterior median −0.121), planning predicts higher effort (0.107), and the largest contemporaneous edge is monitoring–effort (0.465). None of the temporal credible intervals excludes zero, so these medians are descriptive rather than evidence of selected temporal paths. The same accessors that serve the point-estimate fits apply: `summary()` reports one row per network layer, `edges()` lists edges in decreasing magnitude, `nodes()` gives node-level strength, and `matrices()` returns the underlying posterior-median matrices. ```{r output-var-bayes} summary(var_bayes_fit) edges(var_bayes_fit, n = 12) nodes(var_bayes_fit) matrices(var_bayes_fit) ``` The Bayesian mlVAR fit gives a temporal mean absolute weight of 0.015, a contemporaneous mean absolute weight of 0.165, and a between-person mean absolute weight of 0.205 in this panel. Monitoring at occasion $t-1$ to effort at occasion $t$ is the largest average temporal edge (posterior median 0.033). Planning–effort is the largest contemporaneous edge (0.274), and efficacy–planning is the largest between-person edge (0.548) — a statement about which students report high efficacy and high planning on average, not about either process unfolding within any student. ```{r output-mlvar-bayes} summary(mlvar_bayes_fit) edges(mlvar_bayes_fit, n = 12) nodes(mlvar_bayes_fit) matrices(mlvar_bayes_fit) ``` The `plot()` method draws the layers with the same conventions as the other estimators: arrows for lag-one prediction in the temporal panel, undirected edges for the contemporaneous and between layers, width scaled by absolute weight and colour encoding sign. ```{r plot-var-bayes, eval=has_cograph} plot(var_bayes_fit) plot(var_bayes_fit, layer = "temporal") plot(var_bayes_fit, layer = "contemporaneous") ``` ```{r plot-mlvar-bayes, eval=has_cograph} plot(mlvar_bayes_fit) plot(mlvar_bayes_fit, layer = "temporal") plot(mlvar_bayes_fit, layer = "contemporaneous") plot(mlvar_bayes_fit, layer = "between") ``` The evaluated calls remove the gap between displayed code and reported output, but they are still examples rather than a universal MCMC prescription. Applied analyses require problem-specific chain lengths, convergence diagnostics, posterior predictive checks, and sensitivity analyses over the priors. `fit_mlvar_mplus()` additionally depends on an external Mplus installation, so it is demonstrated only as a call template. # References