【问题标题】:dplyr summarise multiple columns using t.testdplyr 使用 t.test 汇总多个列
【发布时间】:2014-12-02 08:54:05
【问题描述】:

是否有可能以某种方式针对同一个分类变量对多个变量进行 t.test,而无需按如下方式对数据集进行重塑?

data(mtcars)
library(dplyr)
library(tidyr)
j <- mtcars %>% gather(var, val, disp:qsec)
t <- j %>% group_by(var) %>% do(te = t.test(val ~ vs, data = .))

t %>% summarise(p = te$p.value)

我尝试过使用

mtcars %>% summarise_each_(funs = (t.test(. ~ vs))$p.value, vars = disp:qsec)

但它会引发错误。

奖励:t %&gt;% summarise(p = te$p.value) 如何还包含分组变量的名称?

【问题讨论】:

  • 您应该考虑在代码中添加空格。
  • 这可能是 data.table 的部分解决方案(没有汇总部分): (step1) library(data.table) (step2) setDT(j) (Step3) j[, te := t.test(value~vs), by=variable][]

标签: r dplyr


【解决方案1】:

在与@aosmith 和@Misha 进行了所有讨论之后,这是一种方法。正如@aosmith 在他/她的 cmets 中所写,您想要执行以下操作。

mtcars %>%
    summarise_each(funs(t.test(.[vs == 0], .[vs == 1])$p.value), vars = disp:qsec)

#         vars1        vars2      vars3        vars4        vars5
#1 2.476526e-06 1.819806e-06 0.01285342 0.0007281397 3.522404e-06

vs 是 0 或 1(组)。如果您想在变量(例如 dips)中的两组之间运行 t 检验,您似乎需要按照@aosmith 的建议对数据进行子集化。我想说谢谢你的贡献。

我最初的建议适用于另一种情况,您只需比较两列。这是示例数据和代码。

foo <- data.frame(country = "Iceland",
                  year = 2014,
                  id = 1:30,
                  A = sample.int(1e5, 30, replace = TRUE),
                  B = sample.int(1e5, 30, replace = TRUE),
                  C = sample.int(1e5, 30, replace = TRUE),
                  stringsAsFactors = FALSE)

如果您想对 A-C 和 B-C 组合运行 t 检验,以下是一种方法。

foo2 <- foo %>%
        summarise_each(funs(t.test(., C, pair = TRUE)$p.value), vars = A:B) 

names(foo2) <- colnames(foo[4:5])

#          A         B
#1 0.2937979 0.5316822

【讨论】:

  • 那些 p 值对我来说看起来不太正确。如果在没有公式的情况下使用 t.testxy 应该是每个组响应的向量。试试summarise_each(funs(t.test(.[vs == 0], .[vs == 1])$p.value), vars = disp:qsec)
  • @aosmith - 你能在 t.test 中使用公式让它工作吗? : mtcars %>% summarise_each(funs(t.test(.~vs)$p.value), vars = disp:qsec) - 它对我不起作用。
  • @KonradRudolph 再次嗨。我在上面运行了您的代码,但收到了一条错误消息。我再次坚持subset并写了以下内容。这是你追求的东西吗? mtcars %&gt;% group_by(am) %&gt;% summarize(t.test(subset(mpg, vs == 0), subset(mpg, vs == 1))$p.value) 如果您需要更多信息,请告诉我。我很乐意提供帮助并一起思考。
  • @KonradRudolph 是的。我明白你的意思。不知道为什么filter 不起作用。 filter(mtcars, vs == 0)[1] 有效。所以,最好的猜测是写mtcars %&gt;% group_by(am) %&gt;% summarize(out = t.test(filter(vs == 0)[1], filter(vs == 1)[1])$p.value)mtcars %&gt;% group_by(am) %&gt;% summarize(out = t.test(filter(.,vs == 0)[1], filter(.,vs == 1)[1])$p.value)。前者返回Error: no applicable method for 'filter_' applied to an object of class "logical",后者返回Error: incorrect length (19), expecting: 13
  • @KonradRudolph 还要给你一件事。没有group_by,以下对我有用。 mtcars %&gt;% summarize(out = t.test(filter(mtcars,vs == 0)[1], filter(mtcars,vs == 1)[1])$p.value)
【解决方案2】:

所以我最终开发了一个新功能: df=dataframe ,by_var=公式右侧,...公式左侧的所有变量(dplyr/tidyr select)。

例如: mult_t.test(mtcars,vs,disp:qsec)

mult_t.test<-function(df,by_var,...){
  require(dplyr)
  require(tidyr)
  by_var<-deparse(substitute(by_var))
  j<-df%>%gather(var,val,...)
  t<-j%>%group_by(var)%>%do(v=tes(.,by_var))
  k<-data.frame(levels(t$var),matrix(unlist(t$v),ncol=3,byrow = T))
  names(k)<-c("var",names(t$v[[1]]))
  k
}


tes<-function(df,vart){
  x<-t.test(df$val~df[[vart]])
  p<-x$estimate
  p<-c(p,p.val=x$p.value)
  p
}

【讨论】:

    【解决方案3】:

    意识到这个问题比较老了,这里再提供一个答案,供后人参考。

    这比公认的答案更通用,因为它允许动态生成变量名称而不是硬编码。

    vars_to_test <- c("disp","hp","drat","wt","qsec")
    iv <- "vs"
    
    mtcars %>%
      summarise_each_(
        funs_( 
          sprintf("stats::t.test(.[%s == 0], .[%s == 1])$p.value",iv,iv)
        ), 
        vars = vars_to_test)
    

    产生这个:

              disp           hp       drat           wt         qsec
    1 2.476526e-06 1.819806e-06 0.01285342 0.0007281397 3.522404e-06
    

    此解决方案的想法是使用 dplyr 函数的 SE 版本(summarise_each_funs_)而不是 NSE 版本(summarise_eachfuns)。有关标准评估(SE)和非标准评估(NSE)的更多信息,请查看vignette("nse")

    【讨论】:

    • 感谢您的解决方案!这个对我有用。但是,我有两条警告消息:1:summarise_each() is deprecated. Please use summarise_if(), summarise_at(), or summarise_all() instead: - To map "funs" over all variables, use summarise_all() - To map "funs" over a selection of variables, use summarise_at() 和 2:funs_() is deprecated. Please use list() instead。此代码是否有更新版本?第二个问题,有没有办法通过组名(即:在这种情况下为“vs”)更改“1”(第二行的第一个字符)?感谢您的帮助!
    • dplyr 改变了他们所有的东西所有代码现在都坏了
    【解决方案4】:

    我喜欢使用功能强大的“扫帚”包的以下解决方案:

    library("dplyr")
    library("broom")
    
    your_db %>%
      group_by(grouping_variable1, grouping_variable2 ...) %>%
      do(tidy(t.test(variable_u_want_2_test ~ dicothomous_grouping_var, data = .)))
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-06
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多