卡方检验原理与SAS实操:从四格表到PROC FREQ完整指南
2026/9/8 15:00:49 网站建设 项目流程

很多人一提卡方检验,第一反应就是“四格表”“P<0.05”,但真到用SAS跑数据的时候,常常被各种细节卡住。最近重新翻了《实用医学统计学与SAS应用》里分类变量比较的章节,结合自己这些年处理临床数据的经验,把卡方检验从原理到SAS实操完整梳理了一遍。这篇文章不堆公式,重点讲清楚为什么这么做、怎么做、以及那些教材里不会写的坑。对了,先提醒一句:SAS软件和服务器硬盘接口里的SAS(Serial Attached SCSI)完全是两码事,别搜资料的时候搞混了。

1. 为什么分类变量的比较绕不开卡方检验

1.1 卡方检验解决的根本问题

我们平时做统计分析,遇到连续型变量(比如血压、体重、白蛋白值)比均值,用t检验或方差分析;遇到分类变量(比如性别、是否吸烟、治疗有效/无效),比的是“率”或者“构成比”的差别,这时候就轮到卡方检验登场了。

卡方检验的核心逻辑,说白了就是四个字:比较实际值与理论值。它先假设两组或多组之间的率没有差别(零假设),基于这个假设推算出理论上各组应该有多少例发生某事件,称为理论频数或期望频数;然后把实际观察到的频数和理论频数作比较,两者差距越大,卡方值就越大,越说明“两组率相等”这个假设站不住脚,从而拒绝零假设,认为组间差异有统计学意义。

举一个最直观的临床例子。想比较两种降压药的疗效:A药组100人,有效80人,有效率80%;B药组100人,有效60人,有效率60%。表面上看A药明显更好,但问题在于——抽样误差有没有可能造成这20个百分点的差异?卡方检验就是回答这个问题的标准工具,它不直接告诉你“A药比B药有效多少”,而是告诉你“A药有效率高于B药这件事,是否已经超出了抽样误差能解释的范围”。

1.2 卡方检验的适用边界和数据形态

不少初学者问:卡方检验是不是只要给两个百分比就能算?不是。卡方检验处理的是绝对频数,不是相对数或均数,而且在特定条件下才有使用前提。

这里的核心是“频数”二字。比如“80%”本身不能直接进卡方公式,必须还原成“80例有效、20例无效”这样的原始计数,再纳入检验。SAS的FREQ过程,名字就是Frequency(频数)的缩写,处理的正是这类数据。

卡方检验最基础的应用是四格表资料,也就是两组各分两类结局,形成2×2的交叉表。但实际医学研究中,还有R×C表资料(比如血型A/B/AB/O四种,比较病例组和对照组的分布差异)、配对设计资料(比如两种诊断方法检测同一批样本)、以及趋势检验(比如剂量-反应关系)。这几类资料虽然都叫“卡方检验”,但公式、SAS语句和适用条件各有差异,混用起来很容易得错结论。后面按场景逐一展开。

1.3 和SAS软件搭配的实用性场景

学习卡方检验用什么工具最顺手?SPSS点菜单确实省事,但要说可复现性、批量处理和大样本分析,SAS的优势非常明显。尤其在医院临床科研或药企统计部门,SAS几乎是标配,很多SCI期刊对统计分析方法的描述也更认可SAS的结果。

SAS里实现卡方检验的看家过程步是PROC FREQ,配合TABLE语句和CHISQ选项,两三行代码就能搞定。它的输出里包含了卡方值、自由度、P值,还能顺手给出Fisher确切概率法的结果,以及OR值、RR值这样有临床意义的效应量。比起手工计算或Excel函数,SAS的优势是:数据清洗到分析一步到位,而且输出结果规范、可追溯。这也是我选择用SAS作为演示工具的核心原因——不只是做题,而是真正用来处理科研数据。

2. 三类卡方检验的选型和原理解析

2.1 普通四格表卡方检验:最常用的基础款

最经典的案例是队列研究或随机对照试验,比较两组结局事件发生率。数据结构就是一个2×2表格:组别(处理组/对照组)×结局(发生/未发生)。

用SAS实现时,代码框架如下:

data chisq_demo; input group $ outcome $ count @@; datalines; A 有效 80 A 无效 20 B 有效 60 B 无效 40 ; run; proc freq data=chisq_demo; tables group*outcome / chisq; weight count; run;

这段代码的关键有三处:datalines逐行录入频数数据;weight count告诉SAS每一行的count代表该组合的样本量(没有这行的话SAS默认一行只算1例,结果就是错的);tables group*outcome / chisq指定要分析的行变量和列变量,并输出卡方检验结果。

运算结果中,SAS会同时给出Pearson卡方、连续性校正卡方和似然比卡方。对于四格表,一般以Pearson卡方为主要结果,但如果样本量不足或理论频数太小,就要看Fisher确切概率法。这个判断标准下文详述。

2.2 配对设计卡方检验:McNemar检验不可替代

配对设计在诊断试验中非常常见。比如用新方法和金标准同时检测200名患者,每个患者得到一组配对的结果——新方法阳性/阴性、金标准阳性/阴性。这种资料的特点是:每个受试者的两个结果成对出现,不再独立。如果直接套用普通四格表卡方检验,会犯“数据独立性假设被破坏”的错误,这时应当用McNemar检验

McNemar检验只关注“配对结果不一致”的那两类:新方法阳性但金标准阴性,以及新方法阴性但金标准阳性。如果两种方法检测能力没有差异,这两种不一致的频数理论上应相近。SAS实现:

proc freq data=mcnemar_demo; tables new_method * gold_standard / agree; weight count; run;

加一个/ agree选项,SAS会输出McNemar检验结果。注意,AGREE选项同时还会给出Kappa一致性系数,这就是另一个话题了。新手往往在四点表资料里用了普通卡方,导致结果出现方向性的错误——最典型的是把“两种方法检出率一致性”误判成“两种方法有无关联”,这完全是两码事。

2.3 R×C表卡方检验与线性趋势检验

当比较组的数量大于2,或结局的分类多于2时,四格表就扩展成了R×C表。比如比较三种手术方案的并发症发生率(有/无),就是3×2表;比较不同年龄段人群的血型分布(A/B/AB/O),就是4×4表。这一类资料用的依然是卡方检验,但结论解读有区别:卡方检验显著仅表示“各组间存在总体差异”,不能直接推出“哪两组之间差异显著”。要回答后者,需要进一步做事后两两比较,并修正检验水准(比如用Bonferroni法把0.05除以比较次数)。

此外,如果分组变量是有序的(比如轻度、中度、重度),而结局也是二分类,可以进一步做趋势卡方检验(Cochran-Armitage趋势检验),检验“剂量增加”和“效应增强”之间是否存在线性趋势。这在药物临床试验的量效关系探索中非常实用。SAS中的写法是在PROC FREQ里加上/ trend选项,或者用PROC CORRESP做更复杂的对应分析。基础阶段掌握/ trend就够了。

2.4 从公式推导看卡方值到底在算什么

虽然SAS会自动算结果,但理解公式对你判断结果合理性很有帮助。卡方统计量的定义式是:

χ² = Σ (观察频数 - 理论频数)² / 理论频数

其中理论频数(期望频数)由行合计×列合计/总例数得到。每一个格子都计算一个“偏差平方除以期望”的贡献值,最后加总。差值越大、样本量越大、单元格数目越多,卡方值越容易被“放大”,检验也越敏感。

这就是为什么大样本时卡方检验很容易得到P<0.05——它的检验功效随样本量增加而提高。但另一方面,如果样本量太大,即使临床意义微不足道的差异(比如两个率只差2%)也能检出显著,所以做卡方检验时,不但要看P值,还要看率差的置信区间。SAS里用/ risk选项可以输出率差及其95%置信区间,这一步建议作为常规动作加上。

3. SAS实操全流程:从数据清洗到结果解读

3.1 数据结构与频数加权

SAS做卡方检验时,数据有两种存储形式。第一种是原始数据每一行代表一个受试者,两列分别是分组变量和结局变量,有多少人就有多少行;第二种是汇总频数数据,每一行代表一种组合,再加一列权重列记录频数。

第二种形式更省空间,特别适合录入论文表格里的现成数据。但代价是容易忘写weight语句——我见过不止一个同事因为这个疏漏,算出的卡方值看起来很大,其实SAS默认每个组合只算1例,结果完全错误。建议建一个宏变量统一管理权重变量名,或者干脆写注释提醒自己:

* 关键提示:使用汇总频数时必须加上 weight 语句,否则结果错误;

原始数据结构示例:

data cohort; do i = 1 to 100; group = "Treatment"; outcome = (i <= 80); output; end; do i = 1 to 100; group = "Placebo"; outcome = (i <= 60); output; end; run;

生成的数据集包含200行,每行对应一个受试者,这样PROC FREQ就不需要weight语句了。新手我更推荐这种一行一个样本的“长格式”数据,它更接近真实临床数据库的结构。后续做筛选、合并、子组分析都方便。

3.2 PROC FREQ核心语句逐项拆解

PROC FREQ的语句不多,但每个选项都很有分量。以下是一个最完整的分析模板,附带关键注释:

proc freq data=你的数据集; tables 分组变量 * 结局变量 / chisq * 输出卡方检验 expected * 输出期望频数,用于判断卡方适用条件 cellchi2 * 输出每个单元格对卡方值的贡献 norow nocol * 不输出行/列百分比,排版更简洁 relrisk * 输出OR/RR/率差等效应量 ; weight 频数变量; * 如果是汇总频数才需要; exact pchi; * 小样本时输出Fisher确切概率; output out=chi_result pchi chisq; * 把关键结果存成数据集; run;

expected选项是我强烈建议加上的,因为判断卡方检验是否适用(即理论频数条件)时,光靠肉眼看不出来,直接看SAS输出的期望频数表是最稳妥的。cellchi2则能告诉你哪一个格子的偏差贡献最大,比如当结果显著时,你可以定位到究竟是哪个组的哪个结局和期望差别最大。

3.3 结果输出关键点抓读法

SAS输出的卡方检验结果包含多个统计量,你会看到表格中列出:

  • 卡方值(Chi-Square):6.4000
  • 自由度(DF):1
  • P值(Pr > ChiSq):0.0114

同时还会输出似然比卡方(Likelihood Ratio Chi-Square)和Mantel-Haenszel卡方,多数情况下三个结果方向一致,但以Pearson卡方为准。连续校正卡方(Continuity Adj. Chi-Square)用于四格表且样本量适中时,校正后的卡方值会偏小,P值偏保守,通常用于20≤n≤40且存在理论频数在1到5之间的情况。

拿到结果后,建议按照下面这套顺序来读:

  1. 先看期望频数表有没有超过20%的格子期望频数小于5,这是卡方适用条件的硬性门槛;
  2. 满足条件就读Pearson卡方那一行;
  3. 不满足就看Fisher确切概率法结果,尤其是2×2表;
  4. 有统计学意义时,再看relrisk输出的率差、OR值或RR值及其95%置信区间,评估临床意义。

3.4 一份完整的SAS分析示例

用一份模拟数据走一遍完整流程。假设研究问题是:“重症监护病房(ICU)患者早期肠内营养与延迟肠内营养的28天病死率有无差异”,数据如下:早期组200例,死亡28例;延迟组180例,死亡36例。

data icu; input nutrition $ death $ count @@; datalines; early yes 28 early no 172 delay yes 36 delay no 144 ; run; proc freq data=icu; tables nutrition * death / chisq expected cellchi2 relrisk; weight count; run;

运行后,SAS输出四格表、期望频数、卡方值、P值、OR值、率差等。假设结果P=0.1654,结论是“两组28天病死率差异无统计学意义(P>0.05)”,但同时OR=0.65,说明早期肠内营养在方向上似乎有利于降低死亡风险,但这需要更大样本量的研究来验证。这样一个结果解读,既有统计学信息,又有临床导向,回给临床医生时也更有说服力。

4. 常见问题与排查技巧实录

4.1 理论频数太小,卡方结果还能信吗

这是我做咨询时被问得最多的问题。判断标准并不神秘:

  • 总样本量n≥40且所有格子的理论频数T≥5时,直接用Pearson卡方;
  • 当n≥40但有1≤T<5的格子时,用连续性校正卡方或Fisher确切概率法;
  • 当n<40或存在T<1时,只能用Fisher确切概率法

SAS里加exact pchi;语句后,输出中会额外给出Fisher精确检验的P值。四格表情况下,SAS也会自动帮你算,不需要额外操作。对于R×C表,如果期望频数过小,不建议直接用卡方,可以考虑合并类别、增加样本量或使用似然比卡方。

4.2 结果把“有差异”写成“有差异”的陷阱

卡方检验的结果表述,很多人会犯一个语言学错误:检验显著时,适当表述是“组间差异有统计学意义”,而不是“两组有显著差异”。“显著”这个词在统计学里有特指,日常语境下的“显著”容易让读者误以为差异很大,实际上P<0.05只代表“抽样误差导致这种差异的可能性很小”,不代表临床意义大。

反过来,P>0.05也不能直接说“两组没有差异”,更稳妥的说法是“尚不能认为两组差异有统计学意义”,或者“现有样本量不足以检出组间差异”。临床上这层语言功夫很重要,直接影响论文审稿人和临床医生对结果可信度的判断。

4.3 双向无序和有序变量的分析策略

R×C表并非都适合同一个卡方。这里有一个容易踩坑的地方——按变量是否有序来区分:

  • 双向无序(如血型与疾病类型):用Pearson卡方或似然比卡方;
  • 单向有序(如疾病严重程度与分组):如果是结局变量有序,用秩和检验更合适;如果是分组变量有序,可以用趋势卡方;
  • 双向有序(如分期与疗效等级):想做关联分析要用一致性检验(Kappa或Spearman相关),而不是简单卡方。

有些同学不管三七二十一,拿到什么表都跑一个proc freq; tables x*y / chisq;,结果虽然能出P值,但分析逻辑可能是错的。高级阶段要学会按研究设计选择统计量,而不是让SAS替你做统计决策。

4.4 数据量大时的效率建议

真实科研数据往往不止一个结局变量。比如一项队列研究纳入20个基线变量、5个主要结局,每个表格都是一次卡方检验,手工写一遍报表很累。SAS里的高效做法是用数组或宏循环批量完成:

%macro chisq_batch(outcome=, group=); proc freq data=anas; tables &group * &outcome / chisq expected norow nocol; run; %mend; %chisq_batch(outcome=death28, group=treatment); %chisq_batch(outcome=infection, group=treatment); %chisq_batch(outcome=shock, group=treatment);

或者用ods output把多个结果统一捕获到数据集中,后续批量输出到Excel中,方便汇总汇报。这一点在写临床研究报告时非常实用,能让分析报告生成时间从一下午压缩到几分钟。

4.5 别忘了效应量的报告

做卡方检验只报告P值,其实是不够的。推荐在结果表里增加一行率差(Risk Difference)、OR/RR及其95%置信区间。SAS中relrisk选项给的是比值比(OR)和相对风险(RR),输出里注意区分。队列研究和RCT看RR,病例对照研究看OR;诊断试验的配对资料则关注灵敏度和特异度,可结合AGREE选项输出Kappa一致性系数。

这些指标直接提供“差异大小”的信息,相比单纯的P值更加丰富,也是高水平期刊普遍要求报告的内容。

5. 几个值得长期保留的实操心得

5.1 先画四格表再跑程序

正式跑程序前,我习惯先手工列一下四格表的行列排列。把组别放行、结局放列,确认行列变量顺序,避免tables group*outcometables outcome*group结果虽一致(卡方值对称),但后面对比OR值的方向却会颠倒。

5.2 留意SAS中缺失值的处理

PROC FREQ默认会剔除所有变量中含缺失值的观测,如果缺失比例高,这个“隐形剔除”会影响结果。建议先运行proc freq查看缺失情况,或者用missing选项把缺失值作为独立水平呈现——但要注意,这只能用在缺失本身有意义的数据中,否则会造成误导。

5.3 学会利用ODS输出做自动化报告

SAS的ODS(Output Delivery System)可以把你关注的统计量(卡方值、DF、P值)自动捕获成数据集,再导出到Excel或Word。这样当数据更新时,分析报告能自动刷新,避免每次手动复制粘贴。这一点对需要周期性出报表的科室或项目组非常省力。

ods output ChiSq=chisq_result; proc freq data=mydata; tables treat*outcome / chisq; weight cnt; run; ods output close;

保存下来的chisq_result数据集包含所有卡方检验统计量,后续可直接用proc print查看,或合并到总报表数据集中。

这些技巧单独看都很小,串起来使用后,能明显提升分析效率和分析质量。最终回归到那个最根本的问题——卡方检验不是跑完程序拿到P值就算完事,真正有价值的是你读懂结果、判断适用条件、并用规范的语言呈现结论的能力。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询