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

如何用dplyr的across函数实现分组t检验,替代弃用的summarize_each

正确实现方案

版本1:和旧方案输出完全一致

library(tidyverse)
library(broom)

mtcars %>%
  group_by(am) %>%
  summarise(across(
    .cols = mpg,
    .fns = list(
      p.value = ~ t.test(.x[cur_data()$vs == 0], .x[cur_data()$vs == 1])$p.value,
      conf.low = ~ t.test(.x[cur_data()$vs == 0], .x[cur_data()$vs == 1])$conf.int[1],
      conf.high = ~ t.test(.x[cur_data()$vs == 0], .x[cur_data()$vs == 1])$conf.int[2]
    )
  ))

运行输出:

# A tibble: 2 × 4
     am mpg_p.value mpg_conf.low mpg_conf.high
  <dbl>       <dbl>        <dbl>         <dbl>
1     0    0.000395        -8.33         -3.05
2     1    0.00459        -14.0          -3.27

如果需要批量处理多个指标,只要修改.cols参数即可,比如.cols = c(mpg, disp, hp)就能同时对这三个指标做分组t检验。

版本2:更简洁的完整结果输出(推荐)

直接用broom::tidy提取t检验的所有结果,无需手动逐个提取字段:

mtcars %>%
  group_by(am) %>%
  summarise(
    across(mpg, ~ list(tidy(t.test(.x[vs == 0], .x[vs == 1])))) %>% 
      unnest(everything())
  )

运行输出会包含t检验的统计量、估计值、p值、置信区间、检验方法等全部字段,和单独调用t.test后tidy的结果完全一致。


报错原因说明

你之前的代码有两个核心问题:

  1. across的.fns参数要求接收函数对象,你直接传入了执行表达式,没有封装为函数。需要用~开头的purrr风格lambda表达式封装逻辑。
  2. across的lambda中,.x(或者简写的.)仅指代当前遍历的列(也就是你选中的mpg向量),无法直接访问同分组的其他列,需要用cur_data()获取当前分组的完整数据框,才能调用vs列做筛选。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 21:39:03