如何用apply/sapply批量执行卡方检验?代码报错排查
卡方检验批量执行失败的问题与解决方法
问题背景
目标是高效完成多组变量的卡方检验,现有数据集如下:
data <- data.frame( sex = factor(c("M", "F", "M")), ageid = factor(c(8, 6, 7)), married = factor(c(2, 1, 2)), cagv_typ = factor(c("non-primary", "primary", "non-primary")), sq5_1 = factor(c(1, 1, 1)), sq5_2 = factor(c(0, 1, 0)) )
其中sex和married是分组变量,其余为结果变量(实际场景有10+结果变量、5个分组变量)。编写的卡方检验函数如下:
library(rstatix) chis_test <- function(data, var1, var2){ result <- data %>% tabyl({{var1}}, {{var2}}) %>% select(-1) %>% chisq_test() return(result) }
通过expand_grid生成变量组合:
combo <- expand_grid(x = names(data)[c(1, 3)], y = names(data)[-c(1, 3)])
单个变量组合(如sex与cagv_typ)测试可得到预期结果,但使用apply批量执行时失败:
apply(combo, 1, function(x) chis_test(data, x[1], x[2]))
问题原因
函数中使用的{{var1}}是tidy eval(整洁评估)语法,它期望接收的是裸变量名(例如直接传入sex而非字符串"sex")。但apply遍历combo时,传入的是字符串格式的变量名,两者不兼容,导致函数无法正确识别数据集中的变量。
解决方法
方法一:修改函数适配字符串输入
使用.data代词直接通过字符串访问数据集中的变量,修改后的函数如下:
chis_test <- function(data, var1, var2){ result <- data %>% tabyl(.data[[var1]], .data[[var2]]) %>% # 用.data代词处理字符串变量名 select(-1) %>% chisq_test() return(result) }
修改后原apply代码即可正常运行:
apply(combo, 1, function(x) chis_test(data, x[1], x[2]))
方法二:用purrr::pmap配合符号转换适配原函数
如果不想修改原函数,可以使用purrr包的pmap函数,结合sym()将字符串转为符号,再用!!解引用,适配原函数的tidy eval语法:
library(purrr) combo %>% pmap(function(x, y) chis_test(data, !!sym(x), !!sym(y)))
额外说明
当前数据集仅3行样本,实际执行卡方检验时会触发期望频数过小的警告,这是数据样本量的问题,而非代码逻辑错误,实际使用大样本数据集时可避免该问题。
内容的提问来源于stack exchange,提问作者N Kevin
相关产品推荐
相关产品推荐

