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: