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

如何在mutate across后对宽格式数据框的多组配对列应用t.test()

提问内容

本问题关联问题:T-tests across multiple columns or tidy the data

示例数据

df <- structure(list(Subject = 1:3, PreScoreTestA = c(30L, 15L, 20L
), PostScoreTestA = c(40L, 12L, 22L), PreScoreTestB = c(6L, 9L, 
11L), PostScoreTestB = c(8L, 13L, 12L), PreScoreTestC = c(12L, 
7L, 9L), PostScoreTestC = c(10L, 7L, 10L)), class = "data.frame", row.names = c(NA, 
-3L))

> df
  Subject PreScoreTestA PostScoreTestA PreScoreTestB PostScoreTestB PreScoreTestC PostScoreTestC
1       1            30             40             6              8            12             10
2       2            15             12             9             13             7              7
3       3            20             22            11             12             9             10

原问题询问是否可以对宽格式数据框中的成对列应用t.test,目前已有基于长格式的解决方案。
我尝试编写如下代码,以在宽格式下实现t.test运算:

可正常运行的加法运算版本

library(dplyr)
library(stringr)
df %>%
  mutate(across(starts_with('PreScore'), ~ . +
                  get(str_replace(cur_column(), "^PreScore", "PostScore")), .names = "{.col}_TTest")) %>%
  rename_at(vars(ends_with('TTest')), ~ str_remove(., "PreScore"))

# 输出结果:
  Subject PreScoreTestA PostScoreTestA PreScoreTestB PostScoreTestB PreScoreTestC PostScoreTestC
1       1            30             40             6              8            12             10
2       2            15             12             9             13             7              7
3       3            20             22            11             12             9             10
  TestA_TTest TestB_TTest TestC_TTest
1          70          14          22
2          27          22          14
3          42          23          19

报错的t.test版本

我尝试将+替换为t.test,但代码无法运行,尝试多种变体均失败:

library(dplyr)
library(stringr)
df %>%
  mutate(across(starts_with('PreScore'), ~ . t.test
                  get(str_replace(cur_column(), "^PreScore", "PostScore")), .names = "{.col}_TTest")) %>%
  rename_at(vars(ends_with('TTest')), ~ str_remove(., "PreScore"))

核心疑问

是否可以像-、+、/等运算符一样,在across后对预定义的列对集合应用t.test函数?


回答

可以实现,你之前的代码报错主要有两个原因:

  1. 函数调用语法错误:t.test是普通函数,不能像加减乘除运算符那样放在两个操作数中间,需要写成t.test(x, y)的标准函数调用形式
  2. t.test返回的是htest类的列表对象,不是单个数值,无法直接生成普通的数值列,需要用列表列存储结果,或者先把检验结果整理为结构化数据

实现方案

方案1:将完整检验结果存储为列表列

library(dplyr)
library(stringr)

# 配对t检验,不需要配对可删除paired=TRUE参数
result <- df %>%
  summarise(across(starts_with('PreScore'), 
                   ~ list(t.test(., get(str_replace(cur_column(), "^PreScore", "PostScore")), paired = TRUE)),
                   .names = "{.col}_TTest")) %>%
  rename_with(~ str_remove(., "PreScore"), ends_with('TTest'))

# 查看TestA的完整检验结果
result$TestA_TTest[[1]]

方案2:直接生成结构化的检验结果表

搭配broom包的tidy函数可以直接把所有检验的统计量整理成方便查看的表格:

library(dplyr)
library(stringr)
library(broom)
library(tidyr)

result_table <- df %>%
  summarise(across(starts_with('PreScore'), 
                   ~ tidy(t.test(., get(str_replace(cur_column(), "^PreScore", "PostScore")), paired = TRUE)),
                   .names = "{str_remove(.col, '^PreScore')}")) %>%
  unnest(cols = everything(), names_sep = "_")

输出的结果表会包含每个检验的t值、p值、置信区间、均值差等所有核心统计指标。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 02:45:00