尝试对每一行执行 t.test 并计算 p 值小于 0.05 的所有行
trying to perform a t.test for each row and count all rows where p-value is less than 0.05
在过去的四个小时里,我一直在绞尽脑汁试图找到 R 问题的解决方案,这让我抓狂。我到处寻找合适的答案,但到目前为止,我一直在碰壁。我现在呼吁这个美好社区的善意寻求帮助。
考虑以下数据集:
set.seed(2112)
DataSample <- matrix(rnorm(24000),nrow=1000)
colnames(DataSample) <- c(paste("Trial",1:12,sep=""),paste("Control",13:24,sep=""))
我需要对 DataSample 中的每一行执行 t 检验,以确定 TRIAL 和 CONTROL 组是否不同(等方差适用)。
然后我需要计算 p 值等于或低于 0.05 的行数。
这是我试过的代码,我知道它是错误的:
set.seed(2112)
DataSample <- matrix(rnorm(24000),nrow=1000)
colnames(DataSample) <- c(paste("Trial",1:12,sep=""),paste("Control",13:24,sep=""))
pValResults <- apply(
DataSample[,1:12],1,function(x) t.test(x,DataSample[,13:24], var.equal=T)$p.value
)
sum(pValResults < 0.05) # Returns the wrong answer (so I was told)
我确实尝试查看有关 Whosebug 的许多类似问题,但我经常以语法错误或维度不匹配而告终。上面的代码是我在不返回 R 错误的情况下所能得到的最好的代码——但是由于代码返回了错误的答案,我没有什么值得骄傲的。
如有任何建议,我们将不胜感激!提前感谢您的宝贵时间。
一个选项是遍历数据集,为每一行计算 t 检验,但它并不那么优雅。
set.seed(2112)
DataSample <- matrix(rnorm(24000),nrow=1000)
colnames(DataSample) <- c(paste("Trial",1:12,sep=""),paste("Control",13:24,sep=""))
# initialize vector of stored p-values
pvalue <- rep(0,nrow(DataSample))
for (i in 1:nrow(DataSample)){
pvalue[i] <- t.test(DataSample[i,1:12],DataSample[i,13:24])$p.value
}
# finding number that are significant
sum(pvalue < 0.05)
我转换成一个data.table
,得到的答案是45:
DataSample.dt <- as.data.table(DataSample)
sum(sapply(seq_len(nrow(DataSample.dt)), function(x)
t.test(DataSample.dt[x, paste0('Trial', 1:12), with=F],
DataSample.dt[x, paste0('Control', 13:24), with=F],
var.equal=T)$p.value) < 0.05)
要进行配对 T 检验,您需要提供paired = TRUE
参数。 t.test
函数未向量化,但一次测试整个矩阵非常简单。这是三种方法(包括使用apply
):
library("genefilter")
library("matrixStats")
library("microbenchmark")
dd <- DataSample[, 1:12] - DataSample[, 13:24]
microbenchmark::microbenchmark(
manual = {ps1 <- 2 * pt(-abs(rowMeans(dd) / sqrt(rowVars(dd) / ncol(dd))), ncol(dd) - 1)},
apply = {ps2 <- apply(DataSample, 1, function(x) t.test(x[1:12], x[13:24], paired=TRUE)$p.value)},
rowttests = {ps3 <- rowttests(dd)[, "p.value"]})
#Unit: milliseconds
# expr min lq mean median uq max
# manual 1.611808 1.641783 1.677010 1.663122 1.709401 1.852347
# apply 390.869635 398.720930 404.391487 401.508382 405.715668 634.932675
# rowttests 2.368823 2.417837 2.639671 2.574320 2.757870 7.207135
# neval
# 100
# 100
# 100
您可以看到手动方法比应用快 200 倍以上。
如果您实际上是指不成对的测试,这里是等效比较:
microbenchmark::microbenchmark(
manual = {x <- DataSample[, 1:12]; y <- DataSample[, 13:24]; ps1 <- 2 * pt(-abs((rowMeans(x) - rowMeans(y)) / sqrt((rowVars(x) + rowVars(y)) / ncol(x))), ncol(DataSample) - 2)},
apply = { ps2 <- apply(DataSample, 1, function(x) t.test(x[1:12], x[13:24], var.equal = TRUE)$p.value)},
rowttests = {ps3 <- rowttests(DataSample, factor(rep(1:2, each = 12)))[, "p.value"]})
请注意,手动方法假定两组的大小相同。
使用外部库添加替代方案。
执行测试:
library(matrixTests)
res <- row_t_equalvar(DataSample[,1:12], DataSample[,13:24])
结果格式:
res
obs.x obs.y obs.tot mean.x mean.y mean.diff var.x var.y var.pooled stderr df statistic pvalue conf.low conf.high alternative mean.null conf.level
1 12 12 24 0.30569721 0.160622830 0.145074376 0.5034806 1.0769678 0.7902242 0.3629105 22 0.399752487 0.69319351 -0.6075559 0.89770469 two.sided 0 0.95
2 12 12 24 -0.27463354 -0.206396781 -0.068236762 0.8133311 0.2807800 0.5470556 0.3019535 22 -0.225984324 0.82329990 -0.6944500 0.55797651 two.sided 0 0.95
3 12 12 24 -0.19805092 -0.023207888 -0.174843032 0.4278359 0.5604078 0.4941219 0.2869733 22 -0.609265949 0.54858909 -0.7699891 0.42030307 two.sided 0 0.95
具有p <= 0.05
的行数:
> sum(res$pvalue <= 0.05)
[1] 4
在过去的四个小时里,我一直在绞尽脑汁试图找到 R 问题的解决方案,这让我抓狂。我到处寻找合适的答案,但到目前为止,我一直在碰壁。我现在呼吁这个美好社区的善意寻求帮助。
考虑以下数据集:
set.seed(2112)
DataSample <- matrix(rnorm(24000),nrow=1000)
colnames(DataSample) <- c(paste("Trial",1:12,sep=""),paste("Control",13:24,sep=""))
我需要对 DataSample 中的每一行执行 t 检验,以确定 TRIAL 和 CONTROL 组是否不同(等方差适用)。
然后我需要计算 p 值等于或低于 0.05 的行数。
这是我试过的代码,我知道它是错误的:
set.seed(2112)
DataSample <- matrix(rnorm(24000),nrow=1000)
colnames(DataSample) <- c(paste("Trial",1:12,sep=""),paste("Control",13:24,sep=""))
pValResults <- apply(
DataSample[,1:12],1,function(x) t.test(x,DataSample[,13:24], var.equal=T)$p.value
)
sum(pValResults < 0.05) # Returns the wrong answer (so I was told)
我确实尝试查看有关 Whosebug 的许多类似问题,但我经常以语法错误或维度不匹配而告终。上面的代码是我在不返回 R 错误的情况下所能得到的最好的代码——但是由于代码返回了错误的答案,我没有什么值得骄傲的。
如有任何建议,我们将不胜感激!提前感谢您的宝贵时间。
一个选项是遍历数据集,为每一行计算 t 检验,但它并不那么优雅。
set.seed(2112)
DataSample <- matrix(rnorm(24000),nrow=1000)
colnames(DataSample) <- c(paste("Trial",1:12,sep=""),paste("Control",13:24,sep=""))
# initialize vector of stored p-values
pvalue <- rep(0,nrow(DataSample))
for (i in 1:nrow(DataSample)){
pvalue[i] <- t.test(DataSample[i,1:12],DataSample[i,13:24])$p.value
}
# finding number that are significant
sum(pvalue < 0.05)
我转换成一个data.table
,得到的答案是45:
DataSample.dt <- as.data.table(DataSample)
sum(sapply(seq_len(nrow(DataSample.dt)), function(x)
t.test(DataSample.dt[x, paste0('Trial', 1:12), with=F],
DataSample.dt[x, paste0('Control', 13:24), with=F],
var.equal=T)$p.value) < 0.05)
要进行配对 T 检验,您需要提供paired = TRUE
参数。 t.test
函数未向量化,但一次测试整个矩阵非常简单。这是三种方法(包括使用apply
):
library("genefilter")
library("matrixStats")
library("microbenchmark")
dd <- DataSample[, 1:12] - DataSample[, 13:24]
microbenchmark::microbenchmark(
manual = {ps1 <- 2 * pt(-abs(rowMeans(dd) / sqrt(rowVars(dd) / ncol(dd))), ncol(dd) - 1)},
apply = {ps2 <- apply(DataSample, 1, function(x) t.test(x[1:12], x[13:24], paired=TRUE)$p.value)},
rowttests = {ps3 <- rowttests(dd)[, "p.value"]})
#Unit: milliseconds
# expr min lq mean median uq max
# manual 1.611808 1.641783 1.677010 1.663122 1.709401 1.852347
# apply 390.869635 398.720930 404.391487 401.508382 405.715668 634.932675
# rowttests 2.368823 2.417837 2.639671 2.574320 2.757870 7.207135
# neval
# 100
# 100
# 100
您可以看到手动方法比应用快 200 倍以上。
如果您实际上是指不成对的测试,这里是等效比较:
microbenchmark::microbenchmark(
manual = {x <- DataSample[, 1:12]; y <- DataSample[, 13:24]; ps1 <- 2 * pt(-abs((rowMeans(x) - rowMeans(y)) / sqrt((rowVars(x) + rowVars(y)) / ncol(x))), ncol(DataSample) - 2)},
apply = { ps2 <- apply(DataSample, 1, function(x) t.test(x[1:12], x[13:24], var.equal = TRUE)$p.value)},
rowttests = {ps3 <- rowttests(DataSample, factor(rep(1:2, each = 12)))[, "p.value"]})
请注意,手动方法假定两组的大小相同。
使用外部库添加替代方案。
执行测试:
library(matrixTests)
res <- row_t_equalvar(DataSample[,1:12], DataSample[,13:24])
结果格式:
res
obs.x obs.y obs.tot mean.x mean.y mean.diff var.x var.y var.pooled stderr df statistic pvalue conf.low conf.high alternative mean.null conf.level
1 12 12 24 0.30569721 0.160622830 0.145074376 0.5034806 1.0769678 0.7902242 0.3629105 22 0.399752487 0.69319351 -0.6075559 0.89770469 two.sided 0 0.95
2 12 12 24 -0.27463354 -0.206396781 -0.068236762 0.8133311 0.2807800 0.5470556 0.3019535 22 -0.225984324 0.82329990 -0.6944500 0.55797651 two.sided 0 0.95
3 12 12 24 -0.19805092 -0.023207888 -0.174843032 0.4278359 0.5604078 0.4941219 0.2869733 22 -0.609265949 0.54858909 -0.7699891 0.42030307 two.sided 0 0.95
具有p <= 0.05
的行数:
> sum(res$pvalue <= 0.05)
[1] 4