Mixed Model for Repeated Measures (MMRM) in RWE
A likelihood-based longitudinal model for a continuous outcome measured at categorical visits, treating time as a factor with an unstructured within-subject residual covariance and no random effects, yielding visit-specific treatment contrasts that are valid under missing-at-random without explicit imputation.
In plain language
A Mixed Model for Repeated Measures (MMRM) is a statistical method for analyzing a continuous outcome — such as kidney function or a symptom score — that is measured at several scheduled clinic visits for every patient. Instead of throwing away data from patients who miss a visit, MMRM uses all the measurements that were recorded and makes a mathematically principled assumption (called missing-at-random) that the gap can be explained by what was already observed. The result is a single estimated difference between treatment groups at the visit you care about most, without ever making up numbers for the missing visits. One honest caveat: if patients tend to drop out precisely because they are getting worse — not just randomly — the missing-at-random assumption breaks and the estimate can be misleading.
The mixed model for repeated measures (MMRM) analyzes a continuous outcome (or change from baseline) measured longitudinally, modeling visit as a categorical factor and a treatment-by-visit interaction, with an unstructured (UN) within-subject residual covariance and — in its canonical form — no random effects. Because it is fit by (restricted) maximum likelihood on all available records, MMRM produces an asymptotically unbiased estimate of the visit-specific mean contrast (e.g., difference in change from baseline at the target visit) under missing-at-random (MAR) missingness, without imputing the missing values. In confirmatory trials MMRM is the FDA/EMA-default primary analysis for continuous longitudinal endpoints; this entry (`-rwe`) is specifically about what changes — and what breaks — when the same model is applied to real-world EHR, registry, or linked data where visits are not protocol-driven and the MAR assumption is far weaker.
Core estimand distinction
The MMRM estimand is a marginal (population-average) mean contrast at a pre-specified target visit — typically change from baseline at, say, month 12 — under a stated intercurrent-event strategy. With no random effects, the regression coefficients are marginal, so the treatment-by-visit term is interpreted as the average group difference at each visit, not a subject-specific trajectory effect. Critically, MMRM only addresses missing data; it does not define how intercurrent events (death, treatment discontinuation, disenrollment, switching) are handled. That is an estimand choice you must make explicitly: a treatment-policy estimand keeps post-event measurements and analyzes them; a hypothetical estimand treats post-event values as MAR-missing (the usual implicit MMRM behavior); a composite/while-on-treatment estimand redefines the variable. In RWE the most defensible default is to name the strategy per ICH E9(R1) and pair MMRM with sensitivity analyses, because death and disenrollment are often informative (MNAR), which MMRM silently mishandles. See `estimands-ate-att-intercurrent-events-rwe`.
Interpreting the output
Consider the worked example: 200 patients (Drug A vs Drug B) with eGFR measured at baseline, Month 3, Month 6, and Month 12. Drug A patients gain an average of 3.2 mL/min from baseline by Month 12; Drug B patients lose an average of 3.2 mL/min. The MMRM yields an adjusted mean difference at Month 12 of 6.4 mL/min (95% CI 4.1 to 8.7 mL/min) favoring Drug A, based on all 200 patients who contributed at least one post-baseline measurement — including patients who missed one intermediate visit.
Formal interpretation: The arm-by-visit interaction term at Month 12 is the primary result. It estimates the average difference in eGFR change from baseline between the two arms at Month 12 under the missing-at-random assumption: patients who missed the Month 6 visit are included using information borrowed from their own observed trajectory via the unstructured within-person residual covariance. This is a marginal (population- average) contrast — no random patient effects enter the model — valid under MAR without imputation. It is not a subject-specific prediction for any individual patient.
Practical interpretation: Drug A patients gain approximately 6.4 mL/min more eGFR by Month 12 than Drug B patients on average. This is the per-visit contrast the FDA/EMA recognize as the primary longitudinal endpoint estimand for continuous outcomes under MAR. Because MAR is an assumption that cannot be verified — patients may drop out because their eGFR is worsening — the primary analysis should always be paired with a sensitivity analysis under MNAR assumptions (delta-adjusted or reference-based multiple imputation, or a tipping-point analysis).
Pros, cons, and trade-offs
- vs a linear mixed model with random slopes (`mixed-effects-models-longitudinal-rwe`): MMRM treats time as categorical with a UN residual covariance and no random effects, making no assumption about the shape of the mean trajectory; the LMM imposes a parametric trajectory (random intercept/slope) and is more efficient if that shape is right and far more robust to irregular/continuous visit timing. Prefer MMRM for a small fixed set of nominal visits where the trajectory shape is unknown and a clean per-visit contrast is wanted; prefer the LMM when visits are irregularly timed (the RWE norm), when you need a slope/rate-of-change estimand, or when UN is unestimable. - vs GEE (`gee-population-average-models-rwe`): Both target a marginal mean. The decisive difference is missingness: MMRM is likelihood-based and valid under MAR; standard GEE is moment-based and valid only under MCAR unless it is inverse-probability-weighted. Since real-world dropout is rarely MCAR, prefer MMRM for incomplete continuous Gaussian outcomes; reserve GEE for non-Gaussian outcomes (binary/count) or when a working-correlation, design-based interpretation is wanted. - vs multiple imputation + ANCOVA (`multiple-imputation-longitudinal-rwe`): MMRM handles MAR implicitly and only MAR. MI is explicit and extends naturally to MNAR sensitivity (pattern-mixture, delta/reference-based imputation, tipping-point). Prefer MMRM as the primary MAR analysis; add MI/delta-adjustment as the required sensitivity layer when informative dropout is plausible — which, in RWE, it almost always is. - vs joint longitudinal–survival models: When dropout is driven by a terminal event (death) correlated with the outcome, MMRM's MAR assumption fails and the visit-specific mean among survivors is a biased/ill-defined target. Joint models (or a survivor-average causal estimand) address this; MMRM does not.
When to use
A continuous, repeatedly measured outcome on a small set of nominal (categorical) visits — serial HbA1c or eGFR, weight/BMI, blood pressure, PHQ-9/PROMIS or other PRO scores in `pro-rwe` programs, registry-collected HRQoL feeding QALY mapping — where missingness is plausibly MAR conditional on observed history and treatment, and the estimand is a per-visit mean difference. MMRM is the natural primary analysis when you want the FDA/EMA-recognized approach and can bin records to a defensible visit grid.
When NOT to use — and when it is actively misleading or dangerous
- Irregular, continuous-time visit timing with no meaningful nominal grid. Forcing real-world encounters into "month 3 / month 6" windows when patients are seen on idiosyncratic schedules either discards information or mislabels measurements; UN covariance becomes meaningless. Use a continuous-time LMM (random slopes / spline in time) instead — and stop calling it MMRM. - Terminal events / competing risk of death. If sicker patients die and drop out, the among-survivors mean MMRM estimates drifts toward the healthy and the treatment contrast is biased. This is the single most dangerous misuse in elderly or oncology RWE; MAR does not hold and MMRM gives a confidently wrong number. - Differential measurement frequency by arm. When one arm is monitored more intensively (sicker patients have more contact), the observed data process differs by exposure and MAR conditional on a misspecified mean model fails. - Non-Gaussian or bounded/floor-ceiling outcomes (counts, heavily skewed costs, scores piled at the boundary): MMRM's normality and constant-variance-within-visit assumptions break; use GLMM/GEE or a transformation. - The real question is a rate of change or a subject-specific trajectory — MMRM's per-visit contrasts do not answer it; use an LMM with random slopes.
Data-source operational depth
- Claims (FFS / MA / commercial): Claims rarely contain a true repeated continuous clinical outcome — there is no serial HbA1c or eGFR, only diagnosis/procedure/cost events. Attempting MMRM on a claims-derived "continuous" series (e.g., monthly cost, which is non-Gaussian and zero-inflated) violates the model's assumptions. Where claims are used, the danger is that "missing visit" is actually disenrollment (MA-only person-time lacks FFS claims; a plan switch looks like loss to follow-up) or death, both informative — restrict to continuously enrolled, FFS-observable person-time (`continuous-enrollment-observable-time-rwe`) and treat post-disenrollment values as MNAR in sensitivity, not silently MAR. - EHR (the typical MMRM-in-RWE substrate): Serial labs/vitals/PROs exist, but capture is encounter-driven, so measurement times are irregular and differential by health status — the core threat to both the visit grid and MAR. Bin to clinically meaningful windows (e.g., ±45 days around nominal quarters), pre-specify which record represents a visit when several fall in a window (closest-to-target vs last), and treat a patient who leaves the system as potentially informatively missing. Baseline is often itself a derived/last-observation value — document how it was constructed because change-from-baseline inherits its error. - Registry: Strongest for scheduled, adjudicated repeated outcomes (serial disease severity, PROs at protocol visits), giving the cleanest nominal grid for MMRM — but registry completeness erodes over time and dropout correlates with disease progression and death (informative). Link to a death index and to claims to distinguish true MAR loss from terminal-event loss. - Linked EHR–claims–vital records: The ideal MMRM substrate — EHR supplies the continuous serial outcome, claims confirm continuous observability and treatment exposure, and the death index lets you correctly classify terminal dropout as a competing event rather than MAR missingness. Reconcile measurement, enrollment, and death dates before assigning visits.
Worked example (linked EHR + claims)
Question: change from baseline in eGFR over 12 months among new initiators of drug A vs active comparator B for type 2 diabetes, using EHR labs linked to medical/pharmacy claims. (1) Cohort: active-comparator new-user design — first fill of A or B (`fill_date`, `days_supply`, NDC) with 365 days of prior continuous medical + pharmacy enrollment and FFS-observable person-time; `index_date` = first fill. (2) Outcome series: all serum-creatinine→eGFR results from the linked EHR with `result_date` between index and month 12. (3) Visit grid: nominal visits at baseline, 3, 6, 9, 12 months; assign each eGFR to the visit whose target it is nearest, within a ±45-day window; if multiple results fall in a window, keep the one closest to the target date; baseline eGFR = the value nearest to (and within 45 days before/on) `index_date`. (4) Analysis variable: change from baseline eGFR at each post-baseline visit. (5) Model: MMRM with fixed effects for arm, visit (categorical), arm×visit, baseline eGFR, and pre-index covariates, and an unstructured residual covariance within `person_id`; the primary contrast is the arm difference in eGFR change at month 12. (6) Missingness/intercurrent events: records after disenrollment (no FFS-observable person-time) or death (linked death index) are missing — pre-specify a hypothetical estimand (those values MAR-missing) for the primary analysis, then run delta-adjusted / reference-based MI and a tipping-point analysis assuming progressively worse unobserved eGFR in the active arm as MNAR sensitivity. (7) Diagnostics: report observed-data completion by arm and visit (a `missing-data-pattern-table-rwe`), check that attrition is not differential by arm, and confirm the UN covariance is estimable (it has V(V+1)/2 parameters for V visits — collapse to Toeplitz/AR(1) only if UN fails to converge).
Worked example
Scenario
A registry study enrolls 200 adults with type 2 diabetes starting either Drug A (n=100) or Drug B (n=100). Kidney function is measured as eGFR (a lab value in mL/min — higher is better) at four scheduled visits: baseline, Month 3, Month 6, and Month 12. Some patients miss one or two visits. The question is: what is the treatment-group difference in eGFR change from baseline at Month 12? The analyst uses MMRM so that patients with a missing Month 6 visit are not dropped from the analysis entirely.
Dataset
Observed mean eGFR by arm and visit (all enrolled patients who had at least one post-baseline measurement; n shown = patients with a recorded value at that visit).
| visit | arm | mean_egfr | n_observed | mean_change_from_baseline |
|---|---|---|---|---|
| Baseline | Drug A | 62.0 | 100 | |
| Baseline | Drug B | 61.8 | 100 | |
| Month 3 | Drug A | 63.5 | 94 | 1.5 |
| Month 3 | Drug B | 60.9 | 96 | -0.9 |
| Month 6 | Drug A | 64.1 | 89 | 2.1 |
| Month 6 | Drug B | 59.7 | 88 | -2.1 |
| Month 12 | Drug A | 65.2 | 82 | 3.2 |
| Month 12 | Drug B | 58.6 | 79 | -3.2 |
Steps
Each row in the analysis dataset is one patient at one visit; patients who missed a visit simply have no row for that visit — they are not dropped from the dataset entirely.
MMRM fits a single model that includes fixed effects for arm (Drug A vs Drug B), visit (Baseline / Month 3 / Month 6 / Month 12 as categories), and the arm-by-visit interaction, plus each patient's baseline eGFR as a covariate.
The unstructured covariance lets the model learn from each patient's own observed trajectory — so a patient seen at Baseline, Month 3, and Month 12 still contributes information about Month 6 through the estimated within-person correlations.
MMRM does NOT fill in the missing Month 6 value with the last observed reading (that older approach, called LOCF, assumes the outcome stayed flat, which is rarely true); instead it uses maximum likelihood to borrow information across all visits without inventing data.
The primary result is read from the arm-by-visit interaction term at Month 12: the estimated difference in mean change from baseline between Drug A and Drug B at that visit.
Result
MMRM estimates Drug A patients gained an average of 3.2 mL/min in eGFR from baseline by Month 12, while Drug B patients lost an average of 3.2 mL/min — a treatment difference of 6.4 mL/min (95% CI: 4.1 to 8.7 mL/min) favoring Drug A at the final visit. All 200 patients who had at least one post-baseline measurement contributed to this estimate, including the 18 Drug A patients and 21 Drug B patients who missed one intermediate visit.
Runnable example
python implementation
Fit an MMRM-style model in long format. Required input (one row per person per captured visit, after binning real-world measurements to a nominal grid): df : person_id, arm ('A'/'B'), visit (ordered categorical: 'm3','m6','m9','m12'), chg (change from...
import pandas as pd
import statsmodels.formula.api as smf
def fit_mmrm_approx(df: pd.DataFrame):
"""Approximate MMRM via a random-intercept LMM (statsmodels lacks true UN residual covariance).
Treats visit as categorical and includes the arm-by-visit interaction (the MMRM estimand)."""
df = df.copy()
df["visit"] = pd.Categorical(df["visit"], categories=["m3", "m6", "m9", "m12"], ordered=True)
df["arm"] = pd.Categorical(df["arm"], categories=["B", "A"]) # B = reference
# arm*visit gives the per-visit treatment contrast; adjust for baseline and covariates.
model = smf.mixedlm(
"chg ~ arm * C(visit) + base",
data=df,
groups=df["person_id"], # within-person clustering (random intercept approximation)
re_formula="1",
)
res = model.fit(reml=True, method="lbfgs")
# Primary contrast = arm[A]:C(visit)[m12] (treatment difference in change at month 12).
return resr implementation
True unstructured-covariance MMRM with the FDA-aligned `mmrm` package (and an nlme::gls equivalent shown in comments). Required input (long format, one row per person per nominal visit): df : person_id (factor), arm (factor, reference = comparator), visit...
library(mmrm)
df$person_id <- factor(df$person_id)
df$visit <- factor(df$visit, levels = c("m3", "m6", "m9", "m12"))
df$arm <- relevel(factor(df$arm), ref = "B") # comparator = reference
# Canonical MMRM: arm*visit fixed effects, baseline adjustment, UNSTRUCTURED residual covariance us(visit | id).
fit <- mmrm(
formula = chg ~ arm * visit + base + us(visit | person_id),
data = df,
reml = TRUE
)
summary(fit) # arm[A]:visit[m12] row = treatment difference in change from baseline at month 12
# nlme equivalent (unstructured corr + heterogeneous variance by visit):
# library(nlme)
# fit_gls <- gls(chg ~ arm * visit + base, data = df,
# correlation = corSymm(form = ~ as.integer(visit) | person_id),
# weights = varIdent(form = ~ 1 | visit),
# na.action = na.omit, method = "REML")