BS
Biostatistics & Statistical Programming
MMRM / PROC MIXED · 培训与实施演示
SAS 9.4 M7+ ICH E9(R1)
Statistical Analysis · Training Deliverable

MMRM 在临床试验中的 SAS 实现

从 ADaM 长格式数据出发,逐参数拆解 PROC MIXED: 每一个关键词读走了数据里的哪一列、在数学上触发了哪一步运算、最终如何落到 TLF 表格。
Document TypeTraining / Demo
Version1.0
Data StandardADaM · BDS (ADQS)
SoftwareSAS 9.4 · PROC MIXED
Estimand FrameworkICH E9(R1)
CovarianceUnstructured (UN)
DF MethodKenward–Roger
Status示例数据 · 仅供培训
声明 本文档中所有受试者编号、数值、LS Means 与 p 值均为模拟示例,不代表任何真实研究结果, 不可用于任何提交材料。代码结构与参数含义按 SAS 官方文档核对,可直接迁移到真实项目。
Core Statement
5
CLASS / MODEL / REPEATED / LSMEANS / ESTIMATE,MMRM 的全部骨架
Cov Params (k=4, UN)
10
k(k+1)/2 —— UN 收敛难度的根源
Imputation Needed
0
MMRM 在 MAR 下用直接似然,不做任何填补
Reading Time
45min
建议顺序:§1 概念 → §2 动画 → §3 参数 → §6 模板

阅读导览

① 先看 §2 的联动动画

九步分解:点「下一步」,左边数据表的列会亮起,右边代码里对应的 token 同时亮起,中间用曲线连起来 —— 直观回答「这个参数到底在读哪一列」。

② 再看 §5 的参数沙盘

TYPE=DDFM=METHOD=、是否加交互项,代码实时重写,右侧同步显示「协方差参数个数 / 设计矩阵列数 / 自由度怎么算」。

③ 多队列项目直接看 §3.10 / §6.5

LSMESTIMATE 的系数定位器(点格子生成代码)、 方括号里到底填 level 序号还是变量值、Pooled 汇总组的 divisor=4−4, 以及 5 组 + Pooled 的完整生产代码。§9 是这次对话 32 问的逐条复盘。

§1

MMRM 是什么、为什么临床上偏爱它

Mixed Model for Repeated Measures

MMRM 是「对纵向重复测量数据做的、以访视为类别因子的、带受试者内相关结构的线性混合模型」。 它之所以成为慢病 / CNS / 免疫等长期随访试验主要疗效分析的默认方法,核心只有一句话: 它在 MAR 假设下用全部可观测数据做直接似然估计,不需要任何填补。

1.1 模型形式

设受试者 i 在访视 jj = 1…k)的相对基线变化为 Yij

Yij = μ + τt(i) + γj + (τγ)t(i)j + β·basei + εij,    εi ~ N(0, Σ)
符号SAS 里对应的写法含义与临床解读
τt(i)TRTP(CLASS)治疗主效应;单独看几乎不用,重点在交互项
γjAVISIT(CLASS)访视主效应 —— 访视按类别因子进模型,不假设时间上的线性/任何形状
(τγ)tjTRTP*AVISIT治疗×访视交互;这是 MMRM 的灵魂,它允许每个访视有各自的组间差
β·baseBASE(连续协变量)基线校正,提高精度;很多 SAP 还加 BASE*AVISIT,允许基线效应随时间衰减
ΣREPEATED … TYPE=UN受试者内 k×k 协方差矩阵;建模的是残差相关,不是随机效应
关键点 去掉 TRTP*AVISIT,模型就变成「所有访视共用同一个组间差」,你将拿不到分访视的 LS Mean 差值, 这与绝大多数 SAP 里「Week 24 的 LS mean difference」这一主要终点定义直接冲突。

1.2 为什么不是 LOCF / 不是逐访视 ANCOVA

方法缺失数据怎么处理受试者内相关 有效假设问题
LOCF把上一次观测值搬到后面所有访视被人为抹平 极强且不可检验方差被低估 → I 类错误膨胀;对退化性疾病系统性偏乐观。监管已基本不接受作为主分析
逐访视 ANCOVA
(Completers)
直接删掉缺失者完全忽略 MCAR只用完成者 → 选择偏倚;每个访视样本量不同,结果不可比
MMRM不填补,缺的行不进似然显式建模 Σ MAR需要预先指定协方差结构;UN 在小样本/多访视时可能不收敛
Multiple Imputation
+ ANCOVA
多重填补后合并在填补模型里 MAR(可扩展到 MNAR)步骤多、需 Rubin 合并;作为敏感性分析或 MNAR 情形的主力
监管 EMA《Guideline on Missing Data in Confirmatory Clinical Trials》(2010) 与 NRC (2010) 报告均明确批评了 「把单一填补当作保守方法」的做法。当前主流做法是:MMRM 作为主分析(MAR)+ 基于控制组的填补 / tipping point 作为 MNAR 敏感性分析

1.3 MMRM 与 Estimand 的关系(ICH E9(R1))

MMRM 本身只是一个估计方法,它对应哪个 estimand,取决于你把哪些数据放进模型:

Intercurrent Event 策略数据处理MMRM 的角色
Hypothetical
(若未停药)
停药后的数据不进模型(或本就没采集) 标准 MMRM。这是历史上最常见的 “efficacy / de jure” estimand
Treatment Policy
(不论是否停药)
停药后仍继续随访并采集,全部进模型 MMRM 仍可用,但缺失的是「本应采集却没采到」的部分;此时 MAR 更难成立,通常配合 retrieved dropout / 控制组填补
Composite停药本身编码为不良结局(如记为无应答)一般改用二分类模型,MMRM 不直接适用
While on treatment只用在治期间的观测MMRM 可用,但访视窗定义要重新设计
SAP 措辞 可直接引用的模板句:“Change from baseline in [endpoint] will be analysed using a restricted maximum likelihood (REML) based mixed model for repeated measures (MMRM). The model will include treatment, visit, treatment-by-visit interaction and [stratification factors] as fixed effects, with baseline value and baseline-by-visit interaction as covariates. An unstructured covariance matrix will be used to model the within-subject correlation; denominator degrees of freedom will be estimated using the Kenward-Roger approximation.”
§2

数据 ↔ 代码 联动演示

Which column does each keyword read?

左边是一份 ADaM BDS 长格式数据(3 名受试者 × 4 个访视,含 2 个缺失),右边是 MMRM 的完整代码。 点「下一步」逐步推进:亮起的列就是这一步真正被读取的数据,曲线连到代码里对应的关键字, 下方卡片解释这一步在数学上做了什么运算。

1 / 9
WORK.ADQS (分析数据集 · 长格式 BDS)
USUBJID TRTP AVISITN AVISIT BASE AVAL CHG
101-001Drug A4Week 422.020.5-1.5
101-001Drug A8Week 822.019.8-2.2
101-001Drug A16Week 1622.018.9-3.1
101-001Drug A24Week 2422.018.1-3.9
101-002Placebo4Week 424.023.6-0.4
101-002Placebo8Week 824.023.9-0.1
101-002Placebo16Week 1624.024.40.4
101-002Placebo24Week 2424.0..
101-003Drug A4Week 419.018.2-0.8
101-003Drug A8Week 819.0..
101-003Drug A16Week 1619.016.9-2.1
101-003Drug A24Week 2419.016.5-2.5
12 obs · 3 subjects · 2 obs 的响应变量缺失
mmrm_primary.sas
ods output LSMeans=lsm  Diffs=dif  CovParms=cov           SolutionF=fix Tests3=t3 ConvergenceStatus=cs; proc mixed data=ADQS method=REML;    class USUBJID TRTP AVISIT;    model CHG = BASE TRTP AVISIT TRTP*AVISIT / ddfm=KR solution cl;    repeated AVISIT / subject=USUBJID type=UN r rcorr;    lsmeans TRTP*AVISIT / diff cl alpha=0.05;run;
高亮行 = 当前步骤执行的语句 · 曲线 = 该关键字读取的数据列
STEP 1

读入分析数据集

§3

PROC MIXED 全参数解剖

Statement-by-statement reference

MMRM 只用到 PROC MIXED 的一小部分能力。下面按语句罗列,加粗的是临床项目里真正会用到的, 其余作为「知道它存在」的储备 —— 遇到审评问询或收敛问题时会派上用场。

3.1 语句总览

语句可重复作用MMRM 中的角色
PROC MIXED全局设置:估计方法、收敛、输出必需 METHOD=REML
CLASS声明分类变量必需 受试者、治疗、访视
MODEL固定效应(唯一必需语句)必需
REPEATEDR 侧:残差协方差结构必需 MMRM 的定义性语句
RANDOMG 侧:随机效应一般不用 见 3.6
LSMEANS最小二乘均值与两两差必需 主要终点来源
LSMESTIMATE对 LS Means 做自定义线性组合 多队列必需 Pooled 汇总组、加权对比 —— 见 §3.10
ESTIMATE任意线性组合 L′β(作用在参数上)常用 跨访视平均、特定对比
CONTRAST线性假设的 F 检验多剂量组整体检验
SLICE对 LS Means 做分片简单效应检验等价于 LSMEANS … / SLICE=,可单独成句
STORE把模型上下文存成 item store配 PROC PLM 事后再做对比,不必重跑模型
PARMS协方差参数初值 / 固定值救急 收敛失败时给初值
ID / BY / WEIGHT输出附带变量 / 分组运行 / 加权BY 用于亚组批量分析
PRIOR贝叶斯后验抽样基本不用
版本说明 LSMESTIMATESLICESTORE 是 SAS/STAT 9.22 起加入 PROC MIXED 的「共享语句」, 在 MIXED 里完全可用(很多老资料仍说它们只属于 GLIMMIX,那是 9.2 之前的情况)。 真正只在 GLIMMIX 里有的是 NLOPTIONS 语句和 COVTEST 语句 —— MIXED 的优化控制写在 PROC 语句选项上(MAXITER=CONVH=RIDGE=SCORING=), 协方差参数检验用 PROC 语句的 COVTEST 选项

3.2 PROC MIXED 语句选项

选项含义临床里怎么填
DATA=输入分析数据集通常带 (where=(ITTFL='Y' and ANL01FL='Y')),把分析集筛选写在这里最不容易出错
METHOD=REML / ML / MIVQUE0 / TYPE1‑3REML(默认)。REML 对协方差参数无偏,小样本更稳;ML 仅在需要用似然比检验比较固定效应时才用
CL协方差参数的置信限需要报告方差成分时加
COVTEST协方差参数的 Wald Z 检验参考价值有限(边界问题),一般不加
EMPIRICAL三明治(robust / sandwich)方差协方差结构可能设错时的敏感性分析;小样本会低估方差,谨慎
NOCLPRINT不打印 CLASS 水平清单USUBJID 有几百个水平时必加,否则 LST 爆炸;写 NOCLPRINT=20 可只压超过 20 水平的
NOITPRINT不打印迭代历史生产脚本常加;但调试收敛时要去掉
NOINFO / NOPROFILE抑制信息表 / 不剖面化残差方差NOPROFILE 偶尔能救回收敛
MAXITER= / MAXFUNC=最大迭代 / 函数求值次数默认 50 / 150;UN 多访视时可提到 200 / 1000
CONVH= / CONVF= / CONVG=收敛判据(Hessian 相对梯度 / 函数 / 梯度)默认 CONVH=1E‑8。放宽收敛判据来「制造收敛」在监管上是有风险的,需在 SAP 或注释中说明
RIDGE= / SCORING=岭因子 / 前 n 次迭代用 Fisher scoringSCORING=5 是最常见的救收敛手段之一
NOBOUND允许方差估计为负能让「边界上不收敛」变成收敛,但结果不再是合法协方差矩阵,主分析不建议
IC输出一整套信息准则比较协方差结构时方便
ORDER=CLASS 水平排序:FORMATTED / INTERNAL / DATA / FREQMMRM 里的高频坑,见 §8.1
ASYCOV / ASYCORR协方差参数估计的渐近协方差做 delta 方法推断时需要
PLOTS=ODS Graphics 诊断图PLOTS=(RESIDUALPANEL STUDENTPANEL) 做模型诊断

3.3 CLASS 语句

class
class USUBJID TRTPN(ref='0') AVISITN / order=internal;
  • USUBJID 必须在 CLASS 里(除非用 SUBJECT= 且它已是分类变量)—— 它定义了协方差矩阵的分块。
  • 访视必须是分类变量。把 AVISITN 当连续变量放进 MODEL,模型就变成线性斜率模型,不再是 MMRM。
  • (ref='...') 只在配合 MODEL … / SOLUTION 看参数估计时影响解读;LS Means 的差值不受参考水平影响(只影响符号方向的呈现方式,DIFF 输出里两个方向都能查到)。
  • 把 USUBJID 放在 CLASS 会打印几百行水平表 —— 配 NOCLPRINT

3.4 MODEL 语句

model
model CHG = BASE TRTPN AVISITN BASE*AVISITN TRTPN*AVISITN      / ddfm=KR solution cl alpha=0.05 residual outp=pred;
选项含义说明
DDFM=分母自由度算法见下方对照表,MMRM 的关键选项
SOLUTION | S打印固定效应参数估计QC 必看;主表一般不呈现
CL / ALPHA=固定效应的置信限默认 0.05
CHISQ额外给出 Wald 卡方检验大样本时与 F 检验接近
HTYPE= / E1 E2 E3假设检验类型(默认 Type 3)与系数打印MMRM 用 Type 3
COVB / CORRB固定效应估计的协方差 / 相关阵手工做 delta 方法或组合估计时需要
OUTP= / OUTPM=输出预测值:含随机效应 / 仅边际MMRM 只有 R 侧,两者基本一致;OUTPM 更贴近「群体平均」
RESIDUAL / VCIRY输出学生化、Cholesky 残差正态性与方差诊断
INFLUENCE影响诊断(Cook's D 等)INFLUENCE(EFFECT=USUBJID ITER=5) 找异常受试者
NOINT不含截距MMRM 不用

DDFM= 对照

取值做法是否调整 SE什么时候选
KENWARDROGER (KR)对固定效应协方差做偏倚校正,再算近似自由度 MMRM 的行业默认。小样本、UN 结构下 I 类错误控制最好。SAS 9.4 后可写 KR(LINEAR)KR2 变体
SATTERTHWAITE (SATTERTH)Satterthwaite 近似自由度 KR 太慢或不收敛时的替代;样本量大时与 KR 几乎一致
BETWITHIN (BW)把自由度拆成受试者间/内 REPEATED 模型的默认值。速度快,但小样本略激进
RESIDUAL残差自由度 = n − rank(X)会严重高估自由度,MMRM 不用
CONTAIN包含法(默认,用于 RANDOM 模型)MMRM 不用
要点 KR 与其他选项的本质区别在于 它同时修正了 SE:普通 REML 把 Σ 当作已知,低估了 Var(β̂); KR 加上了「因为 Σ 是估出来的」这部分不确定性。样本量越小、协方差参数越多(UN!),KR 的修正越重要。

3.5 REPEATED 语句 —— MMRM 的定义性语句

repeated
repeated AVISITN / subject=USUBJID type=UN r rcorr;* 每臂各估一套协方差(参数翻倍);repeated AVISITN / subject=USUBJID type=UN group=TRTPN;* 访视间隔不等时的空间幂结构:不写重复效应,给连续时间变量;repeated / subject=USUBJID type=sp(pow)(AWEEK);
成分含义与注意点
重复效应
(AVISITN)
决定 Σ 的行列顺序。必须是 CLASS 变量。它的水平顺序 = 矩阵的第 1…k 行 —— 对 AR(1)/TOEP 这类依赖「相邻」的结构顺序错了结果就错。同一受试者内不能有重复水平(会报 “subject … has repeated levels”)。
SUBJECT=定义分块:不同 SUBJECT 之间残差独立。可写成 subject=USUBJID,也可写 subject=SITE*SUBJID。数据建议按 SUBJECT 排序以提高效率。
TYPE=协方差结构,见 §4。默认 VC(即 σ²I,等价于不考虑相关)。
R / RCORR打印第一个受试者的 R 矩阵 / 相关阵。写 r=1,2,3 可指定第几个受试者。QC 时必看:能立刻发现维度或顺序不对。
GROUP=按组分别估协方差。参数个数 × 组数,收敛难度陡增;用于两组变异明显不同的情形。
LOCAL= / LOCALW在结构上再叠加异方差(如 local=exp(covariate)
SSCP / LDATA=用平方和叉积形式 / 从数据集读入结构

3.6 RANDOM vs REPEATED:G 侧与 R 侧

Vi = ZiGZi + Ri  (RANDOM 建 G,REPEATED 建 R

标准 MMRM:只用 R 侧

不写 RANDOM,直接令 Vi = Ri = Σ(UN)。 因为 UN 已经是最一般的 k×k 对称正定矩阵,再加随机截距不会增加任何拟合能力,只会造成参数不可识别 / 收敛失败

同时写 random intercept / subject=usubjid;repeated / type=un; 是常见错误。

什么时候才需要 RANDOM

  • 中心效应random intercept / subject=SITEID; 把中心作为随机效应(多中心试验的一种常见处理)
  • 随机斜率增长曲线模型(不是 MMRM):random intercept AWEEK / subject=usubjid type=un;
  • 此时 REPEATED 通常降为 type=VC 或不写

RANDOM 的常用选项:G GCORR V VCORR SOLUTION GROUP= TYPE= SUBJECT=

3.7 LSMEANS 语句

选项含义MMRM 中的用法
DIFF | PDIFF所有两两差;DIFF=CONTROL('0') 只对参照组 多剂量组时用 diff=control 省掉无关比较
CL / ALPHA=LS Mean 及其差值的置信限主表要报 95% CI,必加
SLICE=在指定因子的每个水平内做简单效应 F 检验slice=AVISITN 得到「每个访视内治疗效应」的 F 检验
AT把连续协变量固定在指定值at BASE=20;默认是总体均值
OM / BYLEVEL用观测边际权重代替等权各访视/各组样本量差异大时的替代加权方式
ADJUST=多重性调整:TUKEY / DUNNETT / BON / SIDAK / SIMULATE … SAP 若规定层级检验,一般在这里调整
E打印 L 矩阵核对 ESTIMATE 系数时的黄金工具
COV / CORRLS Means 之间的协方差手工合并多个访视的估计时需要
高频坑 lsmeans TRTP*AVISIT / diff; 会产出全部 C(8,2)=28 对两两比较,其中包含「A 组 Week 4 vs P 组 Week 24」这类无意义比较。 正确做法:从 Diffs 数据集里筛 where AVISIT = _AVISIT(同访视内比较),或用 ESTIMATE 精确指定。

3.8 ESTIMATE / CONTRAST:系数怎么数

ESTIMATE 的系数顺序 = CLASS 水平的排序;交互项按「左因子慢变、右因子快变」展开。以 class TRTPN AVISITN、TRTPN∈{0,1}、AVISITN∈{4,8,16,24} 为例:

效应系数位置(从左到右)
TRTPN[0] [1]
AVISITN[4] [8] [16] [24]
TRTPN*AVISITN[0,4] [0,8] [0,16] [0,24]  |  [1,4] [1,8] [1,16] [1,24]
estimate
/* Week 24 的组间差:Drug A(1) − Placebo(0) */estimate 'A - P @ Week 24'    TRTPN         -1  1    TRTPN*AVISITN 0 0 0 -1   0 0 0 1 / cl e; /* 跨 4 个访视的平均治疗效应(等权) */estimate 'A - P averaged over visits'    TRTPN         -4  4    TRTPN*AVISITN -1 -1 -1 -1   1 1 1 1 / divisor=4 cl;
为什么 BASE 的系数是 0 同一个访视下比较两个治疗组时,BASEBASE*AVISITN 在两个 LS Mean 里取值完全相同, 相减后自动抵消。所以即使模型里有基线交互项,ESTIMATE 里也不需要写它们。 永远用 / e 打印 L 矩阵,与 lsmeans … / diff 的结果核对一次。

3.9 ODS OUTPUT 可提取的数据集

ODS 表名内容下游用途
LSMeans各 TRTP×AVISIT 的 LS Mean、SE、DF、CI主表的「LS Mean (SE)」列
Diffs两两差值、SE、DF、tValue、Probt、CI主表的「Difference (95% CI), p」列;需筛同访视
ConvergenceStatusStatus(0=收敛)、Reason、pdG、pdH自动降级逻辑的判据
CovParms协方差参数估计QC、附录、结构比较
SolutionF固定效应参数估计QC
Tests3Type 3 固定效应检验(含交互项 p)报告 treatment-by-visit interaction
FitStatistics / InfoCrit−2 Res Log Lik、AIC、AICC、BIC协方差结构比较
R / RCorrR 矩阵与相关阵附录、QC
SlicesSLICE= 的简单效应 F 检验各访视内整体治疗效应
Estimates / ContrastsESTIMATE / CONTRAST 结果跨访视平均等自定义估计
NObs / Dimensions / ClassLevels观测数、维度、水平QC:核对进模型的记录数与受试者数
LSMEstimatesLSMESTIMATE 的估计、SE、DF、Probt、CIPooled 汇总组的结果出口

3.10 LSMESTIMATE 专题:Pooled 汇总组怎么算

这是多队列 / 多剂量试验(例如 1 个安慰剂 + 4 个队列)绕不开的语句。 LSMEANS 只能吐出模型里客观存在的水平;一旦 SAP 要求「Pooled Active」这种模型里根本不存在的组合, 就必须用 LSMESTIMATE 给 LS Means 做线性加权。

LSMEANS 能做的(直接用,别手写系数)

  • 每个 TRTN×AVISITN 单元格的 LS Mean
  • 各队列 vs 安慰剂的同访视差值(DIFF 后筛选)
  • 各访视内的简单效应 F 检验(SLICE=
5 组 × 3 访视的场景里,SAP 要的 11 项中有 9 项 LSMEANS 就能给。

只能用 LSMESTIMATE 的(2 项)

  • Pooled Active 的 LS Mean(4 个队列等权平均)
  • Pooled Active − Placebo 的差值(含正确的 SE、DF、p)
用 DATA 步把 4 个队列的 LS Mean 手工加起来除以 4:点估计对,SE 和 p 一定错 —— 合并估计的方差要用到 4 个 LS Means 之间的协方差,只有让 SAS 在 L′(X′V⁻¹X)⁻L 这一层算才对。

3.10.1 两种系数写法:位置向量 vs 名值对

写法形式要点
位置向量
(positional)
'label' 0 0 -1  0 0 1  0 0 0  … 必须写满 全部 g×k 个位置,顺序为「左因子慢变、右因子快变」。 新增一个访视 → 整套向量作废。数错一位不报错,只是算错。
名值对
(nonpositional)
'label' [1, 2 3] [-1, 1 3] 推荐 只写非零项,格式 [系数, 左因子level 右因子level]。 增删访视不影响已写好的语句。
最大的坑:方括号里填 level 序号,不是变量值 SAS 官方原文:“you enter the levels of the classification variables in the square brackets, not their formatted values.”
也就是说,若 AVISITN 的取值是 28 和 84,那么 Day 84 要写 2(它是第 2 个水平),写 84 会直接报错:
ERROR: level 84 is not valid for CLASS variable AVISITN.
       The level specifications for this variable must range from 1 to 2.
序号规则:把变量放进 CLASS → SAS 取所有唯一值 → 按 ORDER= 排序 → 从 1 编号。 数值变量默认升序(28→1,84→2);但只要挂了 FORMAT,默认 ORDER=FORMATTED 会按格式化文本排序, "Week 12" 会排到 "Week 4" 前面,序号直接颠倒。所以生产代码里请一律写 proc mixed … order=internal;,并用输出里的 Class Level Information 表复核。

3.10.2 系数定位器(点格子生成代码)

下面按「1 个安慰剂 + 4 个队列 × 3 个访视」布置。 点格子循环切换系数 0 → +1 → −1 → −4,右侧实时生成两种写法与对应数学式。 先点预设按钮看标准写法,再自己改。

Class Level Information(SAS 输出里的这张表就是序号的唯一依据)
ClassLevelsValues(从左到右 = Level 1,2,3…)
TRTN51  2  3  4  5
AVISITN314  28  84
名值对写法(推荐)
位置向量写法(15 个位置全写)

这条语句在算什么

3.10.3 为什么 Placebo 填 −4

目标是 (LSM2+LSM3+LSM4+LSM5)/4 − LSM1divisor=4 会把括号里所有系数一起除以 4,所以要让 Placebo 的有效系数等于 −1, 写进去的就必须是 −4(−4/4 = −1)。这样做的好处是括号里全是整数,既好读又避免浮点误差。 等价的小数写法是 [0.25,…] [−1, 1 3] 且不加 divisor。

3.10.4 LSMESTIMATE 的前置条件与 QC

条件说明 / 违反时的现象
效应变量必须在 CLASS 里否则 ERROR: Effect is not in CLASS
效应必须在 MODEL 里TRTN*AVISITN 就要求 MODEL 含该交互项;否则不可估
level 序号必须在 1…k 范围内超范围直接 ERROR(见上);范围内但填错则静默算错
交互项里 level 的先后顺序
必须与效应书写顺序一致
[1, 2 3] 中第一个 2 给 TRTN、第二个 3 给 AVISITN。写成 AVISITN*TRTN 含义就反了
对应单元格必须可估某队列在某访视一个人都没有 → 输出 Non-est
/ e必加 打印 L 矩阵系数表,逐格确认 −1 / +1 落在了正确的组与访视上
/ elsm额外打印参与计算的每个 LS Mean,方便手工验算差值
QC 流程 ① 先跑一遍只带 lsmeans TRTN*AVISITN;,记下 LS Means 表的行顺序; ② 用同样的 LSMESTIMATE 写一条已知能被 LSMEANS 算出的对比(如队列 1 vs Placebo); ③ 两边的 Estimate / StdErr / DF 必须逐位相同;④ 相同后,再信任 Pooled 那两条。

3.11 Diffs 数据集的方向:带下划线的就是被减数

Estimate = LSM(不带下划线的变量) − LSM(带下划线的变量)

把下划线 _ 记成减号,带 _ 的那一组就是被减掉的组。由此推出两条实用规则:

筛选条件实际算的是结果
where _TRTN=1 and AVISITN=_AVISITNActive − Placebo 正确diff=control 完全一致
where TRTN=1 and AVISITN=_AVISITNPlacebo − Active 符号反了 与上面互为相反数
另一个高频报错交互项DIFF=CONTROL('1') 会报:
ERROR: Wrong number of control levels for TRTN*AVISITN.
原因:效应里有 2 个 CLASS 变量,CONTROL 就必须给每个变量各一个水平。两条出路:
  • 要「各访视各自比当期安慰剂」(MMRM 最常见)→ 不要用 CONTROL,写 / pdiff cl, 再筛 _TRTN=1 and AVISITN=_AVISITN
  • 要把某一个格子当全局锚点/ pdiff=control('1' '84'), 注意这里填的是 变量的格式化值(84),与 LSMESTIMATE 方括号里填 level 序号正好相反
control('1' '84') 时,Diffs 里所有 AVISITN≠84 的行都是 「某组 Day 28 vs 安慰剂 Day 84」这种跨访视错位比较,临床上无意义,必须在后处理里删掉。
DIFF 与 PDIFF 两者是完全等价的别名,输出的 ODS 表、字段、数值一模一样。 PDIFF 不会「只给 p 值」,也不会自动做多重性调整 —— 调整由 ADJUST= 控制。 项目内保持一种写法即可。
§4

协方差结构实验室

TYPE= · what the matrix actually looks like

点选结构,右边的 4×4 矩阵会实时重画:格子颜色深浅 = 相关系数大小(同一色相由浅到深), 格子里是该结构对应的符号表达式。下方给出参数个数、SAS 写法和临床取舍。示例为 4 个访视(Week 4/8/16/24)。

Σ(4×4) ·「Unstructured
相关 0
1

4.1 结构对照总表

TYPE=参数个数
(k=4)
异方差假设临床取舍
UN10不做任何假设 首选 监管默认。访视多 (k≥6) 或每臂 < 50 例时易不收敛
UNR10同 UN,改用「方差+相关」参数化与 UN 等价拟合,收敛行为有时更好
TOEPH7相关只依赖访视间隔常用降级 1 保留异方差,参数少 3 个
ANTE(1)7一阶前依赖(相关沿时间累乘)纵向数据的自然结构,SAP 里偶见
CSH5方差随访视变,相关恒定常用降级 2
ARH(1)5方差随访视变,相关按间隔幂衰减访视等间隔时合理
UN(1)4对角,方差各异,不相关诊断用;不是真正的 MMRM
TOEP4同方差 + 带状相关少用
CS2方差恒定、任意两访视相关相同降级末端 等价于随机截距模型;对长期随访通常过强
AR(1)2相关按 ρ|i−j| 衰减要求等间隔访视
SP(POW)(t)2ρ|ti−tj|,真实时间距离 被低估 访视间隔不等(4/8/16/24 周)时,它才是 AR(1) 的正确版本
VC(默认)1σ²I,完全独立等价于逐访视 ANCOVA;忘了写 TYPE= 就会落到这里
最容易犯的错 repeated AVISITN / subject=USUBJID; —— 漏了 type=。SAS 不会报错, 它会安静地用 TYPE=VC(独立),你得到的其实是一个「加权 ANCOVA」,缺失机制的处理优势全部消失。

4.2 结构该怎么定?

确证性试验:SAP 预先指定 + 降级序列

不要用 AIC 在解盲后挑结构 —— 那是数据驱动的选择,会被质疑。 标准做法是在 SAP 里写死:UN → TOEPH → CSH → CS,按顺序尝试直到收敛,并在报告中说明实际使用的结构。

探索性 / II 期:可以比 AICC

用 REML 比较协方差结构时,固定效应必须完全相同; 比较固定效应则必须换成 ML。小样本优先看 AICC 而非 AIC。

§5

参数沙盘:填什么 = 算什么

Parameter sandbox

改动下面的选项,代码会实时重写,右侧同步显示这一组参数在数学上意味着什么运算量: 设计矩阵有几列、协方差要估几个参数、自由度怎么来、收敛风险多大。

生成的代码(实时)

      

这组参数让 SAS 做什么运算

§6

生产级代码模板

Production-ready macro with fallback

三段:① ADaM 侧的数据准备与分析集筛选;② 带收敛降级序列的 MMRM 宏;③ 结果整理成 TLF 可用结构。 可直接复制到项目里改参数。

6.1 数据准备(ADQS / ADVS 等 BDS 结构)

01_prep.sas
/*-- 分析集:ITT,主要参数,仅基线后访视,且有分析标记 --------------*/data work.anl;    set adam.adqs;    where PARAMCD = 'ADASTOT'      and ITTFL   = 'Y'      and ANL01FL = 'Y'          /* 每访视窗内只保留 1 条记录 */      and AVISITN gt 0            /* 排除基线访视本身          */      and not missing(BASE);      /* 无基线者无法进模型        */    keep USUBJID TRTPN TRTP AVISITN AVISIT BASE AVAL CHG SITEGR1 STRAT1;run; /*-- QC:核对进模型的记录数 / 受试者数 / 各访视 n ------------------*/proc sql;    create table qc_n as    select AVISITN, TRTP,           count(distinct USUBJID) as n_subj,           sum(case when missing(CHG) then 1 else 0 end) as n_miss    from work.anl group by 1,2;quit; /*-- 排序:SUBJECT 连续存放可显著加快 MIXED 的分块计算 -------------*/proc sort data=work.anl; by USUBJID AVISITN; run;
缺失的 CHG 记录不需要删 —— PROC MIXED 会自动跳过响应变量缺失的观测。但反过来, 「本该存在却根本没有那一行」和「有行但 CHG=.」对 MMRM 是等价的,都不进似然。 所以不必为了 MMRM 去补齐访视骨架(补齐只在做「按计划访视 n (%)」类汇总表时才需要)。

6.2 核心宏:UN → TOEPH → CSH → CS 自动降级

02_mmrm_macro.sas
/*--------------------------------------------------------------------*
 | MACRO  : %mmrm
 | PURPOSE: MMRM 主分析,按 SAP 预设顺序尝试协方差结构直至收敛
 | NOTE   : 实际使用的结构写入全局宏变量 &MMRM_STRUCT,需在报告中说明
 *--------------------------------------------------------------------*/%macro mmrm(data=work.anl, resp=CHG, base=BASE,            trt=TRTPN, trtref=0, visit=AVISITN, subj=USUBJID,            strat=, covseq=UN TOEPH CSH CS, ddfm=KR, alpha=0.05);   %global MMRM_STRUCT MMRM_CONV;  %local i nseq struct st done;  %let nseq = %sysfunc(countw(&covseq));  %let done = 0;   %do i = 1 %to &nseq;  %if &done = 0 %then %do;    %let struct = %scan(&covseq, &i);    %put NOTE: [MMRM] attempt &i -- TYPE=&struct;     /* ODS EXCLUDE ALL 抑制打印但保留 ODS OUTPUT 数据集 */    ods exclude all;    ods output LSMeans           = _lsm               Diffs             = _dif               CovParms          = _cov               SolutionF         = _fix               Tests3            = _t3               FitStatistics     = _fit               RCorr             = _rcorr               ConvergenceStatus = _cs;     proc mixed data=&data method=REML noclprint=20 noitprint                    maxiter=200 scoring=5;        class &subj &trt(ref="&trtref") &visit &strat;        model &resp = &base &trt &visit &strat                      &base*&visit &trt*&visit              / ddfm=&ddfm solution cl alpha=&alpha;        repeated &visit / subject=&subj type=&struct rcorr;        lsmeans &trt*&visit / diff cl alpha=&alpha;    run;    ods exclude none;     /* Status=0 表示收敛;同时要求 Hessian 正定 (pdH=1) */    %let st = 9;    proc sql noprint;        select max(Status) into :st from _cs;    quit;     %if &st = 0 %then %do;        %let done = 1;        %let MMRM_STRUCT = &struct;        %let MMRM_CONV   = CONVERGED;        %put NOTE: [MMRM] converged with TYPE=&struct;    %end;    %else %put WARNING: [MMRM] TYPE=&struct failed (Status=&st) -- 降级;  %end;  %end;   %if &done = 0 %then %do;      %let MMRM_CONV = FAILED;      %put %str(ER)ROR: [MMRM] 所有预设协方差结构均未收敛,请人工介入;  %end;%mend mmrm; %mmrm(data=work.anl, strat=STRAT1);

6.3 结果整理成 TLF 结构

03_tlf.sas
/*-- ① LS Mean(每组每访视) -------------------------------------*/data lsm_c;    set _lsm;    length col_lsm $24;    col_lsm = cats(put(Estimate,8.2),' (',put(StdErr,8.2),')');    keep TRTPN AVISITN Estimate StdErr DF Lower Upper col_lsm;run; /*-- ② 只保留「同一访视内 vs 参照组」的比较 ----------------------*
 |  Diffs 的 Estimate = LSM(TRTPN) - LSM(_TRTPN)
 |  故取 _TRTPN=0 即为「试验组 - 安慰剂」
 *---------------------------------------------------------------*/data dif_c;    set _dif;    where AVISITN = _AVISITN   /* 同访视        */      and _TRTPN  = 0;         /* 对照 = 安慰剂 */    length col_diff $34 col_p $10;    col_diff = cats(put(Estimate,8.2),' (',put(Lower,8.2),', ',                    put(Upper,8.2),')');    col_p    = put(Probt, pvalue6.4);    keep TRTPN AVISITN Estimate StdErr DF Lower Upper Probt col_diff col_p;run; /*-- ③ 脚注自动带上实际使用的协方差结构(合规要求) --------------*/%let fn1 = %str(Covariance structure actually used: &MMRM_STRUCT (&MMRM_CONV).); /*-- ④ 跨访视平均效应(若 SAP 需要) -----------------------------*/proc mixed data=work.anl method=REML noclprint;    class USUBJID TRTPN AVISITN;    model CHG = BASE TRTPN AVISITN BASE*AVISITN TRTPN*AVISITN / ddfm=KR;    repeated AVISITN / subject=USUBJID type=UN;    estimate 'A - P averaged over visits'             TRTPN         -4  4             TRTPN*AVISITN -1 -1 -1 -1   1  1  1  1             / divisor=4 cl e;run;

6.4 敏感性分析:MNAR 方向

04_sensitivity.sas
/*-- 基于对照组的填补 (Control-Based / J2R):把试验组退出者
    的后续走势拉回安慰剂组,是最常用的保守 MNAR 敏感性分析 --*/proc mi data=wide seed=20260812 nimpute=100 out=mi_out;    class TRTPN;    var TRTPN BASE W4 W8 W16 W24;    monotone reg(W4 W8 W16 W24 = TRTPN BASE);    mnar model(W4 W8 W16 W24 / modelobs=(TRTPN='0'));  /* 用安慰剂组建模 */run; /*-- 再逐个填补集跑 ANCOVA / MMRM,最后用 MIANALYZE 合并 --*/proc mianalyze data=est_all;    modeleffects Estimate;  stderr StdErr;run;
监管 典型的敏感性分析组合:① MMRM (MAR) 主分析 → ② 控制组填补 / J2R → ③ Delta 调整或 tipping point(找到多大的偏移会翻转结论)。 ICH E9(R1) 要求把「与 estimand 一致」放在第一位,敏感性分析要针对假设而不是随便换个方法。

6.5 案例:5 组多队列 + Pooled 汇总组的完整实现

场景:TRTN = 1 (Placebo) + 2~5 (四个队列),AVISITN = 14 / 28 / 84, SAP 要 11 项输出:5 个单组 LS Mean + 1 个 Pooled LS Mean + 4 个单组 vs Placebo + 1 个 Pooled vs Placebo。 推荐写法:LSMEANS 拿那 9 项,只用一条 LSMESTIMATE 补 Pooled 的 2 项 —— 比把 11 项全手写成 LSMESTIMATE 的出错概率低一个数量级。

05_mmrm_pooled.sas · 建模
/* Day 84 是 AVISITN 排序后的第 3 个 level(14→1, 28→2, 84→3)
   —— 方括号里填的是 level 序号,不是 84!先看 Class Level Information 确认 */%let vlev = 3; ods output LSMeans           = raw_lsm           Diffs             = raw_dif           LSMEstimates      = raw_pool           ConvergenceStatus = cs; proc mixed data=ads1(where=(avisitn gt 0 and not missing(chg) and not missing(base)))           method=REML order=internal noclprint=20;    class SUBJID TRTN AVISITN;    model CHG = BASE TRTN AVISITN TRTN*AVISITN / ddfm=satterthwaite s cl;    repeated AVISITN / subject=SUBJID type=UN rcorr;     /* (1) 9 项:5 个单组 LSM + 全部两两差(后处理再筛同访视 vs Placebo) */    lsmeans TRTN*AVISITN / cl pdiff alpha=0.05;     /* (2) 2 项:Pooled Active 的 LSM 与 Pooled vs Placebo 的差值 */    lsmestimate TRTN*AVISITN        'LSM for Pooled Active'            [1, 2 &vlev] [1, 3 &vlev] [1, 4 &vlev] [1, 5 &vlev] divisor=4,        'Diff LSM for Pooled Active vs Placebo'            [1, 2 &vlev] [1, 3 &vlev] [1, 4 &vlev] [1, 5 &vlev]            [-4, 1 &vlev] divisor=4        / cl alpha=0.05 e;   /* e = 打印 L 矩阵,QC 必看 */run;
05_mmrm_pooled.sas · 后处理
/* --- 单组 LS Mean (ord 1-5) --------------------------------------- */data ds_lsm;    set raw_lsm;    length item $40 type $4;    select(TRTN);        when(1) do; ord=1; item='Placebo';  end;        when(2) do; ord=2; item='Cohort 1'; end;        when(3) do; ord=3; item='Cohort 2'; end;        when(4) do; ord=4; item='Cohort 3'; end;        when(5) do; ord=5; item='Cohort 4'; end;        otherwise;    end;    type='LSM';    keep AVISITN ord item type Estimate StdErr DF Lower Upper;run; /* --- 单组 vs Placebo 差值 (ord 7-10)
   _TRTN 是被减数 → _TRTN=1 才是 Active - Placebo;筛 trtn=1 会得到相反数 */data ds_dif;    set raw_dif;    where _TRTN = 1 and AVISITN = _AVISITN;    length item $40 type $4;    select(TRTN);        when(2) do; ord=7;  item='Cohort 1 vs Placebo'; end;        when(3) do; ord=8;  item='Cohort 2 vs Placebo'; end;        when(4) do; ord=9;  item='Cohort 3 vs Placebo'; end;        when(5) do; ord=10; item='Cohort 4 vs Placebo'; end;        otherwise;    end;    type='DIFF';    keep AVISITN ord item type Estimate StdErr DF Probt Lower Upper;run; /* --- Pooled 两项 (ord 6, 11)
   注意:LSMEstimates 数据集里没有 AVISITN 列,只有 Label,需自己贴回访视 */data ds_pool;    set raw_pool;    length item $40 type $4;    AVISITN = 84;    if index(Label, 'Diff') then do;        ord=11; item='Pooled Active vs Placebo'; type='DIFF';    end;    else do;        ord=6;  item='Pooled Active';            type='LSM';    end;    keep AVISITN ord item type Estimate StdErr DF Probt Lower Upper;run; /* --- 合并:只 SET 不写 BY!三个输入没有共同的排序顺序,
       写 by avisitn ord 会直接报 "BY variables are not properly sorted" --- */data all_res;    set ds_lsm ds_pool ds_dif;run; proc sort data=all_res; by AVISITN ord; run; /* --- TFL 文本列 ---------------------------------------------------- */data tfl_res;    set all_res;    length c_est $24 c_ci $30 c_p $10;    if not missing(Estimate) then        c_est = cats(put(Estimate,8.2), ' (', put(StdErr,7.2), ')');    if not missing(Lower) then        c_ci  = cats('(', put(Lower,8.2), ', ', put(Upper,8.2), ')');    if type='DIFF' and not missing(Probt) then        c_p = ifc(Probt lt 0.0001, '<0.0001', put(Probt, pvalue6.4));run;
关于 COHORT 与 TRT 共线COHORT 是由 TRT 直接派生的(每个队列对应唯一治疗组),两者完全别名: 模型里同时放 COHORTTRT*AVISIT 会让部分参数不可估, 输出中出现 Non-est 或某些效应的 DF 被置 0。SAS 不会崩,但 LS Means 是否仍可估必须逐项核对
实务上有两条合规路径:① 严格按 SAP 保留 COHORT,并在 QC 文档中记录哪些估计变成 Non-est; ② 若确认完全别名,向统计师提 SAP clarification,把 COHORT 从模型中移除并留下书面依据 —— 不要自行在代码里静默注释掉
§7

输出解读与 TLF 落地

Reading the LST, filling the shell

下面是一次真实结构的 PROC MIXED 输出(数值为模拟)。灰色注释是看这段时该问自己的问题

7.1 输出片段逐段读

Model Information / Dimensions / Number of Observations
Covariance Structure             Unstructured
Subject Effect                   USUBJID
Estimation Method                REML
Residual Variance Method         None
Fixed Effects SE Method          Kenward-Roger
Degrees of Freedom Method        Kenward-Roger

Covariance Parameters                 10
Columns in X                          14
Subjects                             240
Max Obs Per Subject                    4

Number of Observations Read            960
Number of Observations Used            871
Number of Observations Not Used         89
QC 三连问:① Subjects 是否等于分析集人数?② Covariance Parameters 是否等于 k(k+1)/2?③ Not Used 的 89 条是否全部来自 CHG 缺失(而不是 BASE 或分层因子缺失)? 第 ③ 点最常出问题 —— 若某个分层变量有缺失,会连带整条记录被丢掉。
Convergence / Covariance Parameter Estimates
Convergence criteria met.

        Cov Parm     Subject     Estimate
        UN(1,1)      USUBJID       4.0132
        UN(2,1)      USUBJID       3.4820
        UN(2,2)      USUBJID       5.8104
        UN(3,1)      USUBJID       3.3391
        UN(3,2)      USUBJID       5.1552
        UN(3,3)      USUBJID       7.4988
        UN(4,1)      USUBJID       3.2160
        UN(4,2)      USUBJID       4.8419
        UN(4,3)      USUBJID       6.8951
        UN(4,4)      USUBJID       9.2077
看两件事:① 方差是否随访视递增(4.0 → 9.2,典型的纵向数据发散,说明 CS 的同方差假设不成立,UN/CSH 是对的); ② 有没有出现 0 或负值(意味着边界解,即使显示 “Convergence criteria met” 也要警惕)。 同时留意日志里有没有 Estimated G matrix is not positive definite 类警告。
Fit Statistics / Type 3 Tests of Fixed Effects
-2 Res Log Likelihood          4218.6
AIC  (Smaller is Better)       4238.6
AICC (Smaller is Better)       4238.9
BIC  (Smaller is Better)       4273.4

Effect                Num DF   Den DF   F Value   Pr > F
BASE                       1    236.0    118.42   <.0001
TRTPN                      1    238.4     22.07   <.0001
AVISITN                    3    235.7     14.85   <.0001
BASE*AVISITN               3    233.9      3.11   0.0267
TRTPN*AVISITN              3    234.6      9.64   <.0001
TRTPN*AVISITN 的 p<.0001 说明治疗效应随时间变化(差值在扩大), 这正是要分访视报告 LS Mean 差的理由。注意 Den DF 是非整数(234.6)—— 这是 KR / Satterthwaite 的特征, 看到整数自由度就要回头检查 DDFM 是不是掉回 BW / RESIDUAL 了。
Least Squares Means(节选 Week 24)
Effect          TRTPN  AVISITN  Estimate  StdErr    DF  Lower    Upper
TRTPN*AVISITN       0       24    0.9412  0.4585  231  0.0378   1.8446
TRTPN*AVISITN       1       24   -2.9188  0.4498  229 -3.8051  -2.0325
这两行就是主表「LS Mean (SE)」列的来源。LS Mean 是把连续协变量固定在总体均值、 分类因子等权平均后的模型预测均值,不等于观测均值 —— 若两者差很远,通常提示基线不平衡或缺失严重。
Differences of Least Squares Means(已筛同访视)
_TRTPN  TRTPN  AVISITN  _AVISITN  Estimate  StdErr     DF  tValue  Pr>|t|   Lower    Upper
     0      1        4         4   -0.8604  0.4331  228.7   -1.99  0.0479  -1.7138  -0.0070
     0      1        8         8   -1.7135  0.4980  231.2   -3.44  0.0007  -2.6948  -0.7322
     0      1       16        16   -2.7908  0.5673  230.4   -4.92  <.0001  -3.9086  -1.6730
     0      1       24        24   -3.8600  0.6420  229.8   -6.01  <.0001  -5.1250  -2.5950
Estimate = LSM(TRTPN) − LSM(_TRTPN)。这里 _TRTPN=0(安慰剂)为被减项, 所以负值 = 试验组下降更多 = 有效(ADAS-Cog 分数越低越好)。方向一定要在程序里写死并在脚注说明, 不要靠人工判断符号。

7.2 图形:LS Mean 轮廓图

Figure 14.2.1.1

相对基线变化的 LS Mean 及 95% 置信区间(MMRM, ITT)

纵轴向下为改善(ADAS-Cog 分数下降)。误差线为 LS Mean 的 95% CI。模拟数据。

7.3 图形:治疗差值随访视变化

Figure 14.2.1.2

Drug A − Placebo 的 LS Mean 差值及 95% CI

虚线为无差异参考线(0)。CI 不跨 0 即在该访视达到名义显著。模拟数据。

7.4 主表 shell 映射

VisitLS Mean Change (SE) Difference (95% CI)p-value
Placebo
(N=120)
Drug A
(N=120)
Week 4−0.42 (0.31)−1.28 (0.30)−0.86 (−1.71, −0.01)0.0479
Week 8−0.15 (0.36)−1.86 (0.35)−1.71 (−2.69, −0.73)0.0007
Week 160.38 (0.41)−2.41 (0.40)−2.79 (−3.91, −1.67)<0.0001
Week 24 主要终点 0.94 (0.46)−2.92 (0.45)−3.86 (−5.13, −2.60)<0.0001
映射 「LS Mean (SE)」两列 ← _lsm.Estimate / StdErr;「Difference (95% CI)」← dif_c.col_diff; 「p-value」← dif_c.col_p。N 一般用分析集人数而非各访视有数据的人数,若 shell 要求「n at visit」, 需另外从 work.anl 统计并单独成行。
脚注必备 ① 模型完整规格(固定效应、协变量、协方差结构、自由度方法);② 实际使用的协方差结构(若发生降级); ③ 分析集定义;④ 差值方向的说明;⑤ 缺失数据处理声明(“No imputation was performed; the model uses all available observations under MAR.”)。
§8

常见坑与交付前自检清单

Pitfalls & pre-delivery checklist

8.1 高频坑清单

8.2 交付前自检清单

点击勾选(仅本地记录,刷新即清空)。

§9

对话问答复盘

Q&A recap

你的原始提问顺序整理:33 个提问合并为 32 条(两个纯格式化请求合并为 Q18)。每条给出:当时答复的要点、 正确 / 需修正 的判定,以及落到项目里该怎么写。 标红的几条是当时答错或表述不严谨的,请以这里为准。

结论正确,可直接用 方向对,但有需要补充的前提 当时答错 / 前后矛盾,已更正
§10

拓展与参考

Alternatives & references

10.1 同一个模型的其他实现

工具写法与 PROC MIXED 的差异
PROC MIXEDrepeated AVISITN / subject=USUBJID type=UN; 行业基准。KR 自由度、REML、R 侧建模
PROC GLIMMIXrandom AVISITN / residual subject=USUBJID type=UN; 同一个模型的等价写法(residual 关键字 = R 侧)。多了 LSMESTIMATESTORENLOPTIONSCOVTEST 语句,优化控制更细;能顺带做非正态终点
PROC GENMOD
(GEE)
repeated subject=USUBJID / type=UN corrw; 群体平均模型,用工作相关阵 + 三明治方差。只在 MCAR 下无偏(除非做 IPW 加权), 所以不能直接替代 MMRM 作为主分析
R · mmrmmmrm(CHG ~ TRT*AVISIT + BASE + us(AVISIT|USUBJID), data=) 专为 MMRM 写的包,支持 KR 与 Satterthwaite,与 SAS 结果通常在数值精度内一致, 是目前 R 侧做监管提交的首选
R · nlme::glsgls(CHG ~ ..., correlation=corSymm(), weights=varIdent()) 能拟合 UN,但没有 KR 自由度,小样本 p 值会偏小
对不上时先查这四项 ① CLASS 水平排序是否一致;② 参照水平(谁减谁);③ 自由度方法(KR vs Satterthwaite vs 渐近); ④ 进模型的记录数(Number of Observations Used)—— 90% 的「SAS 和 R 结果不一致」最后都落在第 ④ 条。

10.2 参考文献

  1. ICH E9(R1) (2019). Addendum on Estimands and Sensitivity Analysis in Clinical Trials. —— estimand 框架的规范来源。
  2. EMA (2010). Guideline on Missing Data in Confirmatory Clinical Trials (EMA/CPMP/EWP/1776/99 Rev.1).
  3. National Research Council (2010). The Prevention and Treatment of Missing Data in Clinical Trials.
  4. Mallinckrodt, C.H. Preventing and Treating Missing Data in Longitudinal Clinical Trials. Cambridge University Press. —— MMRM 与缺失数据的标准参考书。
  5. Mallinckrodt et al. (2008). Recommendations for the primary analysis of continuous endpoints in longitudinal clinical trials. Drug Information Journal, 42, 303–319. —— 「MMRM 作为主分析」的经典论证。
  6. Kenward, M.G. & Roger, J.H. (1997). Small sample inference for fixed effects from restricted maximum likelihood. Biometrics, 53, 983–997.
  7. Siddiqui, O., Hung, H.M.J., O'Neill, R. (2009). MMRM vs. LOCF: a comprehensive comparison. Journal of Biopharmaceutical Statistics, 19, 227–246.
  8. SAS Institute. SAS/STAT User's Guide: The MIXED Procedure —— TYPE= 结构清单与选项的权威定义。
  9. Sadler et al. (2023). The mmrm R package. —— R 侧实现与 SAS 的一致性验证。