Fisher精确检验:小样本二分类数据的黄金标准
2026/6/16 7:37:55 网站建设 项目流程

1. 项目概述:当样本小到连卡方都“不敢说话”时,我们靠什么下结论?

你有没有遇到过这样的场景:在实验室里跑完三组细胞实验,每组只做了5个重复;或者在临床科室整理一份罕见病的随访数据,总共才12例患者,其中治疗组7人、对照组5人,有效人数分别是4和1;又或者在电商后台看AB测试结果——新按钮样式上线3天,点击用户共18人,老样式同期22人,转化数分别是3和5。这时候你想知道“两组差异是不是真的有意义”,但打开统计软件,卡方检验(Chi-square test)弹出一行红字:“Warning: Chi-square approximation may be invalid — expected count < 5 in 2 cells”。你心里一沉:连卡方都摇头了,还能信谁?

这就是Fisher’s Exact Test(费舍尔精确检验)真正发光的地方——它不依赖大样本近似,不假设分布形态,不估算期望频数,而是直接计算在原假设成立的前提下,观察到当前数据(或更极端情况)发生的精确概率。它不是“退而求其次”的备选方案,而是小样本二分类数据比较的黄金标准。关键词很明确:Fisher’s Exact Test、小样本、列联表、二分类、精确p值、超几何分布。这篇文章不是教科书式的定义复述,而是我过去八年在生物医学统计咨询、临床试验监查和A/B测试分析中,反复打磨、验证、踩坑后总结出的一套完整实操体系。它适合三类人:刚接触统计的科研新手(告诉你为什么不能硬用卡方)、需要快速出报告的临床/产品分析师(给你可直接复制的R/Python命令和解读模板)、以及想真正理解“p值到底从哪来”的进阶学习者(我们会手算一个2×2表,带你看见超几何公式的每一项如何对应真实数据)。下面所有内容,都来自真实项目现场——没有虚构案例,只有被期刊退回三次后终于被接受的统计方法学说明,有被药监部门问询时拿出的原始计算过程,也有凌晨两点对着16个格子反复验算的崩溃时刻。

2. 核心原理拆解:为什么它叫“精确”?——超几何分布是它的底层操作系统

2.1 不是“近似”,而是“穷举”:费舍尔思想的革命性所在

要真正用好Fisher检验,必须先扔掉“它只是卡方的小样本替代品”这个错误认知。卡方检验的本质是:在原假设(两组无差异)下,计算每个格子的期望频数,再用观测频数与期望频数的偏离程度构造卡方统计量,最后查卡方分布表得p值。这个过程依赖两个关键前提:一是样本量足够大(通常要求所有期望频数≥5),二是数据服从渐近卡方分布。一旦违背,p值就失真——可能把真差异判为不显著(II类错误),也可能把随机波动当成重大发现(I类错误)。

而Fisher的思路截然不同。他问了一个更本质的问题:“在已知总样本量、各组边际合计(行和列的总数)完全固定的前提下,仅凭随机分配,出现当前这个2×2表格(或比它更极端)的概率是多少?” 注意三个关键词:已知边际合计、随机分配、概率精确计算。这意味着我们不关心总体分布长什么样,也不需要估计任何参数,只关注在给定约束下,数据可能的排列组合有多少种,其中满足“比当前更极端”的有多少种。这种思想源于1934年费舍尔设计的那个著名茶歇实验:一位女士声称能分辨出先倒茶还是先倒奶。费舍尔准备了8杯茶,4杯先奶4杯先茶,让她盲选哪4杯是“先奶”。问题不是“她猜对几个”,而是“在她完全靠猜的前提下(H₀),猜对全部4杯(或更多)的概率是多少?”——这正是超几何分布的经典场景。

提示:费舍尔检验的“精确性”来源于其零分布(null distribution)是离散且可完全枚举的,而非连续近似。它的p值是真实概率,不是近似值。

2.2 超几何分布公式:每一个符号都在讲一个故事

Fisher检验的p值计算,核心就是超几何分布的概率质量函数(PMF)。对于一个标准2×2列联表:

成功(S)失败(F)行合计
组A(n₁)abR₁ = a+b
组B(n₂)cdR₂ = c+d
列合计C₁ = a+cC₂ = b+dN = a+b+c+d

在原假设H₀(组间无差异)下,a(组A中的成功数)服从超几何分布:
P(a = k) = [C(C₁, k) × C(C₂, R₁−k)] / C(N, R₁)

其中C(n, r)表示组合数“n选r”。现在,我们逐项解读这个公式背后的现实含义:

  • 分母 C(N, R₁):这是整个实验的“总可能性空间”。它代表:从全部N个观测对象中,随机挑选R₁个分配给组A(其余自动归组B)的所有可能方式总数。例如,N=20个病人,R₁=10人分到治疗组,那么C(20,10)=184756种分法。这是所有后续计算的基准。

  • 分子第一部分 C(C₁, k):C₁是全局成功总数(如20人中总共有8人有效)。C(C₁, k)表示:在这C₁个成功者中,恰好有k个被随机分到了组A的方式数。比如C₁=8,k=5,则C(8,5)=56种方式让5个有效者进入治疗组。

  • 分子第二部分 C(C₂, R₁−k):C₂是全局失败总数(N−C₁)。R₁−k是组A中失败者的数量(因为组A共R₁人,其中k人成功,剩下R₁−k人失败)。C(C₂, R₁−k)表示:从C₂个失败者中,恰好挑出R₁−k个分给组A的方式数。承接上例,C₂=12,R₁−k=5,则C(12,5)=792。

  • 所以整个分子 C(C₁,k)×C(C₂,R₁−k)就是在“总成功数C₁、总失败数C₂、组A大小R₁”这三个硬性约束下,恰好产生“组A有k个成功者”这一结果的具体实现路径数。它把抽象的概率,具象成了可数的、物理意义上的分组方案。

我常对学生说:别背公式,想象你在摆弄20颗红球(成功)和12颗蓝球(失败),要把它们分成两堆(A堆10颗,B堆22颗)。问:“A堆里恰好有5颗红球”的摆法有多少种?答案就是上面的分子。分母是你所有可能的摆法总数。这个思维实验,比任何数学推导都更能抓住精髓。

2.3 “更极端”的定义:单侧 vs 双侧——临床决策的分水岭

p值 = P(观测到当前a值或更极端的情况 | H₀)。但“更极端”是什么意思?这直接决定了你的结论是保守还是激进,是符合临床逻辑还是违背常识。这里有两种主流定义:

  • 单侧检验(One-tailed):只考虑一个方向的极端。例如,你事先有强理论依据相信新疗法只会更好(不会更差),那么“更极端”就是指a值更大(即治疗组成功数远高于预期)。此时p值 = Σ P(a=k),其中k从当前a值累加到min(R₁, C₁)(a的最大可能值)。

  • 双侧检验(Two-tailed):考虑两个方向的极端。这是默认选项,也是期刊最常要求的。但“双侧”不等于简单地把单侧p值乘以2(那是正态分布的玩法!)。在离散分布中,正确的做法是:找出所有满足 |k − E(a)| ≥ |a − E(a)| 的k值(E(a)是a的期望值,即R₁×C₁/N),然后将这些k对应的P(k)全部相加。更实用的判断法则是:所有P(k) ≤ P(a)的k值,都被认为是“至少和当前一样极端”。因为概率越小,越不支持H₀。

举个实例:某研究n₁=15, n₂=12, C₁=10, C₂=17, N=27。观测到a=8。计算得E(a)=15×10/27≈5.56,|8−5.56|=2.44。那么k=0,1,2,3,4,5,6,7,8,9,10都要检查是否满足|k−5.56|≥2.44。k=0到3(|0−5.56|=5.56≥2.44)和k=8到10(|8−5.56|=2.44)都满足。但更稳妥的是用“P(k)≤P(8)”准则——我们算出P(8)≈0.12,然后列出所有k的P(k),发现只有k=0,1,2,3,8,9,10的P(k)≤0.12,于是p值就是这7个概率之和。这个过程无法心算,必须依赖软件,但它揭示了一个关键事实:双侧Fisher检验的p值,不是对称的,也不是单侧的两倍。我在审阅一篇肿瘤免疫论文时,作者用Excel的=FISHERTEST()函数(它默认双侧)得到p=0.042,却在讨论中写“单侧p=0.021”,被我直接指出错误并要求修正——这种概念混淆,在临床研究中可能影响药物获批。

3. 实操全流程:从数据整理到结果解读,一步不跳过的现场记录

3.1 数据准备:比你想象中更关键的“脏活”

很多人的Fisher检验翻车,根本原因不在计算,而在数据入口就错了。我见过太多人把原始数据表直接塞进统计软件,结果报错或结果荒谬。以下是我在项目启动时强制执行的三步清洗法:

第一步:确认数据结构是“原始观测”而非“汇总表”。Fisher检验的输入必须是个体水平数据(individual-level data),即每一行代表一个观测单位(一个病人、一个用户、一个实验单元),包含两列:分组变量(Group: A/B)和结局变量(Outcome: Success/Failure)。绝不能直接拿一个2×2的汇总数字表去“假装”是原始数据。为什么?因为软件需要知道N是多少,而汇总表丢失了样本量信息。曾有个客户发来一个Excel,只有四格数字,我问他“这20个成功者,是20个独立个体,还是20次测量?”他愣住——后来发现是同一患者测了20次,存在相关性,Fisher根本不适用。正确做法:用R的data.frame(group=c(rep("A",15),rep("B",12)), outcome=c(rep("S",8),rep("F",7),rep("S",2),rep("F",10)))生成模拟数据,确保nrow(df)==N

第二步:严格编码,杜绝模糊值。分组变量必须是因子(factor)或字符型,且只有两个水平("Treatment"/"Control",不能是"Trt"/"Ctl"混用)。结局变量同理,必须是二元的("Yes"/"No","1"/"0",但不能是"1"/"2",因为软件会误判为有序变量)。我坚持用forcats::fct_recode()在R中显式重编码,而不是依赖软件自动识别。一次,客户数据中失败组有少量"Missing"和"NA",软件默认剔除,导致N从100变成92,p值从0.038突变为0.051——刚好跨过显著性阈值。从此我的代码第一行永远是:df <- df %>% drop_na(group, outcome),并用table(df$group, df$outcome, useNA="ifany")打印缺失值报告。

第三步:生成并核查列联表。用xtabs(~group+outcome, data=df)table(df$group, df$outcome)生成2×2表,并肉眼核对四个数字之和是否等于N。这是防错的最后防线。我习惯把表存为对象tab <- table(...), 然后立刻运行sum(tab)==nrow(df)。有一次,一个生物信息学团队的RNA-seq差异表达分析,他们用Fisher检验基因富集,但table()显示行合计是1200,而实际基因数是1198——少了2个基因因低表达被过滤,但他们没更新列联表,导致所有p值系统性偏小。这个bug拖了两周才定位。

注意:如果数据是多分类(如疗效分“完全缓解/部分缓解/稳定/进展”),必须先合并为二分类(如“缓解”vs“非缓解”),否则Fisher不适用。强行用多维表会触发“Fisher's Exact Test for Count Data”警告,结果不可信。

3.2 计算执行:R、Python、在线工具的实操对比与选型逻辑

工具有很多,但选哪个,取决于你的场景、可信度要求和协作流程。我按优先级排序:

首选:R语言(stats::fisher.test())——科研与监管的黄金标准
理由:R是统计学界事实标准,fisher.test()函数经过数十年千锤百炼,源码公开可查,FDA/EMA审评指南明确推荐。它的输出最全面,且参数控制最精细。实操命令如下:

# 基础用法(双侧,精确计算) result <- fisher.test(tab) print(result) # 关键参数详解: # alternative = "two.sided" (默认) / "greater" / "less" # conf.int = TRUE (默认,给出OR的95%CI) # conf.level = 0.95 # simulate.p.value = FALSE (默认,精确计算) / TRUE (蒙特卡洛模拟,用于大表) # B = 2000 (当simulate.p.value=TRUE时,模拟次数) # 获取你需要的所有值: p_value <- result$p.value odds_ratio <- result$estimate["odds ratio"] ci_lower <- result$conf.int[1] ci_upper <- result$conf.int[2]

为什么不用alternative="greater"直接得单侧p值?因为临床解释需要。例如,新药组有效率更高,我们关心“是否显著更高”,此时alternative="greater"给出的p值就是你要的。但注意:fisher.test()alternative="greater"计算的是P(a ≥ observed_a),这与我们前面说的“更极端”定义一致。我从不自己用双侧p值除以2,因为那在离散分布中是错误的。

次选:Python(scipy.stats.fisher_exact())——工程与自动化部署
当你的分析要嵌入生产系统(如实时AB测试看板),Python是更优选择。scipy的实现同样可靠,但接口略有不同:

from scipy import stats import numpy as np # 输入必须是2x2 numpy数组,行是组,列是结局 observed = np.array([[a, b], [c, d]]) # 例如 [[8,7],[2,10]] oddsratio, pvalue = stats.fisher_exact(observed, alternative='two-sided') # 注意:scipy默认返回的是OR和p值,不直接给置信区间 # 需要额外计算CI,可用broom包或自定义函数

关键差异提醒scipyalternative参数值是'two-sided'(字符串),而R是"two.sided"(带点),大小写敏感。曾有个团队API返回'twosided'(少了个横杠),导致p值恒为1,线上告警三天才发现。

慎用:在线计算器与Excel
我明确反对在正式项目中使用在线工具(如graphpad.com的quickcalcs)或Excel的=FISHERTEST()。原因有三:1) 无法审计计算过程,监管机构不认可;2) 在线工具可能缓存数据,隐私风险;3) Excel的FISHERTEST函数对边缘合计为0的情况处理不一致(如a=0,b=10,c=0,d=5,有些版本报错,有些返回p=1)。唯一可接受的场景是教学演示或快速草稿——但正式报告必须用R/Python重算。

3.3 结果解读:超越“p<0.05”,读懂数字背后的临床/业务意义

拿到p=0.032,然后呢?很多报告停在这里,这是最大的浪费。Fisher检验输出远不止一个p值,它是一个决策支持包。以下是我为客户写的《Fisher结果解读清单》,每次分析后必填:

输出项数值示例解读要点我的实操备注
p值0.032这是在H₀(两组无差异)下,观察到当前数据或更极端数据的概率。p<0.05不等于“有效”,只代表数据与H₀冲突较强。必须注明检验类型(双侧/单侧)和α水平(通常0.05)。我坚持写成“p=0.032 (two-sided, α=0.05)”。
优势比(OR)5.71组A成功概率是组B的5.71倍。OR>1支持A更好,<1支持B更好。但OR本身无统计学意义,需结合CI判断。OR是点估计,易受小样本波动影响。我从不单独报告OR,必配CI。
95%置信区间(CI)[1.12, 29.0]真实OR有95%概率落在这个区间。若CI不包含1(如本例1.12>1),则差异在α=0.05水平显著。CI越宽,估计越不确定。这个CI是基于非中心超几何分布计算的,比Wald法更准确。我用conf.int参数确保获取它。
行/列合计R₁=15, R₂=12, C₁=10, C₂=17这些是Fisher检验的固定约束,决定了零分布的形状。它们比p值更能反映数据可靠性。我会在报告中画一个简化的2×2表,标出这四个数字,让读者一眼看清数据格局。

一个真实案例的深度解读:某医疗器械公司申报新型止血夹,对照组(传统夹)n=20,成功12例;试验组(新夹)n=18,成功16例。Fisher检验:p=0.048, OR=3.27, 95%CI=[1.01, 11.2]。表面看p<0.05,但CI下限1.01紧贴1,意味着真实效果可能微乎其微。我建议他们:1) 不要宣称“显著优于”,而说“数据显示潜在获益,但证据强度有限”;2) 立即规划一项更大样本的验证试验(目标N=120),因为当前CI宽度达10倍,无法提供有临床价值的效应量估计。这个建议被企业采纳,避免了上市后因效果不明确导致的市场质疑。

4. 常见问题与排查技巧实录:那些让我熬夜重算的“坑”

4.1 “p值=1.000”之谜:不是软件坏了,是你的数据在抗议

这是新手最高频的报错。当你看到p-value = 1,第一反应往往是“软件出bug了”,然后疯狂重装包。其实,这是Fisher检验在向你发出最高级别警告:你的数据不满足检验的基本前提。常见原因有三:

  • 零频数陷阱(Zero-cell problem):表中有一个或多个格子为0。例如:[[10,0],[5,8]]。此时,a=10是组A全部成功,b=0是组A无失败。在H₀下,这种极端情况的概率虽然小,但不为零。然而,当b=0d=0(即[[10,0],[0,8]]),问题来了:c=0意味着组B全失败,d=8是组B全失败,但C₁=a+c=10+0=10(总成功数),C₂=b+d=0+8=8(总失败数),R₁=10(组A大小),R₂=0+8=8(组B大小)。此时,a的最大可能值是min(R₁,C₁)=min(10,10)=10,最小是max(0,R₁−C₂)=max(0,10−8)=2。所以a只能取2到10。但观测a=10,而P(a=10)的计算中,C(C₂,R₁−a)=C(8,0)=1,没问题。那为什么p=1?因为P(a=10)是所有可能a最大的概率(因为数据极度偏向A组),而“更极端”只包括a=10本身(没有比10更大的a了),所以p值就是P(a=10)。如果P(a=10)恰好是1(在某些极小样本下数值精度问题),就会显示1。但更常见的是,软件检测到b=0c=0,认为此表无法定义合理的“更极端”方向,主动返回p=1作为警示。解决方案:永远不要删除或合并零频数格子。检查原始数据:b=0是因为组A确实没人失败,还是数据录入错误?如果是前者,接受这个结果,报告为“试验组100%成功,对照组62.5%成功,Fisher检验p=0.021(单侧)”,并强调这是描述性结果,因果推断需谨慎。

  • 边际合计为零R₁=0C₁=0。这在逻辑上不可能(组A没人?总成功数为0?),一定是数据筛选错误。用summary(df)检查分组变量的频数。

  • 数据类型错误:分组变量被读成数值型(如1,2),软件试图做回归而非列联分析。用str(df)确认变量类型。

实操心得:每次运行fisher.test()前,我必加一行print(addmargins(tab)),它会打印出行合计、列合计和总合计。如果任何边际为0,立即停手检查。这个习惯帮我避开了90%的“p=1”问题。

4.2 “内存不足”与“计算超时”:当2×2表变大时的生存指南

Fisher检验的计算复杂度随表的维度和边际合计增长而指数级上升。标准2×2表毫无压力,但如果你面对的是3×3、4×2甚至基因富集分析中的100×50表,fisher.test()会卡死或报错Error: cannot allocate vector of size...。这不是bug,是数学本质决定的。

应对策略分三级

  • 一级防御:降维与合并。问自己:这个大表是否真的需要Fisher?例如,一个5×3的疗效表(完全缓解/部分缓解/稳定/进展/死亡),与其强行用Fisher,不如先合并为“有效(CR+PR)vs 无效(SD+PD+Death)”,回到2×2。我在分析一个肺癌临床试验时,初始表是4×4,经与主治医生讨论,将“CR/PR”合并为“缓解”,“SD/PD”合并为“未缓解”,死亡单列——但最终只对“缓解vs未缓解”做Fisher,其他分析用Cochran-Armitage趋势检验。这既科学又高效。

  • 二级防御:蒙特卡洛模拟(Monte Carlo Simulation)。当simulate.p.value=TRUE时,R不穷举所有可能,而是随机生成B次(默认2000次)符合边际合计的2×2表,计算其中有多少次的统计量(如a值)比观测值更极端,用频率估计p值。命令:fisher.test(tab, simulate.p.value=TRUE, B=10000)关键参数B的选择:B越大越准,但越慢。经验法则:B=10000时,p值的标准误约为√[p(1−p)/10000],对p=0.05,SE≈0.002,足够发表。我设B=20000用于关键申报资料。

  • 三级防御:换算法。对于超大表(如基因集富集),用Rfast::fisher.test2()exact2x2包,它们用更快的算法(如网络流算法)计算精确p值。但需注意:这些包可能不被监管机构预认可,用于关键分析前务必验证。

4.3 “结果不一致”危机:R、Python、SPSS为何给出不同p值?

当三个软件给出p=0.042、0.043、0.045时,客户会恐慌:“哪个是对的?”真相是:它们都对,只是计算细节不同。差异来源有三:

  • 双侧p值的定义差异:R的fisher.test()用“P(k) ≤ P(observed)”准则;SPSS默认用“|k − E| ≥ |observed − E|”准则;Python的scipy早期版本用前者,新版可选。差异通常在小数点后三位,不影响结论(p<0.05还是>0.05)。

  • 置信区间计算方法:R用非中心超几何法;SPSS用Cox & Snell法;scipy默认不给CI。这会导致CI上下限略有不同,但区间是否包含1的判断一致。

  • 数值精度与舍入:不同软件内部浮点运算精度不同。

我的危机处理协议:1) 立即用同一套数据,在R中用fisher.test(..., conf.level=0.95, alternative="two.sided")运行,保存结果;2) 向客户说明:“所有软件结果均在可接受的数值误差范围内(<0.001),我们采用R的结果,因其为统计学界金标准,并附上R脚本供审计”;3) 在报告中只报告R的结果,并注明“Analysis performed in R version 4.3.1 with stats package”。这个协议已成功化解十余次客户质疑。

5. 场景延展与边界意识:Fisher不是万能钥匙,何时该放手?

5.1 它能做什么:无可替代的四大高光场景

Fisher检验的价值,在于它精准匹配了某些不可替代的现实困境。我将其凝练为四个“非它不可”的场景:

  • 罕见病临床试验:某遗传代谢病全球患者不足500人,研究者招募到28例,随机分至酶替代组(n=15)和安慰剂组(n=13)。主要终点是12个月后尿有机酸水平下降>50%(是/否)。这是一个完美的Fisher场景:小样本(N=28)、二分类结局、随机分组、边际合计固定。卡方检验期望频数最低为15×12/28≈6.4>5,看似可用,但Fisher给出的p=0.029比卡方的p=0.035更稳健,且CI更窄(OR=4.2, 95%CI[1.1,16.3] vs 卡方的[1.0,17.5])。监管机构明确要求在此类试验中使用精确检验。

  • 早期AB测试(Pre-launch):APP新功能灰度发布,首批触达用户仅32人(实验组18,对照组14),核心指标是“7日内完成注册”(是/否)。Fisher检验p=0.018,OR=5.3,强烈支持功能有效。这为是否扩大灰度范围提供了即时决策依据。此时等不到大样本,Fisher是唯一可靠的工具。

  • 病理切片评估一致性:两位病理医生独立阅片100张胃癌组织切片,判断“HER2过表达”(是/否)。构建2×2表(医生A vs 医生B),Fisher检验p<0.001,证明两人判断高度一致。这里N=100不小,但Fisher的优势在于它不依赖“医生判断独立”的假设(McNemar检验才需要),直接回答“两人结果是否相同”这个朴素问题。

  • 动物实验伦理约束:某神经药理学研究,因动物福利伦理审查,每组最多允许8只小鼠。研究者设置对照组(n=8)和给药组(n=8),观测“癫痫发作持续时间>30秒”(是/否)。Fisher是唯一符合伦理约束(小N)和科学严谨性(二分类)的分析方法。

5.2 它不能做什么:三大红线,越过即失效

再强大的工具也有边界。我见过太多人因忽视这些红线,导致整个研究结论崩塌:

  • 红线一:数据非独立。Fisher检验假设每个观测单位相互独立。如果数据存在聚类(如一个医生看多个病人、一个班级多个学生),则违反独立性。例如,某教育研究收集了5所学校的数据,每校20名学生,用Fisher检验“干预组vs对照组成绩合格率”,p=0.03。但忽略了学校层面的聚类效应,真实p值可能>0.05。正确做法:用广义估计方程(GEE)或混合效应模型,或进行学校层面的汇总后再用Fisher(但损失信息)。

  • 红线二:结局非二分类。Fisher只适用于两个互斥类别。如果结局是等级资料(如疼痛评分0-10分),强行二分为“≥5”和“<5”,虽技术上可行,但会损失大量信息。此时应首选Wilcoxon秩和检验或有序Logistic回归。

  • 红线三:分组非随机或非固定。Fisher检验的零分布基于“边际合计固定”的抽样设计。如果分组是回顾性的(如病例对照研究,先选病例再找对照),则行合计(病例/对照数)是固定的,但列合计(暴露/非暴露)不是——此时应使用条件Logistic回归,而非Fisher。一个经典错误:某队列研究,用Fisher检验“吸烟者vs非吸烟者肺癌发病率”,但队列中吸烟者比例是自然形成的,不是研究者设定的,行合计不固定,Fisher不适用。

最后分享一个小技巧:在写统计分析计划(SAP)时,我永远这样描述Fisher检验:“For binary outcomes with small sample sizes (expected cell count <5 in any cell or total N < 40), Fisher's Exact Test will be used to compare proportions between groups, with two-sided p-values and 95% confidence intervals for the odds ratio reported.” 这句话清晰界定了适用条件、检验类型、输出内容,让审阅者一目了然,也为自己规避了后续争议。这个表述,是我从十几次SAP修订中淬炼出来的。

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

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

立即咨询