MyNixOS website logo
Description

Probing, Plotting, and Interpreting Multilevel Interaction Effects.

Provides a unified workflow for probing, plotting, and assessing the robustness of cross-level interaction effects in two-level mixed-effects models fitted with 'lme4' (Bates et al., 2015) <doi:10.18637/jss.v067.i01>. Implements simple slopes analysis following Aiken and West (1991, ISBN:9780761907121), Johnson-Neyman intervals following Johnson and Fay (1950) <doi:10.1007/BF02288864> and Bauer and Curran (2005) <doi:10.1207/s15327906mbr4003_5>, and grand- or group-mean centering as described in Enders and Tofighi (2007) <doi:10.1037/1082-989X.12.2.121>. Includes a slope variance decomposition that separates fixed-effect uncertainty from random-slope variance (tau11), a contour surface plot of predicted outcomes over the full predictor-by-moderator space, and robustness diagnostics comprising intraclass correlation coefficient shift analysis and leave-one-cluster-out (LOCO) stability checks. Designed for researchers in education, psychology, biostatistics, epidemiology, organizational science, and other fields where outcomes are clustered within higher-level units.

mlmoderator

R-CMD-check Lifecycle: stable

Robustness diagnostics and visualization tools for cross-level interaction effects in multilevel models.

mlmoderator provides a unified workflow for probing, plotting, and assessing the robustness of two-way interaction effects in mixed-effects models fitted with lme4::lmer(). It is designed for researchers in education, psychology, biostatistics, epidemiology, organizational science, and any field where outcomes are clustered within higher-level units.


Installation

# Development version from GitHub
remotes::install_github("causalfragility-lab/mlmoderator")

Core functions

FunctionDescription
mlm_center()Grand- or group-mean center variables
mlm_probe()Simple slopes at selected moderator values
mlm_jn()Johnson-Neyman significance regions
mlm_plot()Publication-ready interaction plot
mlm_surface()Contour plot of predicted outcomes over pred x modx space
mlm_summary()Consolidated moderation report
mlm_variance_decomp()Decompose slope uncertainty into fixed vs random components
mlm_sensitivity()ICC-shift robustness + leave-one-cluster-out (LOCO) diagnostics

Usage examples

Education: SES x School Climate

library(mlmoderator)
library(lme4)

data(school_data)

# Center variables
dat <- mlm_center(school_data, vars = "ses",     cluster = "school", type = "group")
dat <- mlm_center(dat,         vars = "climate",                      type = "grand")

# Fit model
mod <- lmer(math ~ ses_c * climate_c + gender + (1 + ses_c | school),
            data = dat, REML = TRUE)

# Simple slopes at -1 SD, Mean, +1 SD of school climate
mlm_probe(mod, pred = "ses_c", modx = "climate_c")
#>  climate_c  slope    se      t   df      p ci_lower ci_upper
#>     -1.036  0.944 0.145  6.504 2995 < .001    0.659    1.228
#>      0.000  1.426 0.101 14.075 2995 < .001    1.228    1.625
#>      1.036  1.909 0.144 13.277 2995 < .001    1.627    2.191

# Johnson-Neyman interval
jn <- mlm_jn(mod, pred = "ses_c", modx = "climate_c")
print(jn)
plot(jn)

# Interaction plot
mlm_plot(mod,
         pred         = "ses_c",
         modx         = "climate_c",
         x_label      = "Student SES (group-mean centred)",
         y_label      = "Mathematics Achievement",
         legend_title = "School Climate")

# Contour surface - predicted math over the full ses x climate space
mlm_surface(mod, pred = "ses_c", modx = "climate_c")

# Full summary report
mlm_summary(mod, pred = "ses_c", modx = "climate_c")

# Variance decomposition: fixed-effect CI vs prediction interval
vd <- mlm_variance_decomp(mod, pred = "ses_c", modx = "climate_c")
print(vd)
plot(vd)

# Robustness diagnostics: ICC shift + LOCO
sens <- mlm_sensitivity(mod, pred = "ses_c", modx = "climate_c")
print(sens)
plot(sens)

Biostatistics / Clinical Trials: Treatment x Baseline Severity

Does the effect of a treatment vary depending on how severe the patient's condition was at baseline? Patients are nested within hospitals.

# mod <- lmer(
#   recovery ~ treatment * baseline_severity + age + comorbidity +
#     (1 + treatment | hospital),
#   data = trial_data
# )

# Where does the treatment effect become significant?
# mlm_jn(mod, pred = "treatment", modx = "baseline_severity")

# How stable is this across hospitals?
# sens <- mlm_sensitivity(mod, pred = "treatment", modx = "baseline_severity")
# plot(sens)  # LOCO panel shows hospital-level influence

# How much of the treatment slope variation is unexplained by severity?
# vd <- mlm_variance_decomp(mod, pred = "treatment", modx = "baseline_severity")
# print(vd)   # % random tells you how much tau11 remains after conditioning on severity

Epidemiology: Individual SES x Neighborhood Deprivation

Does individual socioeconomic status moderate the effect of neighborhood deprivation on BMI? Individuals nested within neighborhoods.

# mod <- lmer(
#   bmi ~ neighborhood_deprivation * individual_ses + age + smoking +
#     (1 + individual_ses | neighborhood),
#   data = health_data
# )

# Full predicted BMI surface over the deprivation x SES space
# mlm_surface(mod,
#             pred    = "individual_ses",
#             modx    = "neighborhood_deprivation",
#             x_label = "Individual SES",
#             y_label = "Neighborhood Deprivation Index")

# Contour rotation reveals where the cross-level interaction is strongest

Organizational Psychology: Workload x Leadership Quality

Does leadership quality buffer the effect of workload on burnout? Employees nested within teams.

# mod <- lmer(
#   burnout ~ workload * leadership + tenure + role +
#     (1 + workload | team),
#   data = org_data
# )

# At what level of leadership quality does workload stop predicting burnout?
# mlm_jn(mod, pred = "workload", modx = "leadership")

# Are results driven by specific teams?
# sens <- mlm_sensitivity(mod, pred = "workload", modx = "leadership",
#                         verbose = TRUE)
# plot(sens)  # LOCO panel flags influential teams

Economics / Policy: Education x Regional GDP

Does regional economic development moderate the return to education in wages? Workers nested within regions.

# mod <- lmer(
#   log_wage ~ education * regional_gdp + experience + sector +
#     (1 + education | region),
#   data = labor_data
# )

# Contour surface: predicted log wage over education x regional GDP
# mlm_surface(mod,
#             pred         = "education",
#             modx         = "regional_gdp",
#             legend_title = "log(Wage)",
#             x_label      = "Years of Education",
#             y_label      = "Regional GDP per capita (standardised)")

Neuroscience / fMRI: Age x Task Difficulty

Does task difficulty moderate the age-related decline in neural activation? Observations nested within subjects.

# mod <- lmer(
#   bold_signal ~ age * task_difficulty + motion + session +
#     (1 + age | subject),
#   data = fmri_data
# )

# Simple slopes: age effect at low, medium, high task difficulty
# mlm_probe(mod, pred = "age", modx = "task_difficulty",
#           modx.values = "tertiles")

# Variance decomp: is the age slope variable across subjects
# beyond what task difficulty explains?
# vd <- mlm_variance_decomp(mod, pred = "age", modx = "task_difficulty")
# print(vd)

Model requirements

RequirementDetail
Model classlmerMod from lme4::lmer()
InteractionTwo-way: pred * modx or pred : modx in fixed effects
OutcomeContinuous (linear mixed model)
ClusteringAny single grouping variable
PredictorsContinuous x continuous, or continuous x binary

Scope of sensitivity analysis

mlm_sensitivity() provides robustness diagnostics, not a full causal sensitivity analysis:

  • ICC-shift: how does the interaction SE and JN boundary change if the intraclass correlation were different?
  • LOCO: does the interaction hold when each cluster is dropped in turn? Which clusters are most influential?

A level-2 omitted variable bound specifically designed for cross-level interactions is under development as a separate methodological contribution. Standard OLS-based sensitivity tools (E-value, ITCV) are not appropriate for multilevel interaction effects and are intentionally excluded.


Citation

If you use mlmoderator in your research, please cite:

Hait, S. (2026). mlmoderator: Robustness Diagnostics and Visualization
for Cross-Level Interaction Effects in Multilevel Models.
R package version 0.2.0.
https://github.com/causalfragility-lab/mlmoderator

Or in BibTeX:

@Manual{mlmoderator,
  title  = {mlmoderator: Robustness Diagnostics and Visualization
            for Cross-Level Interaction Effects in Multilevel Models},
  author = {Subir Hait},
  year   = {2026},
  note   = {R package version 0.2.0},
  url    = {https://github.com/causalfragility-lab/mlmoderator}
}

License

MIT.

Metadata

Version

0.2.1

License

Unknown

Platforms (80)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    uefi
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-freebsd
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64-uefi
  • aarch64-windows
  • aarch64_be-none
  • arc-linux
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-linux
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • sh4-linux
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-uefi
  • x86_64-windows