
学统计的人大概都有这种经历第一次接触卡方检验觉得公式和数据都对得上作业也能做出来等真正拿到自己的临床数据才发现该用哪一个卡方才是最难的一关。《实用医学统计学与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人。四格表如下组别有效无效合计治疗组45550对照组301545合计752095先算期望频数。以治疗组-有效这一格为例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查卡方分布表df1时α0.05的临界值是3.847.76明显超过P 0.01。所以可以认为两组有效率差异有统计学意义。顺便记住一个偷懒技巧2×2表可以用简化公式χ² n(ad-bc)² / [(ab)(cd)(ac)(bd)]验证算出来也是7.76两个公式在数值上完全等价平时手算校验的时候很方便。2. 四格表别急着下结论先判断用哪个方法再谈结果2.1 应用条件的判定顺序n和T是一对铁律很多人在这一步翻车。教材上写得清清楚楚卡方检验是对卡方分布的一种近似近似效果取决于样本量和期望频数。样本太小、期望频数太小的时候统计量会偏离真实的卡方分布此时用标准公式算出来的P值不可靠。所以每次做四格表卡方之前都要按这个顺序过一遍先看总例数n是否≥40再看最小理论频数T是否≥5如果最小T落在1到5之间考虑校正或精确检验如果出现T1或者n40直接用Fisher确切概率法。我把这个判定流程整理成一个对照表临床分析时直接对照查条件推荐方法n≥40所有T≥5Pearson卡方n≥40存在1≤T5连续校正卡方或Fisher确切概率法n40或存在T1Fisher确切概率法这里要特别强调判断依据是最小理论频数不是实际频数。很多人看某个格子实际人数是2就觉得不能用卡方这是误解。理论频数是由边际合计推算出来的实际频数小但期望频数不小的情况很常见判断时一定要以SAS输出的Expected值期望频数为准。2.2 Pearson卡方、连续校正与Fisher精确检验怎么选三个方法看着差不多背后的逻辑完全不同。Pearson卡方的原理就是第一节讲的近似公式适用于大样本、期望频数不太小的情况。它的优点是计算简便、统计功效高缺点是近似条件不满足时P值会偏离真实值。连续校正卡方Yates校正是在Pearson公式基础上做的修正。因为2×2表的卡方统计量是离散数据而卡方分布是连续分布当期望频数较小时未经校正的统计量倾向于被高估也就是P值偏小更容易假阳性。校正公式会在每个格子的偏差上减去0.5再平方相当于惩罚了一下小样本下的乐观估计。实际数据分析中当1≤T5时有些教材推荐连续校正有些教材直接推荐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就可以用如果n40或者最小T1直接看双侧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 datachisq_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它的自由度为1P值就是那个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 FREQproc freq datachisq_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 datachisq_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层OR3.5B层OR0.8说明分层因素与分组存在交互作用此时汇总出一个公共OR就没有意义正确做法是分别报告每一层的OR。SAS里可以用Breslow-Day检验来检查OR齐性如果Breslow-Day检验P值很小就说明各层OR不一致不要勉强汇总。6. 完整实战案例从数据到论文可用的卡方检验报告6.1 案例设定与数据展示假设我们要比较三种不同给药方案下患者的皮疹发生情况数据如下方案发生皮疹未发生皮疹合计发生率A方案10304025.0%B方案8324020.0%C方案238405.0%合计2010012016.7%算最小期望频数每组的行合计都是40皮疹总发生20人40×20/1206.67四个格子最小的期望频数是6.67大于5总例数120也大于40所以Pearson卡方有效。6.2 逐步操作与SAS输出SAS代码依然是PROC FREQdata 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 datarash; tables group*outcome / chisq expected cellchi2 nocol nopercent; weight count; run;跑出来的卡方统计量约6.24自由度2P0.044三组间差异有统计学意义。接下来做两两比较3组共3对Bonferroni校正后检验水准为0.0167。用where语句依次筛出A对C、B对C、A对B分别跑Fisher精确检验。结果大概是A方案与C方案比较P0.012小于0.0167差异有统计学意义其余两对P值都大于0.0167差异无统计学意义。这个结果说明总体卡方显著其实主要来源于A方案与C方案的差异B方案夹在中间和谁也不构成显著差异。这种情况在实际研究中非常典型也是新手报告最容易出问题的地方。好多人拿到总体P0.044就笼统地写三组间差异有统计学意义其中A方案明显优于其他方案这种结论完全没有两两比较的支持。6.3 论文里的标准表述模板一段可以直接放进论文结果部分的写法供参考三种方案皮疹发生率分别为25.0%、20.0%和5.0%差异有统计学意义χ²6.24P0.044。进一步两两比较采用Fisher确切概率法并采用Bonferroni校正校正后检验水准α0.0167结果显示仅A方案与C方案间差异有统计学意义P0.012A方案与B方案P0.58、B方案与C方案P0.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érs V。审稿人看到只有P值没有效应量的结果印象分会大打折扣。卡方检验这套东西知识点本身并不复杂难的是每一步都在做选择。应用条件是对是错分层做不做两两比较怎么校正这些选择叠加起来才真正决定一篇论文的统计部分是不是经得起推敲。我自己每次拿到分类变量数据都会把这篇笔记里的流程从头过一遍多花几分钟后面返工的几率小得多。