做统计分析这些年,Stata是我用得最顺手的工具之一,而重复测量方差分析(Repeated Measures ANOVA)又是实证研究中需求极高、但很多人概念都搞混的一类方法。每次在后台收到“同一批人测了三次,该怎么比较”“干预前后测了两轮,直接t检验行不行”这类的留言,我就知道又有人踩进了统计分析里最容易翻车的设计场景。
这篇文章我打算彻底讲透重复测量方差分析:从它到底是什么、解决什么问题,到什么时候该用、什么时候该换方法,再到Stata里怎么写命令、怎么看输出、怎么做事后检验,最后把实操中踩过的坑和零基础小白入门Stata的学习路径也一并整理出来。不管你是硕士博士、临床科研人员、社科研究者,还是自学统计的爱好者,只要耐心读下去,拿自己一份数据动手跑一遍,大概率就能把这块硬骨头啃下来。
1. 重复测量方差分析是什么:先搞懂它解决的问题
1.1 什么是重复测量数据:用生活化例子讲透
重复测量数据,字面意思就是“同一批对象被重复测量了多次”。注意,这里的关键词是“同一批对象”。举个例子:
- 一组高血压患者分别在治疗前、治疗1个月后、治疗3个月后测定血压
- 20名大学生被要求在三种不同光照条件下完成同一项反应时任务
- 一批运动员接受新的训练方案后,在赛季前、中、后各测一次体能
这三类数据有个共同特征:同一个人的多次测量结果之间一定是有相关性的。如果这个人血压本来就偏高,他三次测的血压大概率都偏高;如果这个人反应快,他在三种光照条件下都会相对更快。也就是说,每条观测值之间并不是互相独立的。
传统独立样本方差分析(ANOVA)要求观测值互相独立,但重复测量数据天然不满足这个前提。如果你无视这一点,直接把所有人的所有时间点数据混在一起做普通的ANOVA,会低估误差、虚高显著性,也就是更容易犯第一类错误。重复测量方差分析之所以被单独拎出来讲,正是因为它专门处理这种“个体内部多次测量”的数据结构。
1.2 原理:方差怎么分?
重复测量方差分析的基本原理并不复杂,核心思想是“把方差得体地拆开”。它把总变异拆成三大部分:
- 组间变异(between-subjects variation):由被试个体之间本身的差异造成的变异。
- 组内变异(within-subjects variation):同一被试内部在多次测量之间的变异,这里又可以进一步拆成时间(或条件)带来的系统效应和随机误差。
- 误差变异(error variation):排除个体差异和时间效应后剩下的随机波动。
为什么要这样拆?因为把个体差异从误差中“剔”出来之后,剩下的误差会更小,检验处理效应(比如时间变化、干预效果)时的统计检验力就更高。这就像用体重秤称重时先去掉皮重——干扰因素减少了,称出来的差值才更接近真实。
一个通俗的类比:假设你和我各跑了三次100米,你想比较我俩的成绩。如果完全忽略“选手”这个因素,把所有6次成绩混在一起,组内差异会被个人水平的波动污染;如果用重复测量的思路,先把“你这人的平均速度”和“我这人的平均速度”估计出来,再把每次成绩与个人平均水平的偏差拿出来比较,剩下来的变异就纯粹是“临场发挥”加工“测量误差”,此时检验两个人是否有差异会更灵敏。
从矩阵角度看,重复测量方差分析还隐含一个重要假设——球形假设(sphericity),即各次测量之间差分的方差近似相等。如果违反球形假设,标准F检验会偏激进,需要采用Greenhouse-Geisser或Huynh-Feldt校正后的P值。这些在Stata输出里会自动呈现,后面在第3、5节我会详细说。
2. 什么时候该用重复测量方差分析:适用情形与边界判断
2.1 典型适用场景:你手里那套数据行不行?
判断一项研究是否适合用重复测量方差分析,可以从三个维度来评估。
第一个维度是测量次数。你必须拥有同一个体在至少两个水平上的测量数据,通常建议至少三个水平。如果只有两个测量点(比如前测、后测),用配对样本t检验往往更直接,重复测量ANOVA虽也能做,但优势不明显。
第二个维度是数据类型。因变量最好是连续变量,且近似满足正态性。如果因变量是排序等级(比如满意度1-5分),一般建议改用非参数方法或有序逻辑回归;如果是二分类(比如治愈/未治愈),应该考虑广义估计方程或混合效应逻辑回归。
第三个维度是研究设计的类别。重复测量方差分析在以下三种设计中最为常见:
- 纵向追踪设计:同一队列人群在不同时间点随访。比如追踪一群戒烟的年轻人,每隔3个月测量一次心理压力。
- 实验前后设计:干预前后多次测量,常见于临床、运动科学和教育学。比如评估一种新的教学方式,分别在开学初、期中、期末测三次成绩。
- 交叉设计或重复处理设计:同一被试先后接受多种条件或处理。比如药学里经典的A/B交叉试验,同一批受试者先吃A药再吃B药,中间经过洗脱期。
在这些设计里,如果你还有一个组间因素(比如“治疗组 vs 对照组”),这就构成了混合设计。混合设计可以同时检验组间主效应、时间主效应和组×时间交互效应。交互效应往往是最有价值的结果——它直接回答了“两组随时间变化的轨迹是否不同”这个核心问题。
2.2 什么时候不该用它:这些坑必须避开
虽然重复测量方差分析很常用,但并不是所有“多次测量”都适合用它。
第一种需要避开的情况是数据缺失严重。传统重复测量方差分析会优先分析完整案例:如果一个被试缺失了某个时间点,做传统ANOVA时常常被整套剔除,样本量骤降。缺失比例较高时,建议改用线性混合模型(mixed-effects model),它能够充分利用部分观测数据。
第二种是结构不满足球形假设且样本量较小。当时间点较多(比如5个以上)时,球形假设往往难以保证,而样本量又不大时,epsilon校正可能调整不足。此时可以考虑多变量方差分析(MANOVA),或直接使用混合模型,后者不依赖球形假设。
第三种是因变量严重偏离正态。重复测量ANOVA对正态性有一定要求,严重偏态的数据使用参数方法会歪曲结果。可以先尝试数据变换,比如对数变换或Box-Cox变换;如果依然不行,就用Friedman检验这种非参数替代方法。
| 数据结构 | 条件 | 推荐方法 |
|---|---|---|
| 两组、一次测量 | 独立样本 | 独立样本t检验 / 单因素ANOVA |
| 两组、两次测量(前后测) | 配对 | 配对样本t检验 |
| 两组、三次及以上测量,缺失少 | 球形假设满足(或校正) | 重复测量方差分析 |
| 多组、多次测量,缺失多或时间间隔不等 | 更灵活 | 线性混合模型 |
| 单组、多次测量,严重偏态 | 分布不满足 | Friedman检验 |
这张表几乎覆盖了实证研究中90%的常见场景,你可以直接对照自己的数据结构选方案。
3. Stata操作命令一步一步来:从数据整理到结果输出
3.1 数据格式准备:宽格式还是长格式?
在Stata里做重复测量方差分析,第一关就是数据格式。新手最常见的报错,十有八九是数据结构不对。
Stata中有两类与重复测量相关的数据格式:
- 宽格式(wide):每个被试占一行,每个时间点是一个变量。例如 id、group、t1、t2、t3。
- 长格式(long):每个被试的每个时间点各占一行。例如 id、group、time、y。
传统的anova命令配合repeated()选项在操作时对数据格式有一定要求,官方示例通常用的是单因变量加组内因素的长格式;而mixed命令也强烈建议使用长格式。为了通用,掌握reshape命令的转换逻辑很重要。
假设现在你拿到一份宽格式数据,变量有id、group、t1、t2、t3,转成长格式的命令如下:
* 宽转长 reshape long t, i(id) j(time) rename t y转换完成后,用list id group time y in 1/12快速检查数据结构。如果每个id出现三行,每行的time分别为1、2、3,说明转换正确。
如果你手里是长格式、需要宽格式做某些图形展示,反向操作是:
* 长转宽 reshape wide y, i(id) j(time)这里一定要记住,i()里填被试唯一标识,j()里填重复测量的标识变量。很多人第一次用reshape会把它搞反,结果数据变成一团乱麻,后续分析全崩。
3.2 命令全流程:一个可复现的例子
下面我用一份模拟数据,演示在Stata中完成一次完整的重复测量方差分析。场景设定是:30名高血压受试者随机分为两组(group=1为对照组,group=2为治疗组),在服药前、服药1个月后、服药3个月后分别测定血压。
* 清空内存并设定随机种子 clear set seed 2024 * 生成30名受试者 set obs 30 gen id = _n * 随机分组:前15人为对照组,后15人为治疗组 gen group = cond(_n > 15, 2, 1) * 生成3个时间点的血压值(宽格式) * 对照组平均血压稳定在120附近,治疗组逐渐下降 gen t1 = rnormal(120, 10) + 20 * (group == 2) gen t2 = rnormal(118, 10) + 10 * (group == 2) gen t3 = rnormal(115, 10) - 5 * (group == 2) * 宽转长 reshape long t, i(id) j(time) rename t y * 对分组变量编码为因子 encode group, gen(group_f)这里故意在t1上加了20*(group==2)来制造基线差异,只是为了演示代码结构,实际研究中还是要保证随机化分组尽可能平衡基线水平。
接下来,执行传统的重复测量方差分析:
* 传统重复测量方差分析(组间因素group_f + 组内因素time) anova y group_f time group_f#time / id|group_f, repeated(time)这条命令的关键在于,斜杠右边是误差项,id|group_f表示被试嵌套在分组中,符合混合设计的方差分解逻辑。输出里会出现三部分信息:组间效应、组内效应、以及球形假设检验与校正结果。
如果你更希望用现代方法、并且不执着于报告球形检验,推荐用mixed命令:
* 方法二:线性混合模型 mixed y group_f##i.time || id:, remlmixed模型的好处是:即使数据有少量缺失,也不会把一个被试的所有记录都删掉;它不要求球形假设;还能自由扩展随机效应结构。当前很多统计课程和期刊开始接受这种分析方式,因为它更灵活,也更能真实反映数据的层次结构。
3.3 交互效应的可视化与边际效应
跑完mixed之后,不要只盯着交互项的P值看,配合画图才更有说服力。Stata里的margins和marginsplot是可视化交互效应的利器:
* 拟合模型 mixed y group_f##i.time || id:, reml * 估计各时间点上两组的调整均值 margins group_f, at(time=(1(1)3)) * 画交互作用图 marginsplot画出来的图形常常是一条剪刀差形状的两条折线。如果两条折线明显分离或者走向相反,即便交互项P值只是边缘显著,图形本身对你向同行解释研究发现也很有帮助。期刊论文里放一张这样的交互效应图,审稿人通常不会再在这个环节挑刺。
4. 结果解读:Stata输出表格怎么看
4.1 关键输出指标:先看交互,再看主效应
跑完mixed后,Stata输出分成几个部分:观测值信息、模型拟合统计量(对数似然、AIC、BIC等)、随机效应方差、固定效应检验表。
最核心的是固定效应表,里面包含四行最值得关注:
- 组间主效应(group_f):检验两组在总体平均水平上是否有差异。
- 时间主效应(time):检验三个时间点整体上是否存在差异。
- 组×时间交互效应(group_f#time):检验两组在不同时间点的变化趋势是否不同。
- 常数项(_cons):整体截距,通常不需要过度解读。
表格中每个效应都有F值、自由度、P值。判断规则很简单:P<0.05则认为该效应具有统计学显著性。但顺序上要记牢:如果交互效应显著,主效应的解读就要谨慎。比如交互显著说明“两组随时间变化的方式不同”,这时候单纯说“时间主效应显著”意义就不大了,因为整体趋势被两组的差异模式掩盖了。
如果跑的是传统anova+repeated(time),输出里还会额外出现:
- Mauchly's test for sphericity:球形假设检验。若P<0.05,说明球形假设被违反。
- Greenhouse-Geisser epsilon(GG系数)
- Huynh-Feldt epsilon(HF系数)
当Mauchly检验P<0.05时,应当读取GG或HF校正后的P值。校正后的P值会比未校正的更大,这是为了控制第一类错误率,是正确做法,不要觉得“校正后不显著了”就失落,这恰恰说明原始结果可能是假阳性。
4.2 事后检验与效应量:论文写作绕不开的两件事
当主效应或交互效应显著时,通常需要进一步做多重比较,确定具体是哪些时间点之间、哪些组之间存在差异。
如果你用的是mixed模型,事后两两比较可以用:
* 先拟合模型 mixed y group_f##i.time || id:, reml * 对时间主效应做多重比较(bonferroni校正) margins time, pwcompare(effects) mcompare(bonferroni) * 如果要看交互:在不同时间点上比较组间差异 margins group_f, at(time=(1(1)3)) pwcompare(effects) mcompare(sidak)第一条margins time会输出三组时间之间的两两差异、标准误、P值和校正后的置信区间。第二条则在每个时间点上比较治疗组和对照组的差异,回答“治疗组在哪个时间点开始起效”这类问题。校正方法的选择没有绝对标准,bonferroni偏保守,sidak稍宽松一点,报告中注明即可。
效应量方面,重复测量方差分析中最常报告的是偏eta平方(partial eta-squared)。用estat esize拿到:
mixed y group_f##i.time || id:, reml estat esize常见的判断经验是:partial eta-squared在0.01~0.06之间算小效应,0.06~0.14算中等效应,0.14以上算大效应。这几个阈值源自Cohen(1988)的经验建议。值得一提的是,不同学科的效应量习惯不一样,报告时最好说出自己采用的判断标准,方便读者理解。
5. 操作注意事项与常见坑:实测中总结的避坑指南
5.1 球形假设:最被教科书强调、实操中最容易忽略
球形假设是重复测量方差分析里绕不开的话题。简单理解:它要求任意两次测量之间差值的方差大致相同。比如你的三个时间点得分,t2-t1的方差、t3-t2的方差、t3-t1的方差,三者要接近。
为什么这个假设重要?因为在传统重复测量ANOVA中,组内均方的误差计算是“汇总”的,如果各差值的方差不一致,汇总误差就会偏离真实情况,导致F检验的P值偏小、更容易犯第一类错误。
现实中,时间跨度越长、测量次数越多,球形假设越容易被违反。高年级纵向队列数据(比如随访5个时间点)中,违反球形几乎成为常态。所以当你看到Stata输出中Mauchly检验的P值小于0.05时,别慌。要么采用GG或HF校正后的P值,要么直接改用mixed模型——混合模型通过直接建模随机效应结构来规避球形假设的约束,是更省心的选择。
5.2 缺失数据、离群值与随机效应结构
实操中还有一个很现实的问题:随访数据十有八九有缺失。有人搬家了没来测,有仪器故障测不成,也有人半途退出。
传统anova+repeated()在处理缺失时非常“粗暴”:只要有一个时间点缺失,整个被试的所有观测都会被剔除。如果缺失比例超过10%,样本量损失就很可观,检验力随之下降。
mixed命令则温和得多。它允许拥有至少一次观测记录的被试进入模型,这在纵向研究中几乎是救命稻草。不过要注意,mixed对缺失处理隐含的假设是数据缺失随机(MAR),也就是缺失与否和未观测到的结果本身无关。如果这个假设不成立,即使使用混合模型也需要谨慎解释结论,最好做敏感性分析。
离群值对重复测量方差分析的影响同样不可忽视。跑模型之前,建议先画箱线图检查:
graph box y, over(time) by(group_f)如果发现极端离群值,不要急着删。先回溯原始记录判断是否录入错误;如果是,修正;如果不是,考虑采用稳健标准误或对数据进行对数变换。直接把离群值“处理掉”而不留下记录,是对数据的不尊重。
5.3 随机效应结构:别只会写|| id:
用mixed时,随机效应的设定真的非常重要。我在实际教学中见过太多人默认用|| id:做随机截距,却没想过这样是否足够。
标准重复测量设计中,每个被试的多次测量共享一个随机截距,描述的是“这个人整体的水平比平均高还是低”。但有些情况下,不仅个体平均水平不同,个体随时间的变化趋势也可能不同。比如有人治疗效果好、血压一路下行,有人治疗反应差、血压反而上升。这时就需要考虑随机斜率:
* 随机截距 + 随机斜率 mixed y group_f##i.time || id: time, reml加了随机斜率后,模型的参数数量增加,但能更真实地捕捉个体异质性。是否该加随机斜率,可以用似然比检验来判断:
* 先拟合随机截距模型 mixed y group_f##i.time || id:, reml estimates store m1 * 再拟合随机截距+随机斜率模型 mixed y group_f##i.time || id: time, reml estimates store m2 * 似然比检验 lrtest m1 m2如果似然比检验P<0.05,说明加入随机斜率显著改善了模型拟合,应该保留随机斜率。这一步很多人会跳过,但跳过之后,模型可能因为随机效应设定不足而产生偏倚的参数估计。
6. 零基础小白入门Stata统计学/计量经济学学习路径
6.1 第一步:安装、注册与界面认识
很多人一上来就到处搜“Stata下载”,我统一建议是:从Stata官方网站申请试用版,或者通过所在学校、机构的授权获取完整许可。正版Stata提供多种授权类型:无时间限制的永久版、年度订阅版等,学生版价格也比较友好。安装完成后,打开软件会看到五个区域:
- 命令窗口(Command):输入命令、回车执行。
- 结果窗口(Results):显示命令执行后的输出结果。
- 变量窗口(Variables):列出当前数据集中的所有变量。
- 属性窗口(Properties):显示选中变量的详细属性。
- 历史记录窗口(Review):记录本session执行过的所有命令。
新手最友好的操作方式是“命令窗口 + do文件”。do文件相当于一个文本脚本,你可以把要执行的多条命令写进去,然后再一键运行。它既方便修改,也能完整保存分析过程。建议所有初学者从第一天起就养成“所有操作都写在do文件里”的习惯,而不是在命令窗口里一条条敲——后者一旦关闭窗口,做过什么都很难复原。写论文的时候,一份规范do文件也是“可复现研究”的重要部分。
6.2 学习路线与资源推荐:三个月从零到能跑回归
下面这条三个月学习路径,是我带过几批零基础学员后逐步定型的,你可以直接照抄:
第一周:熟悉界面、掌握数据导入导出。重点学import excel、use、save、export excel等命令。遇到不懂的命令,直接输入help 命令名查看官方帮助。
第二周到第三周:数据清洗与整理。重点学gen生成新变量、rename重命名、label variable添加变量标签、label values添加值标签、缺失值处理、duplicates识别重复值。这会占据实际研究里60%的时间,别觉得无聊,省下来的时间后面都会回报你。
第四周到第五周:描述性统计与图形。例如tabstat、summarize、tabulate,以及histogram、boxplot、twoway scatter等作图命令。图形是数据表达的重要载体,也是统计分析的“眼睛”。
第六周到第八周:基础的统计检验。包括ttest做t检验、tabulate做卡方检验、pwcorr做相关分析、regress做线性回归。重点是搞懂P值、置信区间和回归系数的含义,不要只背命令。
第九周到第十二周:进阶分析。从oneway、anova开始,然后进入本文讲的mixed和重复测量方差分析,后续可扩展到协方差分析、逻辑回归等。你需要带着自己手头的一份真实数据去学,每学会一个命令就在数据上试一遍,这样可以做到学以致用。
学习资源方面,我个人亲测有效的是这几个:
- Stata官方帮助文档和PDF手册(
help命令永远是最直接的老师) - UCLA IDRE的Stata教程(免费,结构清楚,例子实用)
- 陈强《计量经济学及Stata应用》
- 连玉君的Stata教学视频
- Stata官方YouTube频道
不建议一开始就啃大部头计量经济学教材。最理想的方式是,你手里有一份真实研究数据,带着问题去学——每学会一个命令,立刻在自己的数据上验证一遍。这样三个月下来,比只读书不实操的人进步快得多。
写到这里,我其实最想跟你分享的不是命令本身,而是动手实践的勇气。重复测量方差分析这个概念初看很吓人,但只要手里有一份自己的数据,哪怕只有十几个人、三个时间点,按文中流程自己跑一遍,输出表格里的那些F、P、epsilons就会迅速变得亲切起来。
我个人在这些年的重复测量分析实操中体会最深的一点是:不要一味迷信“教科书默认选项”,一定要先理解自己数据的结构和缺失情况,再决定用传统anova还是mixed模型。数据模型是为研究问题服务的,不是反过来被某种方法绑架。如果你刚开始接触Stata,就把今天的内容当作一张地图,碰到命令就查、碰到报错就debug,多试几次就能跑出自己满意的结果。祝你的数据分析顺利,有具体问题欢迎还在评论区留言交流。