学统计的人大概都有这种经历:第一次接触卡方检验,觉得公式和数据都对得上,作业也能做出来;等真正拿到自己的临床数据,才发现"该用哪一个卡方"才是最难的一关。《实用医学统计学与SAS应用》里讲分类变量资料比较,前前后后涉及了Pearson卡方、连续校正卡方、Fisher确切概率法、似然比卡方、CMH分层卡方,还有趋势检验。名字都记住了,遇到实际问题还是不知道调哪个。这篇文章不是教材的替代品,权当是我反复啃这本书、反复跑SAS之后的一份"消化笔记"——把分类变量比较的判定逻辑、SAS代码和输出解读串成一条线,再把容易被忽略的细节单独拿出来说。无论你是正在备考的医学生,还是在临床上需要自己动手做统计的医生,照着这个思路走一遍,至少不会再面对PROC FREQ的输出结果发呆。
1. 卡方检验到底在检验什么:从思想到公式,一次说清楚
1.1 卡方检验的核心思想:观测频数与期望频数之间的"账差"
分类变量资料的最常见分析诉求,就是比较"组间构成"或"组间率"是否有差异。比如比较治疗组和对照组的有效率,数据落在2×2的四格表里:行是分组,列是结局(有效/无效),四个格子里是人数。用统计学的语言翻译这个问题就是:如果治疗根本没有作用,两组本质上来自同一个总体,那么在相同的有效率之下,我们"期望"看到的四格频数应该是多少?实际看到的频数,和这个期望频数之间,会不会差得太多?
卡方检验的全部逻辑就建立在这个对比上。它把每个格子的观测频数(Observed,记作O)和原假设成立时的期望频数(Expected,记作T)做差值,再把差值按T的大小做个标准化,最后汇总成一个统计量。差得越离谱,说明实际数据和"两组没有差异"这个假设越不吻合,P值就越小,我们就越有理由拒绝原假设。
这里有一个新手很容易绕进去的问题:为什么不能直接看两组有效率差了多少个百分点?因为抽样误差会随样本量变化,100人的研究和1000人的研究,即使率差相同,说服力完全不一样。卡方统计量的巧妙之处在于,它通过期望频数T把样本量的影响吸收进来了,样本越大,期望频数越大,同一个观察到的绝对偏差就越容易被判定为"不像是随机误差"。这和t检验里标准误的作用是同一个道理。
1.2 手算一个四格表的χ²值,把公式彻底吃透
教科书上的基本公式是:
χ² = Σ (O - T)² / T
其中T = 行合计 × 列合计 / 总例数。看起来简单,但很多人从来没真正手算过,导致后面读SAS输出时没有"数值感"。我还是建议你哪怕只算一次。举个我常用来教学的例子:治疗组50人,有效45人、无效5人;对照组45人,有效30人、无效15人。四格表如下:
| 组别 | 有效 | 无效 | 合计 |
|---|---|---|---|
| 治疗组 | 45 | 5 | 50 |
| 对照组 | 30 | 15 | 45 |
| 合计 | 75 | 20 | 95 |
先算期望频数。以"治疗组-有效"这一格为例,T = 50×75/95 = 39.47,意思是如果治疗组和对照组有效率相同,治疗组50人里理论上应该有39.47人有效。同理:
- 治疗组无效:T = 50×20/95 = 10.53
- 对照组有效:T = 45×75/95 = 35.53
- 对照组无效:T = 45×20/95 = 9.47
代进公式:
χ² = (45-39.47)²/39.47 + (5-10.53)²/10.53 + (30-35.53)²/35.53 + (15-9.47)²/9.47 ≈ 7.76
自由度是(行数-1)×(列数-1) = 1,查卡方分布表,df=1时α=0.05的临界值是3.84,7.76明显超过,P < 0.01。所以可以认为两组有效率差异有统计学意义。顺便记住一个偷懒技巧:2×2表可以用简化公式χ² = n(ad-bc)² / [(a+b)(c+d)(a+c)(b+d)]验证,算出来也是7.76,两个公式在数值上完全等价,平时手算校验的时候很方便。
2. 四格表别急着下结论:先判断"用哪个方法"再谈结果
2.1 应用条件的判定顺序:n和T是一对铁律
很多人在这一步翻车。教材上写得清清楚楚,卡方检验是对卡方分布的一种近似,近似效果取决于样本量和期望频数。样本太小、期望频数太小的时候,统计量会偏离真实的卡方分布,此时用标准公式算出来的P值不可靠。所以每次做四格表卡方之前,都要按这个顺序过一遍:
- 先看总例数n是否≥40;
- 再看最小理论频数T是否≥5;
- 如果最小T落在1到5之间,考虑校正或精确检验;
- 如果出现T<1,或者n<40,直接用Fisher确切概率法。
我把这个判定流程整理成一个对照表,临床分析时直接对照查:
| 条件 | 推荐方法 |
|---|---|
| n≥40,所有T≥5 | Pearson卡方 |
| n≥40,存在1≤T<5 | 连续校正卡方或Fisher确切概率法 |
| n<40,或存在T<1 | Fisher确切概率法 |
这里要特别强调:判断依据是"最小理论频数",不是"实际频数"。很多人看某个格子实际人数是2,就觉得不能用卡方,这是误解。理论频数是由边际合计推算出来的,实际频数小但期望频数不小的情况很常见,判断时一定要以SAS输出的Expected值(期望频数)为准。
2.2 Pearson卡方、连续校正与Fisher精确检验怎么选
三个方法看着差不多,背后的逻辑完全不同。
Pearson卡方的原理就是第一节讲的近似公式,适用于大样本、期望频数不太小的情况。它的优点是计算简便、统计功效高,缺点是近似条件不满足时P值会偏离真实值。
连续校正卡方(Yates校正)是在Pearson公式基础上做的修正。因为2×2表的卡方统计量是离散数据,而卡方分布是连续分布,当期望频数较小时,未经校正的统计量倾向于被高估,也就是P值偏小,更容易"假阳性"。校正公式会在每个格子的偏差上减去0.5再平方,相当于"惩罚"了一下小样本下的乐观估计。实际数据分析中,当1≤T<5时,有些教材推荐连续校正,有些教材直接推荐Fisher精确检验,我的经验是:如果校正后恰好卡在临界值附近,那就再跑一遍Fisher,以Fisher的结果为主。
Fisher确切概率法的思路完全不一样,它不依赖任何近似分布,而是基于超几何分布精确计算出在当前边际合计固定的情况下,出现"比观测数据更极端"的各种四格表组合的概率之和。它的优点是没有近似条件限制,小样本下最可靠,缺点是当样本量大时计算量会急剧上升,不过现代计算机根本不在乎这点开销。所以现在越来越多的统计学家建议:能跑Fisher就跑Fisher,别纠结校正不校正。在审稿人眼里,Fisher精确检验的结果几乎挑不出毛病。
2.3 SAS输出的自动警告要怎么读
用PROC FREQ跑完卡方后,SAS有时会在输出末尾附带一句警告,大意是"部分格子期望频数小于5,卡方检验可能不是有效检验"。这句话很多新手看不懂,或者看到了也不在意。实际含义是:SAS已经帮你做了应用条件的快速筛查,如果出现这条警告,Pearson卡方的P值就不能直接用了。
正确的做法是回头去看频数表里的Expected行,找到最小的期望频数,再按照2.1的判定流程选择合适的方法。如果最小T在1和5之间,SAS输出里那个"Continuity-Adjusted Chi-Square"就可以用;如果n<40或者最小T<1,直接看双侧Fisher精确检验的结果。记住这条警告不是让你放弃分析,而是提示你换更合适的检验方法。
3. SAS实操:PROC FREQ做卡方检验的代码模板与结果逐项解读
3.1 数据录入:频数表和原始记录两种格式怎么选
SAS里做卡方检验,第一步是决定数据怎么进。两种最常见的格式:
第一种是原始记录格式,每一行代表一个受试者,有两个变量,一个记录分组,一个记录结局。这种格式最直观,收集数据阶段的Excel问卷通常就是这个样子,读进来直接用。
第二种是汇总频数格式,适合已经有统计好的四格表或者R×C表,每一行代表一个格子,除了分组和结局两个变量之外,多一个count变量记录这个格子的人数。这种格式必须配合weight语句使用,否则SAS默认每行只算一个人,结果会错得离谱。
我平时整理数据更喜欢用汇总频数格式,因为医学论文里的数据几乎都是以表格形式呈现的,直接从论文表里把数字抄进代码就能复现分析,不用来回翻原始数据库。
3.2 四格表的完整代码
以第一节的治疗组/对照组数据为例,SAS代码如下:
data chisq_tab; input group outcome count; datalines; 1 1 45 1 2 5 2 1 30 2 2 15 ; run; proc freq data=chisq_tab; tables group*outcome / chisq expected cellchi2 nocol nopercent; weight count; run;这里逐条解释一下选项的作用。chisq选项是核心,负责输出卡方检验的统计量;expected选项会在每个格子旁边输出期望频数,这是判断应用条件的重要依据;cellchi2输出每个格子对总卡方的贡献,可以帮助定位到底是哪个格子的偏差最大;nocol和nopercent是让输出只保留行百分比,免得表格太拥挤。如果你用的是原始记录格式,只要去掉weight语句、把datalines换成实际变量读入即可,tables语句和proc freq完全一样。
3.3 输出结果逐项解读
PROC FREQ的输出主要分三块看。
第一块是两变量的交叉频数表。每个格子有频数、期望频数、行百分比、格百分比等好几行数字,初学者经常看花眼。我的建议是:主要看频数和期望频数这两行,概率先不管。期望频数行接下来要用来做方法选择,是整张表里最重要的一组数。
第二块是"Statistic"表,里面列了Chi-Square、Likelihood Ratio Chi-Square、Continuity-Adjusted Chi-Square、Mantel-Haenszel Chi-Square。对四格表来说,Pearson卡方看第一行Chi-Square,它的自由度为1,P值就是那个Pr > ChiSq。如果满足连续校正条件,看第三行Continuity-Adjusted的结果。
第三块是Fisher精确检验的表,分单侧和双侧两个P值。医学论文几乎都是报告双侧P值,所以习惯性地看"Two-sided Pr <= P"那一行。另外,对于2×2表,SAS还会输出Phi系数等关联强度指标,Phi系数可以看成是分类变量版本的相关系数,绝对值越接近1说明关联越强。P值告诉你"有没有关系",Phi系数告诉你"关系多大",论文里两个一起报告才有说服力。
4. R×C表的"分路"处理:双向无序、单向有序的统计策略完全不同
4.1 先给你的R×C表定性,再决定分析方法
行数和列数都超过2的R×C表,麻烦程度直接翻倍。因为"R×C表"这个称呼掩盖了一个关键信息:行变量和列变量的性质决定了你该用哪种检验。我刚学统计时在这里犯过不少糊涂,现在遇到R×C表第一反应是先把表定性,而不是急着跑代码。
第一种是双向无序R×C表,比如比较三种治疗方案(无序)在"有效/无效"(二分类)上的差异,或者比较不同血型(无序)和某种基因型(无序)之间的关联。这种表的分析方法就是普通卡方检验,PROC FREQ直接跑就可以。
第二种是单向有序R×C表,结局是等级资料,比如疗效分为"痊愈、显效、进步、无效",或者严重程度分为"轻、中、重"。这时候普通卡方检验检验的是"各组构成比是否有差异",但它忽略了等级的顺序信息,相当于把"轻中重"当成互不相关的三个类去比较,统计功效会打折扣。正确做法是使用趋势卡方检验(Cochran-Armitage趋势检验),或者用基于秩和思想的非参数方法。SAS里做趋势检验可以用PROC FREQ的cmh选项,看其中的"Row Mean Scores Differ"那一行统计量,这行结果专门针对行变量是等级的情况。
第三种是双向有序且属性相同的表,比如两位医生对同一批患者的诊断结果,属于一致性评价,要用Kappa检验而不是卡方检验。
我见过太多人把单向有序的疗效数据直接丢进普通卡方,审稿人一问"你们的趋势检验呢"就答不上来。记住一句话:属性相同看Kappa,结局有序看趋势,其他情况看卡方。
4.2 R×C表结果显著后的两两比较与Bonferroni校正
三组或三组以上的无序分类数据,做完卡方如果P < 0.05,只能说明"总体上各组间存在差异",不能说明"哪两组之间有差异"。比如三种治疗方案的有效率差异有统计学意义,但到底是A优于B,还是A优于C,还是B优于C,普通卡方不回答这个问题。这时候要做事后两两比较。
最稳妥的做法是把每组两两组合拆成多个2×2表,分别做卡方或Fisher精确检验,然后对检验水准做Bonferroni校正。三组之间有3个两两比较,校正后的检验水准α' = 0.05/3 = 0.0167;四组之间有6个两两比较,α' = 0.05/6 = 0.0083。只有P值小于这个校正后的水准,才能判定两组间差异有统计学意义。
SAS里的实现很简单,每次用where语句筛出一对组别,再跑PROC FREQ:
proc freq data=chisq_rdc; tables group*outcome / chisq; weight count; where group in (1, 2); run;注意两两比较也要遵循第二章的判定规则,样本量变小之后,原来的卡方可能不再适用,所以小样本的两两比较我一般直接指定用Fisher精确检验。另外,别用"卡方显著就两两全做、卡方不显著就不做"这样的策略,这是事后分析的典型错误,后者属于"无显著性前提下的数据挖掘",审稿人非常反感。
5. 分层卡方与混杂控制:CMH分析的基本逻辑和SAS实现
5.1 为什么分层:从"辛普森悖论"说起
有时候数据整体分析的结果和分层分析的结果完全相反,这不是统计软件坏了,而是出现了混杂。最经典的例子是某种药物治疗效果的评价:总体上看治疗组有效率低于对照组,但按病情轻重分层后,每一层内治疗组都优于对照组。原因是分组变量在病情轻重上分布严重不平衡,病情轻的患者大量进了对照组,把对照组的总体有效率拉高了。
医学研究里这种混杂无处不在,年龄、性别、病程、疾病严重程度都可能成为混杂因素。处理办法之一就是分层:把数据按混杂因素分成若干层,然后在每一层内比较组间差异,最后再汇总。这就是CMH卡方(Cochran-Mantel-Haenszel检验)要做的事。它检验的是"控制分层因素后,分组与结局之间的关联是否仍然存在",相当于分类变量版的协方差分析。
5.2 CMH检验的SAS代码与结果解读
CMH分析在SAS里依然用PROC FREQ实现,只需把tables语句变成三层:
proc freq data=chisq_strat; tables stratum*group*outcome / cmh; weight count; run;变量顺序有讲究:第一个变量是分层因素,第二个是分组变量,第三个是结局变量。SAS输出里会给出Cochran-Mantel-Haenszel统计量,一般看"General Association"那一行,自由度为1时对应的P值就是控制分层后的检验结果。同时对2×2×K表,SAS还会输出一个公共比值比(Common Odds Ratio)及其95%置信区间,这个值就是调整混杂后暴露因素与结局的关联强度,非常有报告价值。
但有一个前提必须先验证:各层的比值比是否一致。如果A层OR=3.5,B层OR=0.8,说明分层因素与分组存在交互作用,此时汇总出一个"公共OR"就没有意义,正确做法是分别报告每一层的OR。SAS里可以用Breslow-Day检验来检查OR齐性,如果Breslow-Day检验P值很小,就说明各层OR不一致,不要勉强汇总。
6. 完整实战案例:从数据到论文可用的卡方检验报告
6.1 案例设定与数据展示
假设我们要比较三种不同给药方案下患者的皮疹发生情况,数据如下:
| 方案 | 发生皮疹 | 未发生皮疹 | 合计 | 发生率 |
|---|---|---|---|---|
| A方案 | 10 | 30 | 40 | 25.0% |
| B方案 | 8 | 32 | 40 | 20.0% |
| C方案 | 2 | 38 | 40 | 5.0% |
| 合计 | 20 | 100 | 120 | 16.7% |
算最小期望频数:每组的行合计都是40,皮疹总发生20人,40×20/120=6.67,四个格子最小的期望频数是6.67,大于5,总例数120也大于40,所以Pearson卡方有效。
6.2 逐步操作与SAS输出
SAS代码依然是PROC FREQ:
data rash; input group outcome count @@; datalines; 1 1 10 1 2 30 2 1 8 2 2 32 3 1 2 3 2 38 ; run; proc freq data=rash; tables group*outcome / chisq expected cellchi2 nocol nopercent; weight count; run;跑出来的卡方统计量约6.24,自由度2,P=0.044,三组间差异有统计学意义。接下来做两两比较,3组共3对,Bonferroni校正后检验水准为0.0167。用where语句依次筛出A对C、B对C、A对B分别跑Fisher精确检验。结果大概是:A方案与C方案比较P=0.012,小于0.0167,差异有统计学意义;其余两对P值都大于0.0167,差异无统计学意义。这个结果说明,总体卡方显著其实主要来源于A方案与C方案的差异,B方案夹在中间,和谁也不构成显著差异。
这种情况在实际研究中非常典型,也是新手报告最容易出问题的地方。好多人拿到总体P=0.044就笼统地写"三组间差异有统计学意义,其中A方案明显优于其他方案",这种结论完全没有两两比较的支持。
6.3 论文里的标准表述模板
一段可以直接放进论文结果部分的写法供参考:
"三种方案皮疹发生率分别为25.0%、20.0%和5.0%,差异有统计学意义(χ²=6.24,P=0.044)。进一步两两比较采用Fisher确切概率法,并采用Bonferroni校正(校正后检验水准α'=0.0167),结果显示仅A方案与C方案间差异有统计学意义(P=0.012),A方案与B方案(P=0.58)、B方案与C方案(P=0.084)间差异均无统计学意义。"
这里P值是我按前面的计算逻辑估的,实际以SAS输出为准,但表述结构完全可以照搬。
7. 关于卡方检验的常见误用,我踩过和见过别人踩的五个坑
7.1 总例数不够、期望频数太小还硬用Pearson卡方
这是重灾区。尤其是做回顾性病历分析的时候,某种罕见结局全组只有几个病例,有些分析者强行把四格表跑出Pearson卡方,P值看上去挺美,实际完全不可靠。我自己的习惯是:看到任何一张表,第一眼先看总例数,然后看期望频数最小值。如果这两个条件不满足,直接切到Fisher精确检验,不犹豫。SAS在chisq选项下会自动输出Fisher精确检验结果,根本不用额外写代码,只是很多人根本没注意去看。
7.2 三组及以上比较直接拆成多个四格表
三组间两两比较最多有3对,拆开各自做卡方并各自报P值,这种做法的问题在于放大了I类错误。即使组间完全没差异,3对比较中至少有一对假阳性的概率也不是0.05,而是1-(0.95)³≈0.143。这就是为什么要先做总体卡方、再做Bonferroni校正。另外提醒一句,如果总体卡方不显著,原则上就不应该再做两两比较了,否则属于典型的"事后扒数据"。
7.3 等级资料当成无序分类资料直接套卡方
"痊愈、显效、进步、无效"这类等级结局,因为形式上也是几个分类,所以特别容易被顺手丢进卡方检验。但卡方检验不关心类别之间的顺序,它把"痊愈"和"显效"的距离当成和"痊愈"和"死亡"一样远。正确的做法是对结局做趋势检验或直接用秩和检验。SAS里如果只想用PROC FREQ做趋势检验,在tables语句加cmh选项后看"Row Mean Scores Differ"那行就是。这个细节在《实用医学统计学与SAS应用》里讲得很清楚,但应用的时候总是被忽略。
7.4 忘记加weight语句导致的全盘错误
汇总频数格式的数据如果漏写weight语句,SAS会把每一行当成一个样本去分析,你可能只输入了4行数据,它却以为你的总例数是4,算出来的P值必然是错的,而且错得毫无征兆。这个坑我自己踩过,帮别人排查时也遇到过不止一次。建议每次跑完都核对一下输出频数表里的合计列,看看总例数和你预期的是否一致。这个习惯能救你无数次。
7.5 只看P值,不看效应量和方向
最后一个问题不是技术问题,而是思维习惯。卡方检验的P值只说明"有无关联",不说明"关联多大、方向如何"。一个大样本研究里,哪怕有效率差异只有2个百分点,只要样本量足够大,P值一样可以小于0.001。所以报告卡方检验结果时,我建议同时给出率差或OR值及其置信区间,必要时再加上Phi系数或Cramér's V。审稿人看到只有P值没有效应量的结果,印象分会大打折扣。
卡方检验这套东西,知识点本身并不复杂,难的是每一步都在"做选择"。应用条件是对是错,分层做不做,两两比较怎么校正,这些选择叠加起来,才真正决定一篇论文的统计部分是不是经得起推敲。我自己每次拿到分类变量数据,都会把这篇笔记里的流程从头过一遍,多花几分钟,后面返工的几率小得多。