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

R语言不使用chisq.test()复现卡方检验期望频数表的代码问题求解

R手动实现卡方检验:期望频数计算问题排查

示例数据集构造

首先构造性别与学习模式的列联表数据:

dat <- rbind(c(3, 27),
             c(33, 9))
rownames(dat) <- c("Studying", "Not-studying")
colnames(dat) <- c("Men", "Women")

## 生成的数据集如下:
##               Men Women
## Studying       3    27
## Not-studying  33     9

原代码问题说明

你写的代码存在3个核心问题:

  • 赋值逻辑错误:R中for循环没有返回值,直接将for循环赋值给expected只会得到NULL,需要先提前初始化和dat维度一致的空矩阵
  • 计算逻辑错误:期望频数公式是行合计 × 列合计 / 总合计,你写成了对sum(行元素 × 列合计)求和,逻辑完全错位
  • 语法错误:表达式括号不匹配,缺少右闭合括号

修正后的for循环实现

# 第一步:初始化同维度的期望频数矩阵
expected <- matrix(nrow = nrow(dat), ncol = ncol(dat), 
                   dimnames = dimnames(dat))
# 第二步:计算总样本量
total <- sum(dat)
# 第三步:循环计算每个单元格的期望频数
for(i in 1:nrow(dat)) {
  row_sum <- sum(dat[i, ]) # 提前算好当前行合计,避免重复计算
  for(j in 1:ncol(dat)) {
    col_sum <- sum(dat[, j]) # 提前算好当前列合计
    expected[i,j] <- row_sum * col_sum / total
  }
}

运行后得到的expected结果如下:

Men Women
Studying       15    15
Not-studying   21    21

和你给出的示例计算结果一致。

可选:更高效的向量化实现

不需要写for循环,直接用R的向量化运算可以一行代码得到结果:

expected <- rowSums(dat) %o% colSums(dat) / sum(dat)

其中%o%是外积运算符,直接将行合计向量和列合计向量两两相乘得到矩阵,再除以总样本量即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 01:48:03