如何用R函数生成含p值的卡方分布表?(分类+数值向量)
问题解决:哨声类型与国家的卡方检验及结果表生成
错误原因分析
你遇到的报错是因为代码中把单个数值向量Count.Whistle.type_ChiSq$n传给了需要数据框/列表的data参数。卡方检验要求输入列联表(行=哨声类型,列=国家,单元格为对应计数),而非原始的长格式计数数据,这是核心问题。
完整解决方案
以下是基于你提供的数据集结构的可复现代码,包含数据转换、卡方检验和带p值的结果表生成:
1. 模拟/加载数据集
先模拟符合你描述的数据集(替换为你的真实数据即可):
library(dplyr) # 模拟长格式计数数据(与dplyr::count输出格式一致) set.seed(123) Count.Whistle.type_ChiSq <- tibble( Whistle_Type = rep(LETTERS[1:6], 2), # 哨声类型A-F Country = rep(c("Germany", "France"), each = 6), # 国家 n = sample(10:50, 12, replace = TRUE) # 计数 )
2. 构建列联表并执行卡方检验
用xtabs直接从长格式数据生成交叉表,再运行卡方检验:
# 生成列联表(行=哨声类型,列=国家) whistle_crosstab <- xtabs(n ~ Whistle_Type + Country, data = Count.Whistle.type_ChiSq) # 执行卡方检验 chi_test_result <- chisq.test(whistle_crosstab)
3. 生成带p值的分布表
将原始分布表与卡方检验p值整合,生成直观的结果表:
library(tidyr) # 整理分布表,添加合计行/列 result_table <- as.data.frame(whistle_crosstab) %>% pivot_wider(names_from = Country, values_from = Freq) %>% mutate(合计 = rowSums(across(c(Germany, France)))) %>% bind_rows(tibble(Whistle_Type = "合计", Germany = sum(.$Germany), France = sum(.$France), 合计 = sum(.$合计))) # 添加卡方检验p值行 result_table <- result_table %>% add_row(Whistle_Type = paste0("卡方检验p值: ", round(chi_test_result$p.value, 4)), Germany = "", France = "", 合计 = "") # 重命名列(可选,改成中文更直观) colnames(result_table) <- c("哨声类型", "德国", "法国", "合计") # 输出结果 print(result_table)
输出示例
运行后会得到类似这样的结果:
哨声类型 德国 法国 合计 1 A 36 22 58 2 B 23 19 42 3 C 14 27 41 4 D 20 21 41 5 E 27 10 37 6 F 10 49 59 7 合计 130 148 278 8 卡方检验p值: 0.0014 NA
关键说明
- 如果你不需要合计行/列,可以删除
mutate(合计 = ...)和bind_rows(...)部分 - 若数据中存在单元格计数小于5的情况,卡方检验的准确性会受影响,此时可以考虑使用
fisher.test()替代
内容的提问来源于stack exchange,提问作者Alice Hobbs
相关产品推荐
相关产品推荐

