【问题标题】:perform ttest on a data.frame在 data.frame 上执行 ttest
【发布时间】:2018-02-08 15:49:57
【问题描述】:

尝试从 data.frame 执行 ttest(并获取 p.value),有一列包含组(好与坏),其余列是数字。

我在这里生成了一个玩具数据集:

W <- rep(letters[seq( from = 1, to = 2)], 25)
X <- rnorm(n=50, mean = 10, sd = 5)
Y <- rnorm(n=50, mean = 15, sd = 6)
Z <- rnorm(n=50, mean = 20, sd = 5)
test_data <- data.frame(W, X, Y, Z)

然后我将数据转换成长格式:

melt_testdata <- melt(test_data)

并进行了 t.test

lapply(unique(melt_testdata$variable),function(x){
  Good <- subset(melt_testdata, W  == 'a' & variable ==x)$variable
  Bad <- subset(melt_testdata, W == 'b' & variable ==x)$variable
  t.test(Good,Bad)$p.value
})

但我没有得到 t.test 结果,而是收到以下错误消息:

Error in if (stderr < 10 * .Machine$double.eps * max(abs(mx), abs(my))) stop("data are essentially constant") : 
  missing value where TRUE/FALSE needed In addition: Warning messages:
1: In mean.default(x) : argument is not numeric or logical: returning NA
2: In var(x) :
  Calling var(x) on a factor x is deprecated and will become an error.
  Use something like 'all(duplicated(x)[-1L])' to test for a constant vector.
3: In mean.default(y) : argument is not numeric or logical: returning NA
4: In var(y) :
  Calling var(x) on a factor x is deprecated and will become an error.
  Use something like 'all(duplicated(x)[-1L])' to test for a constant vector.

然后我尝试编写循环(第一次..)

good <- matrix(,50)
bad <- matrix(,50)
cnt=3
out <- rep(0,cnt)


for (i in 2:4){
  good[i] <- subset(test_data, W == 'a', select= test_data[,i])
  bad[i] <- subset(test_data, W == 'b', select= test_data[,i])
  out[i] <- print(t.test(good[[i]], bad[[i]])$p.value)
}

仍然没有得到 p.values ....... 这是错误信息

Error in x[j] : only 0's may be mixed with negative subscripts

感谢任何方法的帮助,谢谢!

【问题讨论】:

  • 只需使用$value 而不是$variable,因为t-test 需要数字向量。

标签: r dataframe lapply t-test


【解决方案1】:

这是使用dplyrt.test 的公式参数的解决方案。 do 作用于由group_by. 定义的每个组glancet.test 输出中提取值并将它们制成data.frame

library(tidyverse)
library(broom)

melt_testdata %>% 
  group_by(variable) %>% 
  do(glance(t.test(value ~ W, data = .)))

【讨论】:

  • 谢谢@Richard Telford,它运作良好。 data = 是什么意思?什么意思?
  • . 是data.frame melt_testdata 的一部分,它被variable 分割。 t.test 的 data 参数允许公式访问 data.frame 中的变量(您在 lm 中得到相同的东西)
【解决方案2】:

我认为使用t.testformula 方法会更好。试试

library(broom)
library(magrittr)
library(dplyr)

W <- rep(letters[seq( from = 1, to = 2)], 25)
X <- rnorm(n=50, mean = 10, sd = 5)
Y <- rnorm(n=50, mean = 15, sd = 6)
Z <- rnorm(n=50, mean = 20, sd = 5)
test_data <- data.frame(W, X, Y, Z)

lapply(test_data[c("X", "Y", "Z")],
       function(x, y) t.test(x ~ y),
       y = test_data[["W"]]) %>% 
  lapply(tidy) %>% 
  do.call("rbind", .) %>% 
  mutate(variable = rownames(.))

编辑:

更严格地遵守dplyr 理念,您可以使用以下内容:实际上看起来更简洁。

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

W <- rep(letters[seq( from = 1, to = 2)], 25)
X <- rnorm(n=50, mean = 10, sd = 5)
Y <- rnorm(n=50, mean = 15, sd = 6)
Z <- rnorm(n=50, mean = 20, sd = 5)

test_data <- data.frame(W, X, Y, Z) 

test_data %>% 
  gather(variable, value, X:Z) %>% 
  group_by(variable) %>% 
  do(., tidy(t.test(value ~ W, data = .)))

【讨论】:

  • 谢谢它的工作!我还在更大的数据集上对其进行了测试,结果也很好。非常感谢。我把 test_data[c("X", "Y", "Z")] 改成了 test_data[2:4],它还在工作,太好了!!
  • 是的。如果您的分组变量是您的第一列,您也可以执行 test_data[-1] 并获得相同的结果。
  • 我知道这是一个愚蠢的问题,但 .在 data = mean(最后一行)之后?
  • 这是一个占位符。如果您查看?do,参数是do(.data, ...)。通过将. 放在第一个参数中,它会获取来自上一个调用的数据帧。将其放入t.test 中的data = . 会将数据传递给函数。 (我不确定这是否有意义)
  • 谢谢 Ben,这真的很有帮助。我将阅读该功能并学习如何使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-10
相关资源
最近更新 更多