SAS Pattern Note · 纵向连续终点

MMRM:把纵向连续终点的主分析写成一段可复现、可预先规定的 SAS

一个 III 期试验的主要终点常常是"第 24 周相对基线的变化"。脱落让每个受试者的观测条数 不同,而监管要的是所有随机受试者的平均治疗效应。这一段 PROC MIXED 就是为此而存在的:不设 随机效应,直接把残差协方差建成非结构化,用全部已观测数据估计边际均值差。读完你会知道每个选项为什么 在那儿、换掉它会付出什么代价,以及为什么真正决定成败的是揭盲前写进 SAP 的那几行。

来源  去标识化的 ADaM BDS 形态;研究编号与方案号以 NNNN 代替 状态  静态分析,本机无 SAS 会话;附可运行的校验程序而非转录的输出
范围与去标识化

研究编号、方案号、库中路径、程序头、作者与修订历史均已移除或泛化;输入数据集名泛化为 ADLBC / ADBDS;访视标签保留为通用英文。本笔记覆盖的是主要终点的主分析那一次 拟合:从分析数据集构建到访视内治疗差异的读出。它不覆盖多重插补、参考基准插补(J2R / CIR)、 tipping-point 敏感性分析,也不覆盖二分类与生存终点——那些是另一组模式。本书其余章节的精读见 《Linear Mixed Models》全书精读笔记:本篇用到的每一个概念在原书里的位置, 以及第 3、4、5、8、9 章的临床映射,都在那一篇。

1这段代码要完成什么

一句话的需求,以及由它决定的数据形状。

需求:估计每个剂量组与安慰剂在第 24 周的基线变化之差,采用 treatment-policy 估计目标,并且 不丢弃任何一条已观测到的治疗后测量。第 24 周是主要时间点,但第 4、8、12、16 周的测量不是多余的—— 它们为协方差结构和脱落受试者的信息提供了依据。

1.1 数据形状

输入是 ADaM BDS 的纵向形态:一行一个受试者 × 一个访视。这不是偏好问题,而是 REPEATED 语句要求的形状——SUBJECT= 识别聚类,REPEATED 的效应识别聚类 内部的位置。

变量角色在这段代码里的作用
USUBJID聚类标识REPEATED ... / SUBJECT= 的聚类单元;同时进 CLASS。V 矩阵的块由它切分。
AVISITN位置REPEATED AVISITN 的重复效应。必须是分类变量:进 CLASS,否则模型把时间当成连续直线。
TRTP计划治疗treatment-policy 估计目标下用计划分组,而非实际用药。
CHG响应AVAL - BASE。只在治疗后访视上定义;基线记录的 CHG 恒为 0。
BASE / BASE_C协变量基线作为协变量进入模型,不是响应。BASE_C 是中心化版本,只影响截距的可读性。
ANL01FL纳入标志分析集标志。注意它不等于"这条记录进入响应向量"——见第 5 节 F1。
问题的形状

三件事同时成立,才把问题推到 MMRM 上:(一)同一个受试者的多次测量彼此相关,任何假设观测独立 的过程都会低估标准误;(二)每个受试者的观测条数不同,脱落让数据天然不平衡;(三)要推断的是 总体平均,不是某个特定受试者的效应。前两条排除了 PROC GLM,第三条排除了带随机效应的 条件模型。

一行一个受试者 × 一个访视 格子填色 = 已观测;空格 = 脱落,不填补 01-001 01-002 01-003 W4 W8 W12 W16 W24 Vₕ 非结构化 5 访视 → 15 个参数 缺失的格子从 likelihood 里消失 脱落受试者的前几次测量仍然贡献信息:它们既进入固定效应,也进入协方差结构。 只有一次都没有治疗后测量的受试者才真正无法贡献——主分析集与"能进模型的集"不是同一个集。
Figure 1 | 纵向 BDS 的形状,以及非结构化残差协方差覆盖的范围。空格不是缺失值填补的对象, 是似然里直接不存在的项。
What to take away

MMRM 不填补任何东西。它把每个受试者已观测到的那部分测量放进似然,缺失的那部分根本不出现——这就是 它"处理缺失数据"的全部含义,也是它在 MAR 下无偏、在 MNAR 下同样无能为力的原因。

2需要交代的背景

只讲下面这段拟合所依赖的机制,其余一概不提。

2.1 边际模型:不设随机效应是刻意的

带随机截距的 LMM 写成 Yₕ = Xₕβ + Zₕuₕ + εₕ。把它对 uₕ 积分掉,得到隐含的边际模型

Vₕ = Zₕ D Zₕ' + Rₕ

这说明两件实用的事。第一,随机截距 + 方差恒定的残差,其隐含边际模型就是复合对称(CS) [doc]——所以"加随机截距"和"直接指定 CS 残差结构"在线性模型下是同一个模型,差别只在 你想推断什么。第二,MMRM 跳过了中间那一步:不写 RANDOM,直接把 Vₕ 建成非结构化。代价是不能推断方差分量和 EBLUP;收益是固定效应直接就是总体平均效应,而这正是 监管要的量。

2.2 协方差结构:每个选项值多少参数

非结构化不是"更高级",而是代价更高但假设更少。K 个访视的非结构化矩阵要估 K(K+1)/2 个参数,且随访视数平方增长。下面这些数字不是抄来的,是随笔记附带的 mmrm_check.sas 在 K = 5 的夹具上数出来的 [实践]。

结构参数个数K = 5什么时候用它,以及它的假设
TYPE=UNK(K+1)/215主分析默认。不对方差与相关施加任何模式,因此不会因为结构错设而偏倚;代价是小样本下可能不收敛。
TYPE=TOEP2K − 19UN 不收敛时的第一顺位降级。同一时间滞后共享一个相关,但方差仍可各访视不同。
TYPE=AR(1)22相关随时间间隔指数衰减。隐含等间隔假设——访视在 0/4/8/12/16/24 周时,间隔并非全部相等,用它需要论证。
TYPE=CS22任意两次观测相关相同、方差恒定。等价于随机截距模型的隐含边际结构,作为敏感性分析有意义,作为主分析假设过强。
默认(不写)11fail 残差独立同方差。纵向数据上漏写 TYPE= 等于完全没建模时间相关,标准误被严重低估。

2.3 估计方法与两条铁律

REML 修正了 ML 因估计固定效应而损失的自由度,因此协方差参数要用 REML;但 REML 的似然依赖固定 效应设计矩阵,因此比较两个固定效应结构时必须切回 ML。这是同一段分析里会切换 METHOD= 的唯一正当理由 [doc]。校验程序 A12 / A13 断言了同一组固定效应在 ML 与 REML 下结构 一致——协方差参数个数与交互项的分子自由度都不变,变的只是协方差估计值。

2.4 Kenward–Roger 不是可选项

无论 ML 还是 REML,固定效应的方差都因为用 V̂ 代替真实 V 而向下偏倚。 Kenward & Roger (1997) 的调整把 V̂ 的变异也计入,并给出近似的分母自由度 [lit]。在样本量只有几百、访视缺失又严重的 II/III 期试验里,这是把 I 类错误压回名义水平 的手段。校验程序 A14 断言 KR 的分母自由度与默认的 containment 不相同——如果两者相同,说明 DDFM=KR 根本没生效。

3读这段代码

当前的实现,按步骤标注。 listings 与 mmrm_check.sas 逐语句一致。

3.1 构建分析数据集:基线是协变量,不是响应

data adbds;
   set adlbc;
   base_c = base - 26;
   chg    = aval - base;
   if avisitn > 0 then output;
run;

三条语句各有一件事要说:

3.2 主拟合

proc mixed data=adbds method=reml;
   class usubjid trtp(ref='Placebo') avisitn;
   model chg = base_c trtp avisitn trtp*avisitn / solution htype=3 ddfm=kr;
   repeated avisitn / subject=usubjid type=un r=1 rcorr=1;
   lsmeans trtp*avisitn / cl diff slice=avisitn;
   ods output CovParms = cp_un
              Tests3   = t3
              LSMeans  = lsm
              SolutionF= solf;
run;

逐项:

写法它承担什么,去掉会怎样
class ... avisitn把时间当分类变量。这样每个访视有自己的均值参数,响应轨迹可以是任意形状。若 AVISITN 不进 CLASS 而被当作数值,时间效应退化成一条直线,Type 3 的 AVISITN 分子自由度从 4 掉到 1——校验程序的 A6 就是抓这个的。
trtp(ref='Placebo')把安慰剂设为参照水平,使 solution 里的系数与 diff 的对比直接以安慰剂为基准,不依赖字母序。
trtp*avisitn允许治疗效应随访视变化。没有这一项,等于假设各访视的治疗效应相同,会掩盖真实的时程差异。代价:它通常是模型里最大的一项,也是 UN 不收敛时第一个被审查的对象。
repeated ... / subject=usubjid声明聚类单元。没有 RANDOM 语句是刻意的——这正是边际模型与条件模型的分界。
type=un非结构化。不写就是对角阵(见 2.2 的表格)。
r=1 rcorr=1打印第一个受试者的 R 与相关矩阵。不是为了好看:这是审稿人判断"相关是否随时间间隔衰减"的唯一直接材料。
ddfm=krKenward–Roger 自由度。见 2.4。
lsmeans ... / slice=avisitn给出每个访视内的组间两两比较,第 24 周那一组就是主要终点的对比。见 3.3。
ods output把 CovParms / Tests3 / LSMeans 落到数据集,供 TFL 复用。不要靠人工从 output 窗口抄数字。

3.3 读出第 24 周的对比:用 slice=,不要手写系数

想要"第 24 周,Drug_High 减 Placebo",最稳的写法是让 LSMEANS 自己去切,而不是手写 ESTIMATE 的系数向量。原因是后者对分类水平顺序极其敏感:交互项 TRTP*AVISITN 的 15 个列按 TRTP 慢变、AVISITN 快变排列,一旦 CLASS 的水平顺序因为 ORDER= 选项或数据内容而变,同一串系数指的就是别的对比, 而且不会报错。SLICE=AVISITN 按标签取值,不存在这个问题。

如果要写 ESTIMATE

先在 CLASS 里固定水平顺序(例如加 ORDER=DATA 并用格式控制),再用 / E 选项把 L 矩阵打印出来核对一遍系数落点。把这一步写进程序的注释里—— 下一个接手的人是靠它判断对比对不对的。

4为什么是它,而不是那个更顺手的写法

先比较,再论证。

候选结论为什么
MMRM(本笔记)pass用全部已观测数据;MAR 下无偏;直接给出总体平均效应;UN 不施加相关模式;KR 控制小样本 I 类错误。代价是必须在 SAP 里把结构、估计方法、自由度方法和降级路径全部写死。
LOCF + ANCOVAfail假设脱落者此后的数值不再变化,与医学常识相悖;人为压低方差导致假阳性。ICH E9(R1) 与 FDA 缺失数据指南均不把它作为主分析 [doc]。它还能作为敏感性分析存在,但绝非主分析。
Complete-case ANCOVAdefect只用在第 24 周有观测的受试者。脱落与疗效相关时直接引入选择偏倚,且丢弃了中间访视的全部信息。作为敏感性分析有价值,作为主分析不够。
随机截距 LMMdefect数学上等价于 CS 边际结构(2.1),等于给相关模式加了一个很强的假设;固定效应变成"给定随机效应为 0 时"的对象特异效应,与监管要的总体平均不是同一个量。
GEEdefect同样估计总体平均,且作业相关设错也有稳健 SE 兜底。但标准 GEE 在 MAR 下并不自动有效(需要加权 GEE),且小样本下稳健 SE 偏乐观。更常见于不愿做强分布假设、或终点非连续的场合。

4.1 一个值得单独说的反直觉结论

很多笔记(包括我自己的旧稿)写着"基线 × 访视交互是可选的,多数情况下不需要"。这句话在 2021 年被明确反驳过:Schuler 证明,在调整基线协变量却不包含"协变量 × 时间"交互时,MMRM 相对 complete-case ANCOVA 的功效增益与抗脱落偏倚能力都不再成立,并用模拟做了验证 [lit]。也就是说,加了基线协变量却不让它随时间变化,可能比不做纵向分析更糟。

What to take away

把基线协变量放进模型,就要同时考虑 BASE_C * AVISITN。这不是"锦上添花",而是 MMRM 相对 单时点 ANCOVA 是否真的占优的前提条件。它要进 SAP,因为它是主分析模型的一部分。

5设计与正确性

它保证了什么,哪些输入它 silently 处理错,以及那些必须由人来补的缺口。

5.1 不完美输入下的行为

用例输入形状MMRM 的处理判定与后果
S1五个访视全部观测5 行进入似然pass 完整贡献固定效应与协方差结构。
S2单调脱落,第 8 周后不再就诊2 行进入似然pass 是 MMRM 存在的理由。前两访视既贡献均值轨迹,也贡献相关结构——受试者没有"被填补",只是缺失部分不进似然。校验程序 A17 断言夹具里存在脱落。
S3只有基线记录,无任何治疗后测量0 行进入似然defect 被静默丢弃。受试者仍在 ITT 集里,却对主分析零贡献。校验程序 A15 断言夹具里存在这类受试者;报告里要说清楚主分析集与"实际进入模型的受试者数"的差额。
S4只观测到一次治疗后访视1 行进入似然pass 仍被保留,贡献均值与方差,但不贡献相关。校验程序 A16 断言夹具里存在这类受试者。UN 能估出来靠的是别人,不是他。
S5访视间隔不等(4 / 4 / 4 / 4 / 8 周)当作分类位置处理pass CLASS 化之后间隔不等无所谓——这是 UN 相对 AR(1) 的实际优势。但如果改用 TYPE=AR(1),等间隔假设就被破坏了,此时应留在 UN 或 TOEP。
S6间歇性缺失(中间缺、后面又来)照常进入似然pass MMRM 不要求单调缺失模式,这正是它优于只能处理单调缺失的某些插补方案的地方。

5.2 四个缺陷

Finding 1 — 基线记录留在响应向量里

ANL01FL = 'Y' 在真实 ADaM 里常常同时标在基线记录和治疗后记录上,因为它的含义是 "这条记录属于该分析集",不是"这条记录是响应"。直接 where anl01fl = 'Y' 就把 CHG = 0 的基线记录带进了模型:非结构化矩阵多出一行一列,其中方差为 0,拟合在边界上, 参数估计不可信。防御:显式 if avisitn > 0 then output;,并在校验里断言最小的 AVISITN。这一步不能靠"数据集上游已经处理过"来保证。

Finding 2 — AVISITN 没进 CLASS

SAS 不会因为一个变量"看起来像访视编号"就当它是分类的。漏进 CLASS 时模型照常收敛、照常 出结果,只是时间效应变成一条直线,Type 3 的 AVISITN 分子自由度从 4 变成 1。没有报错, 没有警告。 防御:断言 Type 3 的分子自由度(校验程序 A6–A9)——交互项应为 (3−1) × (5−1) = 8。

Finding 3 — 协方差结构事后挑选

看到 UN 的结果不满意再换成 CS,属于数据驱动的选择,会破坏 α 控制,是审评一定会被问的点。 防御不在代码里,在 SAP 里:把主分析结构和有序的降级路径(UN → TOEP → AR(1) → sandwich)在揭盲前 写死,并规定由谁记录偏差。代码能做的只有一件事:把实际使用的结构写进日志和 TFL 脚注。

Finding 4 — 预先规定的落实情况本身就堪忧

一项对 2015–2018 年提交给汉诺威医学院伦理委员会的 39 个 II/III 期方案的实际检查发现:95% 规定了固定 效应与随机效应,但只有 77% 给出协方差矩阵结构,给出检验方法的 36%、估计方法的 28%、 计算方法的 3%、降级策略的 18% [lit]。也就是说,"UN + REML + KR"这套默认组合 之所以常见,很大程度上是因为它没被写下来时大家默认这么做——而不是因为它被论证过。这是写 SAP 时 最值得补的空白。

5.3 模型不解决的事

MMRM 的合法性建立在 MAR 上,而 MAR 无法用数据检验——要检验就得有缺失的那些值。因此它必须由 敏感性分析来补。行业会议上给出的成熟做法包括:把 pattern-mixture 模型表达为 MMRM 最小二乘均值的线性 组合,并用 delta 法把脱落/完成者比例本身的多项随机性并入方差(Ratitch & O'Kelly, PharmaSUG 2012 [lit]);以及在 MNAR 下用 PROC MI 做参考基准插补(J2R / CIR),再由 PROC MIANALYZE 合并(PharmaSUG 2025 [lit])。另一条常被忽略的界线是: 标准 MMRM 无法区分伴发事件前后的数据——当缺失与伴发事件(停药、补救用药)高度相关时,MAR 假设会 被实质性地违反,此时 treatment-policy 估计目标与标准 MMRM 之间出现裂缝(PharmaSUG China 2024 [lit])。

What to take away

MMRM 是一个在 MAR 下无偏的估计器,不是一个"处理了缺失数据"的黑箱。它的可信度来自两处代码之外的 东西:揭盲前写死的模型设定,以及承认 MNAR 可能的敏感性分析。

6复用检查清单

换到另一个程序里之前,要改什么、要查什么。

要改的地方改的时候注意什么
AVISITN > 0 的阈值本例用 0 表示基线。若项目用 AVISITN = 99 或负数值标记基线/未计划访视,阈值要跟着变,否则会把不该进的记录放进去。
BASE_C 的中心化常数26 是本例基线的近似总均值。换终点要换成新终点的数值——它只影响截距,但写错会让 Solution for Fixed Effects 里的截距无法解释。
固定效应列表协变量必须逐条来自 SAP,不能来自"哪个显著"。分层因素(地区、基线疾病严重度)通常要进。
BASE_C * AVISITN按 4.1,默认应该考虑纳入。加进去要同时检查 UN 还收不收敛。
TYPE= 与降级路径先确认访视数:K(K+1)/2 随访视数平方增长,8 个访视就是 36 个参数。样本量撑不住时,SAP 里就该预先写 TOEP。
DDFM=KR 是默认选择。极不平衡或极大样本下 KR 计算开销明显,可考虑 ddfm=kr2 或 bw,但要在 SAP 里写明。
中心效应本例未纳入。多中心试验里中心数少时作固定效应,中心数多时考虑随机效应——但随机中心效应会改变推断目标,需要统计师确认。
ODS OUTPUT 的表名Tests3 / SolutionF / CovParms / LSMeans 是 PROC MIXED 的表名;换成 PROC GLIMMIX 时部分表名不同,不要照抄。
提交服务器之前

SAS 源码保持全 ASCII:注释、TITLE、LABEL、%PUT 文案一律 英文。中文注释在中文环境里看着没问题,到了服务器的编码环境里会变成乱码,而且可能让程序头校验失败。

7随笔记附带的校验程序

它断言什么,夹具长什么样,以及它刻意不解决什么。

mmrm_check.sas 是纯 Base SAS + SAS/STAT:没有研究宏、没有库名、 没有外部输入、不产生永久数据集。它用 CALL STREAMINIT(20260922) 造出 240 个受试者、3 个治疗组、 基线加 5 个治疗后访视的夹具,脱落是单调的且安慰剂组 hazard 更高——这就是一个症状性试验真实的样子。

sas mmrm_check.sas

17 条断言全部是结构性的。它们确定模型"是什么":每个协方差结构值多少参数(A2–A5)、 Type 3 的分子自由度是多少(A6–A9)、基线记录是否真的被排除(A11)、KR 是否真的改变了分母自由度 (A14)、夹具里是否真的存在那几种麻烦的受试者(A15–A17)。期望值不是写死的数字,而是从刚生成的夹具里 数出来的,所以断言不会随夹具漂移。

断言内容它挡住哪个错误
A1, A11K = 5,响应向量最小 AVISITN = 4Finding 1:基线混进响应向量
A2–A5UN 15 / CS 2 / TOEP 9 / AR(1) 2结构成本算错、SAP 里参数预算写错
A6–A9Type 3 分子自由度 4 / 2 / 8 / 1Finding 2:分类变量漏进 CLASS
A10TRTP*AVISITN 的 LS-means 共 15 行单元格缺失、访视标签不一致
A12, A13ML 与 REML 结构一致报告用 REML 却在 ML 下比较模型
A14KR 的分母自由度 ≠ containmentDDFM=KR 没生效
A15–A17夹具含"无响应""单次访视""有脱落"三类受试者主分析集与"实际进模型的集"混为一谈

末尾还有一个脆弱块,由 %let RUN_FRAGILE = 0; 关掉:它把基线记录留在响应向量里再拟合 一次,打印出 6 × 6 非结构化 R 的协方差参数。这个块的失败本身就是结论,所以它被放在最后、 在日志里明确宣告,并且可以由调度跳过。

本机没有 SAS 会话

本笔记的每一条断言都可以被重跑,但它们没有被重跑过——写作环境里没有授权的 SAS。因此笔记里 没有一个数字是"某次运行的输出"。以下行为只有真实会话才能最终确认:UN 在本夹具上的收敛状态与具体 协方差参数估计值;KR 分母自由度的具体数值;SLICE= 输出的对比是否与 PROC MIANALYZE 路线一致;以及脆弱块究竟是报收敛失败还是给出一个零方差的参数估计。 如果你有许可证,跑一遍 mmrm_check.sas,17 条断言应当全部通过。