Skip to contents

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) and boldness ~ x + (1 | id)). Random-effect bar groups shared between the two declare the higher-level corpair edge.

rho12

Optional one-sided formula (e.g. ~ x) giving predictors of the residual correlation on its link (tanh) scale — a directed path into the rho12 component. NULL (default) declares a constant residual correlation.

family, family2

drmTMB/stats families for the two responses. family2 defaults to family (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; NA suppresses the corpair edge (residual rho12 only).

names

Optional length-2 character vector of node names, defaulting to the two response labels.

Value

A drm_pair declaration object.

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().