Skip to contents

dyadMLM provides tools for dyadic multilevel modeling with linear and generalized linear mixed-effects models. It validates and prepares cross-sectional and intensive longitudinal dyadic data.

It supports distinguishable and exchangeable dyads and can also prepare datasets containing multiple dyad compositions. It creates composition-aware, model-ready columns for dyadic multilevel model parameterizations such as the Actor-Partner Interdependence Model (APIM), Dyad-Individual Model (DIM), and Dyadic Score Model (DSM).

Selected post-estimation tools compare compatible fitted models and back-transform exchangeable random-effect covariance structures into member-level quantities.

Start with the vignettes, or scroll down for a quick-start.

Vignette Focus
Getting Started Data structure, validation, dyad compositions, generated columns, and basic preparation
Actor-Partner Interdependence Model APIM preparation and formulas for distinguishable and exchangeable dyads in cross-sectional and intensive longitudinal data
Dyad-Individual Model DIM predictor construction, formulas, and an interactive demonstration of APIM-DIM equivalence for exchangeable dyads
Dyadic Score Model DSM predictor-score and contrast construction, formulas, and the relationship between the DSM and APIM for distinguishable dyads

For an in-depth tutorial covering data preparation, model fitting, diagnostics, and assumption checks, see Distinguishable and Exchangeable Dyads: Bayesian Multilevel Modelling. It uses dyadMLM for cross-sectional and intensive longitudinal APIM and DIM workflows, with models fitted primarily using brms (source, DOI).

Installation

You can install the released version of dyadMLM from CRAN with:

install.packages("dyadMLM")

You can install the development version from GitHub with:

# install.packages("pak")
pak::pak("Pascal-Kueng/dyadMLM")

Simple Cross-Sectional Example

Prepare distinguishable dyads for a cross-sectional APIM:

library(dyadMLM)

prepared_data <- prepare_dyad_data(
  dyads_cross,
  dyad = coupleID,
  member = personID,
  role = gender,
  predictors = provided_support,
  model_types = "apim",
  # All three observed compositions in `dyads_cross` are detected and retained by
  # default. This example focuses on `female-male` dyads, so we restrict the
  # analysis here.
  keep_compositions = "female-male"
)

print(prepared_data, n = 4)
#> # dyadMLM data
#> # Rows: 240 | Dyads: 120 | Intensive longitudinal: no
#> # Structure: dyad = coupleID, member = personID, role = gender
#> #
#> # Dyad compositions:
#> # female_x_male distinguishable 120 dyads
#> #
#> # Added columns:
#> #   .dy_composition       inferred dyad composition
#> #   .dy_composition_role  composition-specific member role
#> #   .dy_is_{comp-role}    composition-role indicator columns
#> #   .dy_{pred}_actor      APIM actor predictor: actor's original predictor
#> #                         values
#> #   .dy_{pred}_partner    APIM partner predictor: partner's original predictor
#> #                         values
#> #
#> # A tibble: 240 × 12
#>   personID coupleID gender dyad_composition closeness provided_support
#>      <int>    <int> <fct>  <fct>                <dbl>            <dbl>
#> 1        1        1 female female_x_male         4.77             4.49
#> 2        2        1 male   female_x_male         4.46             4.76
#> 3        3        2 female female_x_male         6.44             4.09
#> 4        4        2 male   female_x_male         5.99             6.20
#> # ℹ 236 more rows
#> # ℹ 6 more variables: .dy_composition <fct>, .dy_composition_role <fct>,
#> #   .dy_is_female_x_male_female <dbl>, .dy_is_female_x_male_male <dbl>,
#> #   .dy_provided_support_actor <dbl>, .dy_provided_support_partner <dbl>

The prepared data contains the composition indicators and APIM actor/partner predictor columns used in the model formulas below.

One simple distinguishable APIM formula is:

simple_apim <- glmmTMB::glmmTMB(
  closeness ~

    # Gender-specific intercepts
    0 + .dy_is_female_x_male_female + .dy_is_female_x_male_male +

    # Gender-specific actor effects
    .dy_provided_support_actor:.dy_is_female_x_male_female +
    .dy_provided_support_actor:.dy_is_female_x_male_male +

    # Gender-specific partner effects
    .dy_provided_support_partner:.dy_is_female_x_male_female +
    .dy_provided_support_partner:.dy_is_female_x_male_male +

    # Dyad-level random effects represent the two members'
    # residual covariance structure
    us(0 + .dy_is_female_x_male_female + .dy_is_female_x_male_male | coupleID),

  # With the residual covariance represented by the dyad-level
  # random effects above, the Gaussian residual dispersion is fixed near zero.
  dispformula = ~ 0,
  family = gaussian(),
  data = prepared_data
)

Citation

If you use dyadMLM, please cite the package directly:

@Manual{dyadMLM,
  title = {dyadMLM: Tools for Dyadic Multilevel Models},
  author = {Pascal Küng},
  year = {2026},
  note = {R package version 0.1.0},
  doi = {10.5281/zenodo.21481720},
  url = {https://github.com/Pascal-Kueng/dyadMLM},
}

The package uses the concept DOI 10.5281/zenodo.21481720 across releases.


Continue with the Getting Started Vignette.

Or go directly to a model-specific vignette: