【问题标题】:T-tests across multiple columns or tidy the data跨多列的 T 检验或整理数据
【发布时间】:2021-12-25 07:35:06
【问题描述】:

刚开始在 Stack 上发帖,如有任何问题,我们深表歉意。

我正在学习如何在 R 中更加自如,目前正在考虑使用 broom/purr 一次运行多个统计测试。我当前数据的一个示例如下所示:

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

但是在许多科目和更多测试中。我想进行相关 t 检验以查看分数在培训计划过程中的变化,但不想对每个分数进行测试。

我见过一些使用 group by、nest 和 map 来运行多个 t 检验的示例,但他们的数据格式较长

有没有办法在宽格式下实现相同的目标?或者我是否需要使用 pivot_longer 来更改数据。

提前致谢!

ETA 在这里进行了编辑,但给出的结果不正确,因此已被删除仍在寻找有关参数和相同长度的帮助

预计到达时间第 2 版

我确实找到了使用 pairwise.t.test 的解决方法(代码如下)。它给出了与跨个体评估进行 t.test 相同的 p 值。我很好奇为什么它适用于pairwise.t.test 而不是t.test。如果有人有任何想法,请告诉我!

    results <- testb %>%
     pivot_longer(-Subject, 
                   names_to = c("time", "test"), values_to = "score", 
                   names_pattern = "(Pre|Post)(.*)") %>%
     group_by(test) %>% 
     nest() %>% 
     mutate(ttests = map(.x=data, ~tidy(pairwise.t.test(.x$score, .x$time, paired = TRUE, p.adjust.method = "none")))) %>%  
     unnest(ttests)  

【问题讨论】:

  • 您很可能需要转置数据,因为它的格式不整齐。您正在测试的假设到底是什么?您是否尝试为每个不同的测试(即 TestA、TestB、TestC)生成 t 检验比较?
  • @MrFlick 感谢您的回复,关于数据透视的任何提示?我试图弄清楚但遇到了一些困难。每项测试都是一次体能评估。假设是经过一段时间的训练后,受试者的体能会显着提高。是的,这将是每个评估的 t 检验比较

标签: r tidyverse


【解决方案1】:

这是一个不转为长格式的尝试:这又是在令人难以置信的 akrun 的帮助下完成的!见这里:How to apply t.test() to multiple pairs of columns after mutate across:

df %>%
  summarise(across(starts_with('PreScore'), ~  t.test(.,
                                                      get(str_replace(cur_column(), "^PreScore", "PostScore")))$p.value, 
                   .names = "{.col}_TTest"))
  PreScoreTestA_TTest PreScoreTestB_TTest PreScoreTestC_TTest
1            0.767827            0.330604           0.8604162

【讨论】:

  • 谢谢!我会阅读那篇文章,因为我不理解其中的一些代码。 p值与上述解决方案不同是否有原因?我尝试在我的数据上运行它,它确实有效,但与单独运行 t 检验相比,p 值会有所不同
  • 我已尝试对您链接的询问 akrun 的帖子添加评论,但没有足够的声誉。只是为了扩展前面的评论,如果我运行以下代码 t.test(df$PostScoreTestA, df$PreScoreTestB, data = df, paired = TRUE),与上面输出中的 0.7678 相比,我得到的 p 值为 0.2272(如果我切换 post 和 pre order,则为 0.2136)
  • 差异是因为此解决方案没有通过将 t.test 的配对参数设置为 TRUE 来指定它们是配对样本 t 检验。
【解决方案2】:

是的,需要一些旋转。假设您没有方向性假设,并且您想对每个测试进行事前评估,这可能就是您要寻找的:

df <- as.data.frame(rbind(c(1,  30, 40, 6,  8,  12, 10),
                          c(2,  15, 12, 9,  13, 7,  7),
                          c(3,  20, 22, 11, 12, 9,  10)))

names(df) <- c("Subject",   
               "PrePushup", "PostPushup",   
               "PreRun",    "PostRun",  
               "PreJump",   "PostJump")

df %>% 
  pivot_longer(-Subject, 
               names_to = c("time", "test"), values_to = "score", 
               names_pattern = "(Pre|Post)(.*)") %>% 
  group_by(test) %>% 
  nest() %>% 
  mutate(t_tests = map(data, ~t.test(score ~ time, data = .x, paired = TRUE))) %>% 
  pull(t_tests) %>% 
  purrr::set_names(c("Pushup", "Run", "Jump"))

$Pushup

    Paired t-test

data:  score by time
t = 0.79241, df = 2, p-value = 0.5112
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -13.28958  19.28958
sample estimates:
mean of the differences 
                      3 


$Run

    Paired t-test

data:  score by time
t = 2.6458, df = 2, p-value = 0.1181
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -1.461250  6.127916
sample estimates:
mean of the differences 
               2.333333 


$Jump

    Paired t-test

data:  score by time
t = -0.37796, df = 2, p-value = 0.7418
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -4.127916  3.461250
sample estimates:
mean of the differences 
             -0.3333333 

【讨论】:

  • 谢谢你,我认为它有很大帮助,尽管我可能对代码的含义有一些疑问。但是我遇到了一个我没有想到的问题。我的列的命名有点不同,如下所示:PrePushup、PostPushup、PreRun、PostRun 等。我认为 name_sep 不起作用,或者我做错了。我一直在看 name_pattern 但也在苦苦挣扎。对此有何建议?抱歉,我认为命名没有那么重要。再次感谢您
  • names_pattern 参数使用正则表达式来分隔列。您可以从我不久前写的这篇博文中了解更多关于 R 中的正则表达式:craig.rbind.io/post/2020-06-28-asgr-2-3-string-manipulation。在这种情况下,您可以尝试类似 names_pattern = "(Pre|Post)(.*)" 之类的方法,其中我们将括号分成 2 个组件,其中第一个将进入新的“时间”列可以有"Pre" 或 ("|") "Post" 的值,另一个组件是变量名的其余部分,它将进入新的 "test" 列。
  • 我刚刚更新了我的答案以使用 names_pattern 而不是 names_sep 以使其更灵活
  • purrr::map() 执行的循环部分不需要相同的长度,因为它返回一个列表作为输出。代码失败是因为 t.test() 函数在一对原始测量列中的一个缺失值上引发错误。即使一个项目失败,您也可以通过将您应用于每个项目的函数包装在 try() 中,例如,让循环或映射函数继续运行。地图(数据,〜尝试(t.test(分数〜时间,数据= .x,配对= TRUE)))
  • 如果重复测量数据的数据不平衡或不完整,您可能需要考虑使用混合效应模型而不是配对 t 检验对其进行检查。但是,这个主题超出了堆栈溢出的范围,通过 stats.stackexchange 进行更合适的探索。此线程可能会有所帮助:stats.stackexchange.com/a/93959 或此线程:stats.stackexchange.com/a/310424
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-03
  • 2021-12-28
  • 2021-08-16
相关资源
最近更新 更多