如何在R中循环多列运行clusWilcox.test函数?
批量运行clusWilcox.test的问题与解决
问题背景
我需要对数据集的多列运行clusrank包中的clusWilcox.test函数:
- 数据集共92列,1-26列为因子型自变量,27-92列为数值型因变量
- 手动运行的单列代码示例:
clusWilcox.test(column27 ~ treatment + cluster(factor1), data = df) clusWilcox.test(column28 ~ treatment + cluster(factor1), data = df) # ... 重复到column92
我尝试改编lm的批量代码,但运行失败。参考的lm批量代码(可正常运行):
names(df) varlist <- names(df)[27:92] models <- lapply(varlist, function(x) { lm(substitute(i ~ treatment + factor1, list(i = as.name(x))), data = df) }) models
改编后的clusWilcox.test代码:
names(df) varlist <- names(df)[27:92] models2 <- lapply(varlist, function(x) { clusWilcox.test(substitute(i ~ treatment + cluster(factor1), list(i = as.name(x))), data = df) }) models2
运行后报错:
Error in `vectbl_as_col_location()`: ! Can't subset columns that don't exist. ✖ Columns `substitute`, `i ~ Treatment`, and `list(i = as.name(x))` don't exist. Run `rlang::last_error()` to see where the error occurred.
错误原因
lm可以正确解析substitute生成的公式对象,但clusWilcox.test的参数解析逻辑不同——它没有识别出传入的是公式对象,反而把substitute(...)整个表达式当作列名去数据框中查找,导致出现“列不存在”的错误。
解决方法
方法1:使用reformulate构建公式
reformulate可以直接通过字符向量生成公式,更适合批量场景:
library(clusrank) varlist <- names(df)[27:92] models2 <- lapply(varlist, function(x) { # 构建公式:因变量 ~ treatment + cluster(factor1) formula <- reformulate(c("treatment", "cluster(factor1)"), response = x) clusWilcox.test(formula, data = df) }) models2
方法2:将字符串转为公式对象
先拼接公式字符串,再用as.formula转换为公式对象:
library(clusrank) varlist <- names(df)[27:92] models2 <- lapply(varlist, function(x) { formula_str <- paste(x, "~ treatment + cluster(factor1)") clusWilcox.test(as.formula(formula_str), data = df) }) models2
结果整理(可选)
如果需要把结果整理成更易读的数据框,可以用broom包提取关键信息:
library(broom) library(dplyr) results_df <- bind_rows(lapply(models2, tidy), .id = "variable") results_df <- results_df %>% mutate(variable = varlist[as.integer(.id)]) %>% select(variable, statistic, p.value, method)
内容的提问来源于stack exchange,提问作者Isabelle
相关产品推荐
相关产品推荐

