You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言卡方检验后Bonferroni校正报错:'list'无法转为double的解决求助

问题解决:Bonferroni校正报错的原因与修复方法

错误核心原因

p.adjust()函数的第一个参数要求传入p值组成的向量,但你直接传入了整个列联表(data.frame/矩阵类型),这就导致了'list' object cannot be coerced to type 'double'的报错——函数无法把列联表转换成它需要的数值型p值向量。

分场景修复方案

场景1:仅对整体卡方检验的p值校正(注:单检验无需校正,仅作演示)

如果你只是想对2×3列联表的整体卡方检验p值做校正(实际上单一次检验不需要校正,Bonferroni是为了修正多次检验的Ⅰ类错误),需要先提取卡方检验结果中的p值,再传入p.adjust():

# 先保存卡方检验的结果对象
chi_result <- chisq.test(Smoking, simulate.p.value = TRUE)
# 提取卡方检验的p值
single_p <- chi_result$p.value
# 执行Bonferroni校正(仅1个p值时,校正后结果与原p值一致)
adjusted_p <- p.adjust(single_p, method = "bonferroni")

场景2:对两两分组的卡方检验p值校正(更符合Bonferroni的适用场景)

如果你是想对不同肺病程度组之间的吸烟史差异做两两比较,此时会产生多个独立检验的p值,这才是Bonferroni校正的典型使用场景:

# 拆分2×3列联表为3个2×2的两两比较表
# 轻度(Mild) vs 中度(Mode)
tab_mild_mode <- Smoking[, c("Mild", "Mode")]
chi_mild_mode <- chisq.test(tab_mild_mode, simulate.p.value = TRUE)
# 轻度(Mild) vs 重度(Seve)
tab_mild_seve <- Smoking[, c("Mild", "Seve")]
chi_mild_seve <- chisq.test(tab_mild_seve, simulate.p.value = TRUE)
# 中度(Mode) vs 重度(Seve)
tab_mode_seve <- Smoking[, c("Mode", "Seve")]
chi_mode_seve <- chisq.test(tab_mode_seve, simulate.p.value = TRUE)

# 收集所有两两检验的p值
p_values <- c(chi_mild_mode$p.value, chi_mild_seve$p.value, chi_mode_seve$p.value)
# 执行Bonferroni校正
adjusted_p_values <- p.adjust(p_values, method = "bonferroni")

# 给校正后的p值命名,方便查看
names(adjusted_p_values) <- c("Mild vs Mode", "Mild vs Seve", "Mode vs Seve")
adjusted_p_values

关于你之前错误尝试的说明

  • str(x):这个函数是查看对象结构的,无法帮你转换为p值向量;
  • p.adjust(as.matrix(x), method = x):这里有两个错误:一是method参数需要传入字符串"bonferroni"而非对象x;二是as.matrix(Smoking)仍然是频数矩阵,不是p值向量,所以无法被p.adjust()识别。

另外,你使用simulate.p.value = TRUE来解决预期频数小于5的问题是正确的,模拟p值能有效规避卡方近似误差的问题。

内容的提问来源于stack exchange,提问作者dodobird99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 17:10:43