Skip to contents

mlumr implements Multilevel Unanchored Meta-Regression (ML-UMR), a population-adjusted indirect treatment comparison method for disconnected evidence networks. ML-UMR extends Multilevel Network Meta-Regression (ML-NMR; Phillippo et al., 2020) to the unanchored setting, where individual patient data (IPD) are available for one treatment and only aggregate data (AgD) are available for the comparator, with no common reference arm (e.g. comparison of single arm studies). In this setting, mlumr estimates treatment effects while adjusting for cross-trial differences in prognostic factors.

In terms of the software, mlumr is an adaptation of the GPL-3 licensed multinma package, which provides functionality for conducting ML-NMR and NMAs. mlumr uses similar Sobol quasi-Monte Carlo and Gaussian-copula integration machinery to marginalize over the comparator-population covariate distribution, and extends the implementation with Stan likelihoods for the unanchored two-treatment problem, including SPFA and relaxed-SPFA models for binomial, normal, and Poisson outcomes.

The package provides three complementary methods within a unified interface:

  • ML-UMR (Bayesian): SPFA and Relaxed SPFA models via Stan, with quasi-Monte Carlo integration and Gaussian copula for population adjustment
  • STC (Frequentist): Simulated treatment comparison via parametric G-computation with delta-method standard errors
  • Naive (Benchmark): Unadjusted comparison of crude outcome summaries
Family Outcome type Link functions
Binomial Binary (0/1) logit (default), probit, cloglog
Normal Continuous identity (default), log
Poisson Count + exposure log (default)

Installation

Development version

# install.packages("remotes")
remotes::install_github("choxos/mlumr")

Prerequisites

mlumr uses Stan for Bayesian model fitting. The default backend is rstan, with Stan model C++ code generated by rstantools and compiled during package installation. A C++ toolchain is required:

  • macOS: Install Xcode Command Line Tools (xcode-select --install)
  • Windows: Install Rtools
  • Linux: Install g++ and make (usually available by default)

Optional: cmdstanr backend

Users who prefer cmdstanr can switch backends after installation:

# Switch to cmdstanr (will offer to install cmdstanr + CmdStan if needed)
mlumr_engine("cmdstanr")

# Switch back to rstan
mlumr_engine("rstan")

# Check current engine
mlumr_engine()

The engine preference persists for the current session. To set a permanent default, add to your .Rprofile:

options(mlumr.stan_engine = "cmdstanr")

You can also override the engine for a single model fit:

fit <- mlumr(dat, model = "spfa", engine = "cmdstanr")

When the package is attached with library(mlumr), it prints a short startup message with the installed version and GitHub repository.

Using mlumr alongside multinma

A subset of mlumr’s exported functions perform similar actions to their multinma counterparts and intentionally retain the same name (set_ipd(), set_agd(), add_integration(), unnest_integration(), distr(), marginal_effects(), qbern()/pbern()/dbern()). mlumr also exports several functions that are not available in multinma (mlumr(), naive(), stc(), combine_data(), check_integration(), conditional_effects(), conditional_predict(), prior_sensitivity(), calculate_dic()/loo()/waic(), compare_models()).

If both packages are attached in the same R session, R issues masking warnings on the shared names. The cleanest practice is to use only one package per session for any given analysis, matched to the network type (anchored connected → multinma; unanchored disconnected → mlumr). When you do need both attached (e.g. a methods-comparison sensitivity analysis), use the namespace prefix to disambiguate:

library(multinma)
library(mlumr)

# mlumr fits ML-UMR (disconnected, two-trial)
ipd_umr <- mlumr::set_ipd(ipd_df, treatment = "trt", outcome = "outcome",
                          covariates = c("age_group", "sex"))
fit_umr <- mlumr::mlumr(dat, model = "spfa")

# multinma fits ML-NMR (connected network)
net_nmr <- multinma::set_ipd(pso_ipd, study = studyc, trt = trtc, r = pasi75)
fit_nmr <- multinma::nma(net_nmr, regression = ~ age:.trt)

Quick start

library(mlumr)
set.seed(2026)

# --- Prepare IPD (index treatment) ---
n_A <- 500
ipd_df <- data.frame(
  trt = "Drug_A",
  outcome = rbinom(n_A, 1, 0.55),
  age_group = rbinom(n_A, 1, 0.40),
  sex = rbinom(n_A, 1, 0.55)
)

ipd <- set_ipd(ipd_df, treatment = "trt", outcome = "outcome",
                     covariates = c("age_group", "sex"))

# --- Prepare AgD (comparator) ---
agd_df <- data.frame(
  trt = "Drug_B", n_total = 400, n_events = 148,
  age_group_mean = 0.35, sex_mean = 0.50
)

agd <- set_agd(agd_df, treatment = "trt",
                     outcome_n = "n_total", outcome_r = "n_events",
                     cov_means = c("age_group_mean", "sex_mean"),
                     cov_types = c("binary", "binary"))

# --- Combine and add integration points ---
dat <- combine_data(ipd, agd)
dat <- add_integration(dat, n_int = 64,
  age_group = distr(qbern, prob = age_group_mean),
  sex = distr(qbern, prob = sex_mean)
)

# --- Run all three methods ---
# Naive (instant)
naive_result <- naive(dat)

# STC (instant)
stc_result <- stc(dat)

# ML-UMR SPFA (Bayesian, takes a few minutes)
fit <- mlumr(dat, model = "spfa",
             prior_intercept = prior_normal(0, 10),
             prior_beta = prior_normal(0, 2.5),
             chains = 4, iter = 4000, warmup = 2000, seed = 42)

summary(fit)
marginal_effects(fit, effect = "lor")

Methods overview

Feature ML-UMR SPFA ML-UMR Relaxed STC Naive
Covariate adjustment Joint model Joint model Outcome regression None
Effect modification Assumed absent Estimated Not captured N/A
Uncertainty Posterior Posterior Delta method Delta method
Population weighting QMC integration QMC integration G-computation None
Speed Minutes Minutes Sub-second Sub-second
Integration points required Yes Yes Optional No

Key functions

Function Purpose
set_ipd(), set_agd() Prepare IPD and AgD with outcome and covariate specification
combine_data() Combine IPD and AgD into a unified dataset
add_integration() Generate QMC integration points with Gaussian copula
mlumr() Fit ML-UMR SPFA or Relaxed model via Stan
mlumr_engine() Get or set the Stan backend (rstan or cmdstanr)
naive(), stc() Frequentist benchmark methods
predict() Population-specific predicted outcomes
marginal_effects() Posterior treatment effect summaries
conditional_effects() Covariate-conditional treatment effects
conditional_predict() Predictions at specific covariate values
calculate_loo(), calculate_waic(), calculate_dic(), compare_models() Bayesian model comparison (LOO-CV, WAIC, DIC)

When to use ML-UMR

Method Data required Type of ITC Pairwise only Type of treatment effect Target population
MAIC IPD + AgD Anchored or unanchored Yes Marginal Comparator
STC IPD + AgD Anchored or unanchored Yes Marginal Comparator
ML-NMR IPD + AgD Anchored No Marginal or conditional Any pre-specified target
ML-UMR IPD + AgD Unanchored No Marginal or conditional Any pre-specified target

ML-UMR is most appropriate when:

  1. You have IPD for one treatment and AgD for the comparator
  2. No common reference arm connects the evidence (unanchored)
  3. Binary, continuous, or count outcomes are of interest
  4. Covariate distributions differ between trial populations

Vignettes

Detailed tutorials are available as package vignettes:

References

The ML-UMR methodology extends the ML-NMR framework:

Phillippo, D. M., Dias, S., Ades, A. E., Belger, M., Brnabic, A., Schacht, A., Saure, D., Kadziola, Z., & Welton, N. J. (2020). “Multilevel Network Meta-Regression for population-adjusted treatment comparisons.” Journal of the Royal Statistical Society: Series A, 183(3), 1189–1210. doi:10.1111/rssa.12579

Chandler, C. & Ishak, J. (2025). “Anchors Away: Navigating Unanchored Indirect Comparisons With Multilevel Unanchored Meta-Regression (ML-UMR).” ISPOR Europe 2025, MSR28. Value in Health, 28, S498. https://www.valueinhealthjournal.com/article/S1098-3015(25)05944-3/abstract

Chandler, C. & Ishak, J. (2026). “Surviving Unanchored Indirect Comparisons: An Extension of Multilevel Unanchored Meta-Regression (ML-UMR) for Survival Analyses.” ISPOR 2026, MSR131. Value in Health, 29(S6). https://www.ispor.org/heor-resources/presentations-database/presentation-cti/ispor-2026/poster-session-3-3/surviving-unanchored-indirect-comparisons-an-extension-of-multilevel-unanchored-meta-regression-ml-umr-for-survival-analyses

Citing mlumr

citation("mlumr")

Authors

Acknowledgments

Portions of the package code, documentation, and Stan models were drafted and audited with the assistance of large language models: Anthropic’s Claude Opus 4.6 and 4.7 (via Claude Code) and OpenAI’s ChatGPT 5.4 and 5.5 (via Codex). All methodological choices, design decisions, and the final review and validation were performed by the named authors, who take responsibility for the package’s contents.

License

GPL-3. See https://www.gnu.org/licenses/gpl-3.0 for the full license text.