1.5.3 卡方检验与确切概率检验

更新日期

2026年11月9日

遇到下面的问题,先数清每组有多少人出现结局:

本节聚焦最常见的两组、两类结局:从人数构成判断两项分类变量是否有关联。学完后,你应能根据期望频数选择检验,并结合各组比例、效应量和不确定性解读结果。

1.5.3.1 人数表里,什么算“偏离独立”?

列联表把分组和结局交叉列出,每个独立观察单位只能进入一格。若两者在总体中独立,阳性比例不随组别而变。把全样本阳性比例乘以某组人数,就是独立假设下该组的阳性期望频数:

Eij=第 i 行合计×第 j 列合计总人数。 E_{ij}=\frac{\text{第 }i\text{ 行合计}\times\text{第 }j\text{ 列合计}}{\text{总人数}}。

观察频数 OijO_{ij} 来自计数,期望频数 EijE_{ij} 则由行列合计计算,可以有小数。Pearson 卡方统计量把各格的 (Oij−Eij)2/Eij(O_{ij}-E_{ij})^2/E_{ij} 相加;偏离越大,统计量通常越大。P 值由卡方分布近似得到,稀疏表的近似可能不可靠。

Fisher 确切概率检验在固定行列合计的条件下计算 P 值,无须依赖卡方近似。对本节的 2×22\times2 表,任一格期望频数小于 5 时优先考虑 Fisher,是常见的实用规则;这条线不是绝对界限,也不应看完两种 P 值再挑较小的一个。

警告同一对象前后两次测量要保留配对关系

普通 Pearson 和 Fisher 独立性检验都要求观察单位之间独立。若比较同一批患者的前后两次二分类结果,应考虑配对方法(如 McNemar 检验);不能把同一人的两次记录当成两个人。

1.5.3.2 从两张真实表选择检验

用 MASS::birthwt 的 189 条母婴记录。低出生体重 low(1=小于 2500 克)是结局,分别与孕期吸烟 smoke、高血压病史 ht 交叉;所用三列无缺失,暴露列均用 0=否、1=是。

同一份示例同时展示两种方法。每张表先看实测人数和期望人数,再运行相应检验。

if (!requireNamespace("MASS", quietly = TRUE)) {
  utils::install.packages("MASS", repos = "https://cloud.r-project.org")
}
utils::data("birthwt", package = "MASS")

# 用固定顺序构造 2×2 人数表:第 2 行为有暴露,第 2 列为低出生体重。
selected <- birthwt[stats::complete.cases(birthwt[c("smoke", "ht", "low")]), ]
outcome <- factor(selected$low, levels = c(0, 1), labels = c("no", "yes"))
smoke_table <- table(
  smoke = factor(selected$smoke, levels = c(0, 1), labels = c("no", "yes")),
  low = outcome
)
ht_table <- table(
  ht = factor(selected$ht, levels = c(0, 1), labels = c("no", "yes")),
  low = outcome
)

# 先核对独立假设下的期望人数,再决定用哪种 P 值。
smoke_expected <- outer(rowSums(smoke_table), colSums(smoke_table)) / sum(smoke_table)
ht_expected <- outer(rowSums(ht_table), colSums(ht_table)) / sum(ht_table)
print(smoke_table)
print(smoke_expected)
# FALSE 使用未做连续性校正的 Pearson 统计量;TRUE 会改变统计量和 P 值。
print(stats::chisq.test(smoke_table, correct = FALSE))

print(ht_table)
print(ht_expected)
# two.sided 允许任一方向的关联;conf.level 只控制 OR 区间。
print(stats::fisher.test(ht_table, alternative = "two.sided", conf.level = 0.95))
     low
smoke no yes
  no  86  29
  yes 44  30
          no      yes
no  79.10053 35.89947
yes 50.89947 23.10053

    Pearson's Chi-squared test

data:  smoke_table
X-squared = 4.9237, df = 1, p-value = 0.02649

     low
ht     no yes
  no  125  52
  yes   5   7
            no       yes
no  121.746032 55.253968
yes   8.253968  3.746032

    Fisher's Exact Test for Count Data

data:  ht_table
p-value = 0.05161
alternative hypothesis: true odds ratio is not equal to 1
95 percent confidence interval:
  0.8679484 13.9894703
sample estimates:
odds ratio
  3.340866
R 输出 统计含义 本例怎样读
第一张人数表和随后的期望频数 实际计数、独立假设下的计数 吸烟组实测低出生体重 30 例;期望为 74×59/189=23.1074\times59/189=23.10 例,各格期望均超过 5
X-squared、df、p-value Pearson 统计量、自由度、近似 P 值 吸烟表的统计量为 4.9237,自由度 1,P=0.02649
第二张表的期望频数、p-value 是否稀疏、Fisher 双侧确切 P 值 高血压组低出生体重的期望频数为 3.75,故用 Fisher;P=0.05161
odds ratio、95 percent confidence interval 第 2 行相对第 1 行的阳性优势比(OR)及区间 有高血压病史相对无病史,条件估计 OR 为 3.34,区间约 0.87~13.99

1.5.3.3 把比例和不确定性写进报告

吸烟组低出生体重比例为 30/74=40.5%30/74=40.5\%,不吸烟组为 29/115=25.2%29/115=25.2\%,相差约 15.3 个百分点。Pearson 检验支持两项分类变量有关联,但这是未调整的观察性比较。高血压表中,OR 的区间较宽且包含 1;该结果不足以精确判断关联大小,不能把 P=0.05161 写成“两组没有差异”。Fisher 输出的 OR 是给定边际合计后的条件估计,不必等于四格计数的交叉乘积比。

若结局是以克为单位的原始出生体重,问题应转为比较连续结局的均值。若要分析调整其他变量后的二分类关联,见2.3.1 Logistic回归。迁移 2×22\times2 表时,使用同编号代码碎片明确分组顺序与阳性类别。

实现及参数见 Pearson 卡方检验和 Fisher 确切概率检验。