Fits Bayesian copula vector autoregressive models for bivariate
time series with dynamic, regime-switching, and constant dependence
structures. The package includes simulation, data preparation,
estimation with 'Stan' through 'rstan' or 'cmdstanr', posterior
summaries, diagnostics, trajectory extraction, fitted and predictive
summaries, and approximate leave-one-out cross-validation model
comparison for supported fits. For Bayesian computation and model
comparison, see Carpenter et al. (2017)
dcvar fits Bayesian copula vector autoregressions of order one for bivariate time series. The modelling idea is to keep two questions separate: how each series is distributed on its own, and how the two series move together. A copula carries the dependence, so each margin may follow its own distribution while a single association parameter describes how the series are coupled at a given time.
The conditional mean follows a first-order vector autoregression, so each series depends on the recent past of both. The innovations are joined by a Gaussian copula, with a Clayton copula also available for the constant baseline. The association can be held constant, allowed to drift smoothly as a random walk, allowed to switch between latent regimes, or expressed as a function of covariates. In the dynamic model the autoregressive coefficients and the innovation scales may vary over time as well; in the HMM model, the regime can also govern the intercepts, autoregressive coefficients, innovation scales, and marginal families. Everything is estimated in a fully Bayesian way through Stan, which returns posterior distributions for all quantities.
Two further families, a multilevel version for panel data and a structural-equation version for latent processes, are provided as experimental extensions.
dcvar uses rstan as its default backend.
Install dcvar from CRAN:
install.packages("dcvar")
For the development version:
install.packages("remotes")
remotes::install_github("benlug/dcvar")
Optionally, you can use cmdstanr as an
alternative backend:
install.packages(
"cmdstanr",
repos = c("https://stan-dev.r-universe.dev", getOption("repos"))
)
cmdstanr::install_cmdstan()
For skew-normal margins, install sn:
install.packages("sn")
The example below simulates a bivariate series whose association declines over time, fits the dynamic copula model, and compares it with the regime-switching and constant-association alternatives by cross-validation.
library(dcvar)
# simulate data with decreasing coupling
sim <- simulate_dcvar(
n_time = 150,
rho_trajectory = rho_decreasing(150, rho_start = 0.7, rho_end = 0.3)
)
# fit the DC-VAR model
fit <- dcvar(sim$Y_df, vars = c("y1", "y2"))
# inspect results
summary(fit)
plot_rho(fit, true_rho = sim$true_params$rho)
# compare models via leave-one-out cross-validation
fit_hmm <- dcvar_hmm(sim$Y_df, vars = c("y1", "y2"), K = 2)
fit_con <- dcvar_constant(sim$Y_df, vars = c("y1", "y2"))
dcvar_compare(dcvar = fit, hmm = fit_hmm, constant = fit_con)
The core models differ in how dependence, marginal distributions, and the vector-autoregressive mean are allowed to change over time.
| Model | Function | Association over time | Status |
|---|---|---|---|
| DC-VAR | dcvar() |
Drifts smoothly as a random walk on the Fisher z scale; the autoregressive coefficients and innovation scales may also drift | Core |
| HMM Copula | dcvar_hmm() |
Switches between K latent regimes | Core |
| Constant Copula | dcvar_constant() |
Held constant (Gaussian or Clayton) | Core |
| Covariate DC-VAR | dcvar_covariate() |
A function of observed covariates on the Fisher z scale | Core |
| Multilevel | dcvar_multilevel() |
Series-specific autoregressive coefficients across many units | Experimental |
| SEM | dcvar_sem() |
Latent processes measured by observed indicators | Experimental |
Because the copula keeps the margins separate from the dependence, every model
accepts per-variable margins. Pass a length-two vector such as
margins = c("normal", "exponential") to let each series follow a different
marginal family. The single-level models dcvar(), dcvar_hmm(), and
dcvar_constant() with a Gaussian copula support all four families (normal,
exponential, skew-normal, and gamma), used on their own or in combination.
dcvar_multilevel() and dcvar_sem() support all four families as a single
family or in combination.
dcvar_constant(copula = "clayton") provides a Clayton-copula baseline with
normal or mixed margins.
In dcvar(), the association always evolves over time. Setting tv_phi = TRUE
additionally lets the autoregressive coefficients drift as random walks, and
tv_sigma = TRUE lets the innovation scales drift. tv_phi also accepts
"ar" or "cross" to let only the autoregressive or only the cross-lagged
coefficients vary. With both options off, the model reduces to the
constant-coefficient dynamic copula.
In dcvar_hmm(), switch = "rho" gives the classic regime-switching copula
model, where only the copula correlation changes by latent state. Passing
components such as switch = c("rho", "mu", "phi", "sigma") fits a fuller
Markov-switching VAR(1). The HMM can also use state-specific marginal families
by passing a length-K list to margins; hmm_state_params() extracts the
effective state-specific intercepts, VAR matrices, scale parameters, and
families.
Fitted and one-step-ahead predicted values are available for every fitted
model. For multilevel fits these are specific to each unit; for
structural-equation fits they cover both the latent states (type = "link")
and the observed indicators (type = "response").
Leave-one-out cross-validation through loo() is available for the
single-level fits, the covariate fits, the multilevel fits, and the naive
structural-equation score fits, and dcvar_compare() places several fits on a
common predictive scale. Comparisons that mix model families whose pointwise
predictive densities are not on the same footing are flagged with a warning.
Residual checks based on the probability integral transform, pit_values() and
pit_test(), are provided for the single-level models. They use posterior
means and are best read as heuristic checks rather than exact calibration
tests. Posterior predictive checks through plot_ppc() are available for
normal and exponential margins; gamma and skew-normal fits do not yet store
replicated residuals on the observed margin scale.
The package also includes a constant Clayton-copula baseline, a multilevel model with exponential margins, and naive structural-equation score models that were used in the accompanying simulation studies.
If you use dcvar in your work, cite it with:
citation("dcvar")