假设我有一个大矩阵:

M <- matrix(rnorm(1e7),nrow=20)

进一步假设每个列代表一个样本。说我想将t.test()应用于每一列,有没有一种方法比使用apply()快得多?
apply(M, 2, t.test)

在我的计算机上运行分析花费了不到2分钟的时间:
> system.time(invisible( apply(M, 2, t.test)))
user  system elapsed
113.513   0.663 113.519

最佳答案

如果您有一台多核计算机,那么使用所有核都有一些好处,例如,使用mclapply

> library(multicore)
> M <- matrix(rnorm(40),nrow=20)
> x1 <- apply(M, 2, t.test)
> x2 <- mclapply(1:dim(M)[2], function(i) t.test(M[,i]))
> all.equal(x1, x2)
[1] "Component 1: Component 9: 1 string mismatch" "Component 2: Component 9: 1 string mismatch"
# str(x1) and str(x2) show that the difference is immaterial

这个小例子显示了事情按照我们的计划进行。现在扩大规模:
> M <- matrix(rnorm(1e7), nrow=20)
> system.time(invisible(apply(M, 2, t.test)))
   user  system elapsed
101.346   0.626 101.859
> system.time(invisible(mclapply(1:dim(M)[2], function(i) t.test(M[,i]))))
  user  system elapsed
55.049   2.527  43.668

这正在使用8个虚拟内核。你的旅费可能会改变。虽然 yield 不大,但付出的努力却很少。

编辑

如果您只关心t统计量本身,则提取相应的字段($statistic)会使事情变得更快一些,尤其是在多核情况下:
> system.time(invisible(apply(M, 2, function(c) t.test(c)$statistic)))
   user  system elapsed
 80.920   0.437  82.109
> system.time(invisible(mclapply(1:dim(M)[2], function(i) t.test(M[,i])$statistic)))
   user  system elapsed
 21.246   1.367  24.107

甚至更快,直接计算t值
my.t.test <- function(c){
  n <- sqrt(length(c))
  mean(c)*n/sd(c)
}

然后
> system.time(invisible(apply(M, 2, function(c) my.t.test(c))))
   user  system elapsed
 21.371   0.247  21.532
> system.time(invisible(mclapply(1:dim(M)[2], function(i) my.t.test(M[,i]))))
   user  system elapsed
144.161   8.658   6.313

关于r - 将t.test应用于大型矩阵的每一列的最快方法是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11460680/

10-12 14:19