用t.test比较两个以上组中的多个变量

时间:2018-12-15 22:12:05

标签: r loops purrr t-test broom

我试图做一次t检验,比较时间1/2/3 ..和阈值之间的值。 这是我的数据框:

time.df1<-data.frame("condition" =c("A","B","C","A","C","B"), 
"time1" = c(1,3,2,6,2,3) ,
"time2" = c(1,1,2,8,2,9) ,
"time3" = c(-2,12,4,1,0,6),
"time4" = c(-8,3,2,1,9,6),
"threshold" = c(-2,3,8,1,9,-3))

我尝试通过以下方式比较每两个值:

time.df1%>% 
select_if(is.numeric)  %>%
purrr::map_df(~ broom::tidy(t.test(. ~ threshold)))

但是,我收到了此错误消息

 Error in eval(predvars, data, env) : object 'threshold' not found

所以,我尝试了另一种方式(也许是错误的)

time.df2<-time.df1%>%gather(TF,value,time1:time4)
time.df2%>% group_by(condition) %>% do(tidy(t.test(value~TF, data=.)))

不幸的是,我遇到了这个错误。甚至我将条件限制为仅两个级别(A,B)

 Error in t.test.formula(value ~ TF, data = .) : grouping factor must have exactly 2 levels

我希望根据条件在每个时间列到阈值列之间进行t检验循环,然后使用broom::tidy获得整齐的结果。我的方法显然行不通,非常感谢您提出改进我的代码的任何建议。

2 个答案:

答案 0 :(得分:1)

我们可以从threshold中删除select,然后通过创建一个data.frame来重新引入它,该t.test将进入library(tidyverse) time1.df %>% select_if(is.numeric) %>% select(-threshold) %>% map_df(~ data.frame(time = .x, time1.df['threshold']) %>% broom::tidy(t.test(. ~ threshold))) 的公式对象中

from PyQt5 import QtWidgets

QSS = '''
QTreeWidget{ 
    border: None 
}
QLabel{
    background-color: white; 
    min-height: 200px;
}
'''

class widget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        treewidget = QtWidgets.QTreeWidget()
        label = QtWidgets.QLabel()

        grid = QtWidgets.QGridLayout(self)
        grid.setSpacing(10)
        grid.addWidget(treewidget, 1, 0)
        grid.addWidget(label, 2, 0)
        self.show()

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    app.setStyleSheet(QSS)
    f = widget()
    sys.exit(app.exec_())

答案 1 :(得分:1)

另一种方法是先定义一个带有t.test()所需选项的函数,然后为每对变量(即“ time *”和“ threshold”的每种组合)和嵌套创建数据帧将它们放入列表列,然后将map()与“ broom”中的相关函数结合使用以简化输出。

library(tidyverse)
library(broom)

ttestfn <- function(data, ...){
  # amend this function to include required options for t.test
  res = t.test(data$resp, data$threshold)
  return(res)
}   

df2 <-   
time.df1 %>% 
  gather(time, "resp", - threshold, -condition) %>% 
  group_by(time) %>% 
  nest() %>% 
  mutate(ttests = map(data, ttestfn),
         glances = map(ttests, glance))
# df2 has data frames, t-test objects and glance summaries 
# as separate list columns

现在可以轻松查询该对象以提取所需内容

df2 %>% 
unnest(glances, .drop=TRUE)

但是,我不清楚您要如何处理“条件”,所以我想知道,用GLM来重新构造问题是否更直接(如camille在评论中所建议:ANOVA是GLM系列)。

重塑数据,将“阈值”定义为“时间”因子的参考水平,R使用的默认“处理”对比度将每次与“阈值”进行比较:

time.df2 <- 
  time.df1 %>% 
  gather(key = "time", value = "resp", -condition) %>% 
  mutate(time = fct_relevel(time, "threshold")) # define 'threshold' as baseline

fit.aov <- aov(resp ~ condition * time, data = time.df2)
summary(fit.aov)
summary.lm(fit.aov) # coefficients and p-values

当然,这假定所有主题都是独立的(即没有重复的度量)。如果没有,那么您将需要进行更复杂的过程。无论如何,采用适合研究设计的GLM应该有助于最大程度地减少对同一数据集进行多次t检验的隐患。