MMRM in SAS: Step-by-Step
/*-----------------------------*
| 0) Housekeeping (optional) |
*-----------------------------*/
ods trace on;
options nolabel;
/*-----------------------------*
| 1) Fit the MMRM |
*-----------------------------*/
proc mixed data=xxx(where=(0<vsn<=96)) order=data;
class usubjid trtc vsn genotype;
/* Fixed effects */
model chg =
trtc|vsn /* trtc, vsn, and trtc*vsn */
base*vsn
b_age*vsn
genotype*vsn
/ solution ddfm=kr;
/* Repeated measures (UN covariance) */
repeated vsn / subject=usubjid type=un;
/* Precision/analytic weights (e.g., ATT) */
weight _attwgt_;
/* LSMEANS with visit-wise EC – Internal study differences */
lsmeans trtc*vsn / diff cl slice=vsn;
/* Overall (average over visits) treatment difference */
estimate 'EC vs Internal study (average over VSN)' trtc 1 -1;
/* Visit-specific EC – Internal study contrasts
Ensure the CLASS order for VSN matches 24,48,72,96.
*/
contrast 'EC – Internal study @ 24w'
trtc 1 -1
trtc*vsn 1 0 0 0 -1 0 0 0;
contrast 'EC – Internal study @ 48w'
trtc 1 -1
trtc*vsn 0 1 0 0 0 -1 0 0;
contrast 'EC – Internal study @ 72w'
trtc 1 -1
trtc*vsn 0 0 1 0 0 0 -1 0;
contrast 'EC – Internal study @ 96w'
trtc 1 -1
trtc*vsn 0 0 0 1 0 0 0 -1;
/* Global joint test across visits (multi-df Wald) */
contrast 'Global treatment difference across visits'
trtc 1 -1 trtc*vsn 1 0 0 0 -1 0 0 0,
trtc 1 -1 trtc*vsn 0 1 0 0 0 -1 0 0,
trtc 1 -1 trtc*vsn 0 0 1 0 0 0 -1 0,
trtc 1 -1 trtc*vsn 0 0 0 1 0 0 0 -1;
/* Capture outputs for TLFs/QC */
ods output
lsmeans = lsm_vsn_trt
diffs = dif_vsn_trt
covparms = cov_un
estimates = est_tests;
run;
ods trace off;
What each step does (and how to read it)
-
PROC MIXED & CLASS
Declares the repeated-measures factors.order=dataensures your visit order (e.g., 24, 48, 72, 96) is used when constructing contrasts and LSMeans. -
MODEL statement
-
trtc|vsnfits treatment, visit, and their interaction, so the treatment effect can differ by visit (core of MMRM). -
base*vsn,b_age*vsn,genotype*vsnallow covariate effects to vary by visit (common in SAPs for longitudinal change). -
ddfm=kruses Kenward–Roger degrees of freedom (better small-sample properties). -
solutionprints estimates for all fixed effects (useful for QC, usually not reported directly).
-
-
REPEATED with TYPE=UN
Sets an unstructured covariance for within-subject residuals—maximally flexible (variance and correlation free to vary by visit pair). Appropriate when N allows, and convergence is stable. -
WEIGHT attwgt
Applies precision (analytic) weights (e.g., ATT weights from propensity modeling). Larger weights imply smaller residual variance and more influence.
Tips: ensure weights are positive; consider trimming/stabilizing extreme weights; rerun as sensitivity with trimmed weights. -
LSMEANS trtc*vsn / diff cl slice=vsn
Produces visit-specific EC–Mission differences with CIs and p-values without hand-coding coefficients. This is the easiest, least error-prone way to get per-visit effects. -
ESTIMATE 'EC vs Mission'
Gives an average treatment difference across visits under the model; often de-emphasized when the interaction is present (interpret with care). -
CONTRAST (per visit)
Explicitly reconstructs EC–Mission at a given visit using the cell-means coding fortrtcandtrtc*vsn. Functionally matches theSLICE=VSNresults; useful for an auditable, fixed set of inferential statements. -
Global joint test (multi-df)
The comma-separatedCONTRASTforms a Wald test that all visit-specific EC–Mission differences are zero simultaneously. Report the F/χ², df, and p-value as your global longitudinal treatment test. -
ODS OUTPUT
-
lsm_vsn_trt: LSMeans for each (trtc, vsn) cell (good for figures). -
dif_vsn_trt: Per-visit differences with SE, t, CI, p (table/forest). -
cov_un: the estimated UN covariance (check plausibility, convergence). -
est_tests: rows for ESTIMATE/CONTRAST (per-visit and global tests).
-
Interpretation + QC checklist
-
Primary readouts: table from
dif_vsn_trt(EC–Mission at 24/48/72/96 weeks) and the Global test fromest_tests. -
Convergence & fit: in the PROC MIXED log and
cov_un; if UN struggles, consider CSH or ARH(1) as sensitivity. -
Missing data: MMRM assumes MAR given included covariates. If dropout is meaningful, plan MI/tipping-point sensitivity.
-
Level order safety: Ensure VSN levels are in the intended order (use
order=dataand pre-sort your dataset). -
Weights: Inspect distribution; consider stabilized ATT, trimming (e.g., 1st–99th percentile).
-
Multiplicity: Report both per-visit results and the global joint test to support the overall claim.
Comments
Post a Comment