R语言中用broom::tidy和dplyr::group_modify按物种分组批量做t.test
解决按物种分组批量做t检验并输出指定格式结果的问题
原代码问题分析
- 语法错误:你写的
broom::tidy调用方式不符合函数要求,导致出现逗号相关的语法报错; - 分组逻辑错误:在
group_modify中直接使用全局的df,而非当前分组的子数据集.x,会导致每个分组都用全量数据计算,而非目标子集; - 批量处理逻辑错误:未正确遍历每个数值变量执行t检验,无法生成包含
Variable列的结果。
正确解决方案
以下两种方法都能生成你需要的格式:包含Species、Variable列,以及t检验的完整统计结果。
方法一:转长格式后分组计算(更直观)
先将宽格式数据转为长格式,再按Species和Variable分组做t检验:
library(dplyr) library(tidyr) library(broom) df.ttest <- df %>% # 将第3列及以后的数值变量转为长格式 pivot_longer(cols = 3:ncol(.), names_to = "Variable", values_to = "Value") %>% # 按物种和变量分组 group_by(Species, Variable) %>% # 执行t检验并整理结果,最后取消分组 summarise(broom::tidy(t.test(Value ~ Experiment, data = cur_data())), .groups = "drop")
方法二:用group_modify结合循环处理(适合保留宽格式习惯)
通过group_modify处理每个物种分组,再循环每个变量执行t检验:
library(dplyr) library(purrr) library(broom) df.ttest <- df %>% group_by(Species) %>% group_modify(function(.x, .y) { # 获取当前分组中的数值变量列名(第3列开始) var_names <- names(.x)[3:ncol(.x)] # 遍历每个变量,执行t检验并合并结果 purrr::map_dfr(var_names, function(var) { # 动态构建t检验公式 t_test_formula <- as.formula(paste(var, "~ Experiment")) # 执行t检验并整理结果,添加Variable列 t.test(t_test_formula, data = .x) %>% broom::tidy() %>% mutate(Variable = var, .before = 1) }) }) %>% ungroup()
结果验证
运行上述代码后,df.ttest的结构会和你提供的示例完全一致:每行对应一个物种的一个变量的t检验结果,包含Species、Variable以及t检验的所有统计量列。
内容的提问来源于stack exchange,提问作者Dustin
相关产品推荐
相关产品推荐

