如何在tidyverse中使用group_by批量执行R卡方检验
报错原因
dplyr的group_by()生成的分组列会被默认保留,哪怕你用select()只指定了两个数值列,返回的结果里还是会带brand这个字符类型的分组列。chisq.test()接收输入时会把所有列都纳入计算,遇到字符类型的brand列就会抛出类型错误。
另外chisq.test()本身不支持对分组数据集直接批量运算,就算没有字符列,它也只会把整张表作为一个输入计算一次,不会按分组分别计算。
正确实现方案
方法1:nest + map 组合(推荐)
通过嵌套数据+映射函数的方式批量处理每个品牌的子数据集,代码如下:
library(tidyverse) db %>% # 按品牌拆分生成独立子数据集 nest(data = -brand) %>% mutate( # 对每个子数据集运行卡方检验 chisq_res = map(data, ~ chisq.test(.x[, c("positive_opinion", "negative_opinion")])), # 提取检验p值 p_value = map_dbl(chisq_res, ~ .x$p.value) ) %>% # 输出结果仅保留品牌和对应p值,可根据需要调整 select(brand, p_value)
方法2:group_modify 分组运算
如果你更习惯分组语法,可以用group_modify直接对每个分组返回计算结果:
library(tidyverse) db %>% group_by(brand) %>% group_modify(~ tibble(p_value = chisq.test(.x[, c("positive_opinion", "negative_opinion")])$p.value))
两种方法返回的结果一致,如果你需要查看完整的卡方检验输出(如卡方值、自由度等),保留检验结果列即可。如果你的数据存在期望频数小于5的情况,可以在chisq.test中添加correct = TRUE参数启用连续性修正,也可以替换为fisher.test运行 Fisher 精确检验。
内容的提问来源于stack exchange,提问作者Yunpeng Ding
相关产品推荐
相关产品推荐

