跳至主要内容

R 中的卡方检验:完整指南

了解如何在 R 中创建列联表并使用 chisq.test() 函数执行卡方检验。通过实际应用示例,自信解读结果。
· 8分钟 阅读

使用 AI 探索

理解如何分析和解读数据是数据从业者一项极其宝贵的技能。出于不同目的,我们会使用许多不同的统计检验。卡方检验是一种常见的检验方法,适用于特定情境:当您需要判断分类变量之间是否存在关联时。研究人员经常需要解决这一问题,因此卡方检验是应用最广泛的统计检验之一。

本教程将介绍卡方检验、其不同类型,以及如何使用 R 语言执行相关步骤。阅读完本指南后,您将具备将卡方检验自信地应用于自身数据并解读结果的知识与技能。

如果您是 R 语言新手,建议先查看适合初学者的Data Analyst with R 职业路径,通过动手的数据分析示例熟悉这门语言。

主要步骤:如何在 R 中执行卡方检验

在 R 中执行卡方检验,按以下步骤进行:

  • 步骤 1:将数据整理为列联表格式。

  • 步骤 2:使用 chisq.test() 函数应用卡方检验。

下面用示例数据快速演示:

# Step 1: Creating a contingency table
data <- matrix(c(10, 20, 30, 40), nrow = 2)

# Step 2: Applying the chi-square test function
result <- chisq.test(data)

# Viewing the result
print(result)

该代码片段创建了一个 2x2 的列联表并执行卡方检验。结果将显示检验统计量、自由度以及 p 值。

什么是卡方检验?

卡方检验是一种用于判断分类变量之间是否存在显著关联的统计检验。 它将不同类别中观测到的频数与在变量彼此独立时所期望的频数进行比较。

卡方检验的类型

卡方检验主要有两种类型:

  1. 独立性卡方检验:用于判断变量是否相互独立,或它们之间是否存在关系。例如,您可能想了解性别是否会影响投票偏好。
  2. 拟合优度卡方检验:用于检验样本数据是否符合某个总体分布。例如,您可以通过将每个点数的观测频数与“公平骰子”情况下的期望频数进行比较,来判断一个骰子是否公平。

卡方检验的假设条件

为确保卡方检验的有效性,需要满足以下假设条件:

  • 数据必须以频数或计数的形式出现。
  • 各类别应当互斥。
  • 对于独立性卡方检验,每个单元格中的期望频数应至少为 5。
  • 对于拟合优度检验,期望频数至少为 1,且期望频数小于 5 的单元格不应超过 20%。

卡方检验的实际应用

卡方检验在学术界与工业界应用广泛,尤其用于检验分类变量独立性的假设。 一些常见的实际应用包括:

  • 市场研究: 例如分析不同年龄段与收入水平的消费者对某产品偏好是否不同,或评估不同营销活动在各人口细分中的效果是否相同。
  • 医学研究: 常见用例如研究生活方式因素(如吸烟、运动)与疾病发生(如肺癌、心脏病)之间的关系,或评估临床试验中不同治疗组的康复率是否存在差异。
  • 质量控制: 常用于检验产品缺陷是否与制造工艺或特定生产线无关,以及比较不同供应商产品的质量,以判断不良率是否存在显著差异。
  • 教育: 常用于比较不同学校或教学方法的通过率是否存在显著差异,并评估引入新课程是否能提升学生在各学科的表现。

需要指出的是,这些只是学术界与工业界众多应用中的一部分,还可以扩展至其他领域与场景。

在 R 中执行卡方检验:一个示例

学习卡方检验的最佳方式是通过将检验应用到数据集的示例。我们将使用可在 Kaggle 下载的尼日利亚贫血水平数据集。该数据集来自 2018 年尼日利亚人口与健康调查(NDHS),探讨母亲年龄与社会经济因素对 0–59 个月儿童贫血水平的影响,覆盖尼日利亚 36 个州和联邦首都特区。

让我们在 R 中加载该数据集,并查看一个样本以更好地理解数据。要在 R 中读取 CSV 文件,您需要安装名为 readr 的软件包。

# Load the necessary libraries
install.packages('readr')
library(readr)

# Load the dataset from the CSV file
dataset <- read_csv("children anemia.csv")

# Display the first few rows of the dataset
head(dataset)

# Rename a column
colnames(dataset)[colnames(dataset) == "Anemia level...8"] <- "Anemia level"

# Display the column names
colnames(dataset)

除了数据集的一个样本外,我们还将在下方看到该数据集的列:

R 中数据集的列数据集中的列。图片由作者提供。

在这些列中,我们将选择如下两列来评估它们之间是否存在关系。

  • 受教育最高程度: 该列将母亲的教育程度分为“无教育”“小学”“中学”和“高等”水平。

  • 贫血水平: 该列表示儿童的贫血程度,如“中度”“重度”或“无贫血”。

步骤 1:创建列联表

列联表(也称交叉列联或交叉表)展示两个或多个分类变量在各自类别中的分布情况。 

我们将从数据集中选取上述两列,并将其转换为所需的列联表格式。为此我们将使用常用的软件包 dplyr。

# Install and load the package
install.packages('dplyr')

library(dplyr)

# Select the columns of interest
selected_data <- dataset %>% select(Highest educational level, Anemia level)

# Create a contingency table for Highest educational level and Anemia level
contingency_table <- table(selected_data$Highest educational level, selected_data$Anemia level)

# View the contingency table
print(contingency_table)

生成的列联表如下所示:

R 中的列联表

列联表。图片由作者提供。

步骤 2:应用卡方检验函数

既然我们已得到所需格式的列联表,就可以直接应用 chisq.test() 函数。无需加载其他库即可调用该函数,因为它在 R 的基础包中可用。

# Perform chi-square test
chi_square_test <- chisq.test(contingency_table)

# View the results
print(chi_square_test)

输出结果类似如下:

R 中 Pearson 卡方检验结果

Pearson 卡方检验结果。图片由作者提供。

就是这样!我们仅用两个简单步骤就完成了卡方检验。接下来,如何解读结果?

提出假设并解读结果

假设能够清晰地表述我们要检验的内容,并为结果解读建立框架。通俗来说,我们提出的假设给出了一个明确的问题,而卡方检验帮助我们判断观测到的数据是支持还是反驳这一主张。

卡方检验的假设

进行卡方检验时,通常会设立两个假设:

  • 原假设(H0): 原假设认为被检验的两个分类变量之间不存在关联。它假定数据中任何观察到的差异都源自随机性,而非真实关系。
  • 备择假设(H1): 备择假设认为两个变量之间存在显著关联。它表明观测到的差异并非偶然,变量之间确有关系。

将原假设与备择假设应用到我们所检验的变量上,可表述为:

  • 原假设(H0): 母亲受教育最高程度与儿童贫血水平之间不存在关联。这意味着我们假定儿童是否贫血与母亲教育程度无关。
  • 备择假设(H1): 母亲受教育最高程度与儿童贫血水平之间存在关联。这意味着母亲的教育程度会影响儿童发生贫血的可能性。

解读卡方检验的输出

有了假设之后,我们就可以在假设的语境下解读结果:

  • 卡方统计量(X-squared): 卡方检验统计量为 142.86。该值衡量列联表中观测频数与在变量独立时的期望频数之间的偏离程度。

  • 自由度(df): 本次检验的自由度为 9。其计算方式为(行数 - 1)×(列数 - 1)。

  • P 值: p 值小于 2.2e-16,极其微小。该 p 值表示在原假设为真时,观测到像 142.86 这样极端或更极端的卡方统计量的概率。

由于 p 值远小于常见的显著性水平(如 0.05、0.01,乃至 0.001),我们拒绝原假设。这提供了强有力的证据,表明母亲教育程度与儿童贫血状况之间存在显著关联。 换言之,卡方检验结果表明,儿童发生贫血的可能性与母亲的教育水平显著相关。

进一步分析:从 chisq.test() 获取数值

除了进行假设检验外,我们还可以从 chisq.test() 函数返回的对象中提取部分数值:

观测频数

这些数值表示在各母亲教育水平下,不同贫血程度儿童的实际计数。 可以通过如下代码获取观测频数:

# Observed counts
observed_counts <- chi_square_test$observed

print(observed_counts)

输出如下:

观测频数。

观测频数。图片由作者提供。

期望频数

这些频数是在假定母亲教育水平与儿童贫血状况之间不存在关联的前提下计算得到的。 可以通过如下代码获取期望频数:

# Expected counts
expected_counts <- chi_square_test$expected
print(round(expected_counts, 2))

输出如下:

期望频数。

期望频数。图片由作者提供。

Pearson 残差

这些残差有助于识别观测与期望频数偏离最大的单元格,从而指出哪些单元格对卡方统计量的贡献最大。 可以通过如下代码获取 Pearson 残差:

# Pearson residuals
pearson_residuals <- chi_square_test$residuals
print(round(pearson_residuals, 2))

输出如下:

残差输出。

残差输出。图片由作者提供。

我们来理解这些残差数值的含义:

  • 正残差: 正残差表示观测频数高于期望频数。例如,“高等”教育组中“无贫血”的残差为 5.96,意味着在高等教育母亲中,未贫血儿童数量显著高于期望。

  • 负残差: 负残差表示观测频数低于期望频数。例如,“高等”教育组中“中度”贫血的残差为 -5.74,表明在高等教育母亲中,中度贫血儿童数量显著低于期望。

  • 较大残差: 较大的正或负残差表示与期望值有显著偏离,这些单元格对卡方统计量贡献最大。例如,“高等”教育组中“无贫血”的较大正残差,以及同组“中度”贫血的较大负残差,显示基于母亲教育程度,儿童贫血水平存在显著偏离。

  • 较小残差: 残差接近 0 表示观测频数与期望频数接近,偏离较弱。例如,“小学”教育组在各贫血水平上的残差相对较小,说明该组的观测与期望频数更为接近。

贡献图

基于上述提取的数值,可用以下代码计算每个单元格对卡方统计量的贡献,并将其转换为百分比:

# Calculate contribution to chi-square statistic
contributions <- (observed_counts - expected_counts)^2 / expected_counts

# Calculate percentage contributions
total_chi_square <- chi_square_test$statistic
percentage_contributions <- 100 * contributions / total_chi_square

# Print percentage contributions
print("Percentage Contributions:")
print(round(percentage_contributions, 2))

我们将看到的输出如下:

百分比贡献。百分比贡献。图片由作者提供。

 

可以将计算得到的贡献可视化为热力图。我们将安装并加载 pheatmap 包来实现。

# Install and load heatmap package
install.packages("pheatmap")
library(heatmap)

# Create heatmap for percentage contributions
pheatmap(percentage_contributions,
        display_numbers = TRUE,
        cluster_rows = FALSE,
        cluster_cols = FALSE,
        main = "Percentage Contribution to Chi-Square Statistic")

得到的输出如下:

R 中卡方统计量百分比贡献热力图卡方统计量百分比贡献热力图。图片由作者提供。

如上所示的贡献热力图在您选择做进一步分析时非常有用:在基于卡方检验结果确认存在关联之后,它可以帮助您理解具体存在何种类型的关联。

结论

本教程向您介绍了卡方检验、其不同类型及其背后的假设。我们还通过一个示例学习了如何在 R 中执行检验、解读结果,并进行可视化。

卡方检验在假设检验及更广泛的统计分析中非常常见。建议选修以下课程,以巩固您使用 R 进行数据分析与统计的理解:

Arunn Thevapalan

作者

Arunn Thevapalan

作为一名高级数据科学家,我设计、开发并部署大规模机器学习解决方案,帮助企业做出更明智的数据驱动决策。作为数据科学写作者,我分享所学心得、职业建议以及深入的实践型教程。

常见问题解答

卡方检验的目的是什么?

卡方检验用于判断两个分类变量之间是否存在显著关联。

小样本可以使用卡方检验吗?

通常不建议,因为该检验要求每个单元格的期望频数至少为 5,才能得到可靠结果。

卡方检验中的 Pearson 残差表示什么?

Pearson 残差显示列联表中每个单元格对总体卡方统计量的贡献程度。正值表示观测频数高于期望值,负值表示低于期望值。

如何在 R 中为卡方检验创建列联表?

使用 table() 或 xtabs() 函数,可由分类变量创建列联表。

如果我的数据不满足卡方检验的假设条件,该怎么办?

可考虑使用 Fisher 精确检验,它更适用于样本量较小或期望频数较低的情况。

主题