drm_pair() records a bivariate node: two responses to be fitted jointly
with a residual correlation rho12 (the within-observation coupling that
remains after each response's mean and scale), optionally modelled as a
function of predictors (rho12 ~ x, a directed path into the correlation
component), and — when the two response formulas share a grouping level — a
higher-level random-effect correlation (corpair). It is the bivariate
counterpart of drm_node().
Usage
drm_pair(
formula1,
formula2,
rho12 = NULL,
family = stats::gaussian(),
family2 = family,
level = NULL,
names = NULL
)Arguments
- formula1, formula2
Two two-sided response formulas (e.g.
activity ~ x + (1 | id)andboldness ~ x + (1 | id)). Random-effect bar groups shared between the two declare the higher-levelcorpairedge.- rho12
Optional one-sided formula (e.g.
~ x) giving predictors of the residual correlation on its link (tanh) scale — a directed path into therho12component.NULL(default) declares a constant residual correlation.- family, family2
drmTMB/statsfamilies for the two responses.family2defaults tofamily(a homogeneous bivariate node).- level
Higher-level (
corpair) grouping.NULL(default) auto-detects grouping factors common to both formulas; a string forces a specific level;NAsuppresses thecorpairedge (residualrho12only).- names
Optional length-2 character vector of node names, defaulting to the two response labels.
Details
Declaration here; the joint fit happens in drm_sem(). drm_pair()
validates the two-response node and bridges it onto the covariance-edge
grammar (covary() / covariances()), so the residual (rho12) and
higher-level (corpair) arcs are reported separately from paths() and
respected by basis_set() / dsep(). Passing the pair to drm_sem() fits
one joint drmTMB bivariate model (biv_gaussian() / biv_lognormal() /
biv_student()) and rho12() / corpairs() then read the fitted
coefficients back. An unfitted declaration still reports estimate = NA;
drm_pair() never fabricates a correlation. See
docs/design/07-bivariate-covariance-edges.md.
References
Shipley B (2016). Cause and Correlation in Biology: A User's Guide to Path Analysis, Structural Equations and Causal Inference with R, 2nd edition. Cambridge University Press, Cambridge.
Bollen KA (1989). Structural Equations with Latent Variables. Wiley, New York.
Brooks ME, Kristensen K, van Benthem KJ, Magnusson A, Berg CW, Nielsen A, Skaug HJ, Maechler M, Bolker BM (2017). “glmmTMB Balances Speed and Flexibility Among Packages for Zero-Inflated Generalized Linear Mixed Models.” The R Journal, 9(2), 378–400. doi:10.32614/RJ-2017-066 .
Examples
# A bivariate node: two responses sharing an `id` grouping, with the residual
# correlation itself modelled as a function of `x`.
pair <- drm_pair(
activity ~ x + (1 | id),
boldness ~ x + (1 | id),
rho12 = ~ x
)
pair
#>
#> ── <drm_pair> bivariate node "activity" & "boldness"
#> activity [gaussian]: `activity ~ x + (1 | id)`
#> boldness [gaussian]: `boldness ~ x + (1 | id)`
#> residual correlation: rho12 ~ x [directed path into rho12]
#> higher-level correlation: corpair at 1 level ("id")
#> declaration only; pass this pair to drm_sem() for a joint bivariate fit
rho12(pair) # declared residual edge (estimate NA until drm_sem() fits)
#> <residual correlation (rho12): 1 edge>
#> y1 y2 term estimate std.error statistic p.value link predictors
#> activity boldness <NA> NA NA NA NA tanh x
#> constant
#> FALSE
#> estimate NA: declaration only; fit the pair with drm_sem() or pass a bivariate
#> drmTMB fit to drm_psem().
corpairs(pair) # declared higher-level edge at the shared `id` level
#> <higher-level correlation (corpair): 1 edge>
#> level y1 y2 estimate std.error p.value
#> id activity boldness NA NA NA
#> estimate NA: declaration only; fit the pair with drm_sem() or pass a bivariate
#> drmTMB fit to drm_psem().