我在R邮件列表上多次询问过这个问题,但仍然找不到满意的答案。
假设我是一个矩阵m
m <- matrix(rnorm(10000000), ncol=10)
我可以通过以下方式获得每行的平均值:
system.time(rowMeans(m))
user system elapsed
0.100 0.000 0.097
但是
获得每行的最小值system.time(apply(m,1,min))
user system elapsed
16.157 0.400 17.029
需要的时间超过100倍,有没有办法加快速度?
答案 0 :(得分:17)
您可以使用pmin
,但必须将矩阵的每一列都放到一个单独的向量中。一种方法是将其转换为data.frame,然后通过pmin
调用do.call
(因为data.frames是列表)。
system.time(do.call(pmin, as.data.frame(m)))
# user system elapsed
# 0.940 0.000 0.949
system.time(apply(m,1,min))
# user system elapsed
# 16.84 0.00 16.95
答案 1 :(得分:14)
派对相当晚,但作为matrixStats的作者,如果有人发现这一点,请注意matrixStats::rowMins()
这些天非常快,例如。
library(microbenchmark)
library(Biobase) # rowMin()
library(matrixStats) # rowMins()
options(digits=3)
m <- matrix(rnorm(10000000), ncol=10)
stats <- microbenchmark(
rowMeans(m), ## A benchmark by OP
rowMins(m),
rowMin(m),
do.call(pmin, as.data.frame(m)),
apply(m, MARGIN=1L, FUN=min),
times=10
)
> stats
Unit: milliseconds
expr min lq mean median uq max
rowMeans(m) 77.7 82.7 85.7 84.4 90.3 98.2
rowMins(m) 72.9 74.1 88.0 79.0 90.2 147.4
rowMin(m) 341.1 347.1 395.9 383.4 395.1 607.7
do.call(pmin, as.data.frame(m)) 326.4 357.0 435.4 401.0 437.6 657.9
apply(m, MARGIN = 1L, FUN = min) 3761.9 3963.8 4120.6 4109.8 4198.7 4567.4
答案 2 :(得分:8)
如果您想坚持CRAN软件包,那么matrixStats
和fBasics
软件包都有rowMins
函数[注意s
不是Biobase
在{{1}}函数]和各种其他行和列统计信息。
答案 3 :(得分:5)
library("sos")
findFn("rowMin")
来自Bioconductor的Biobase
包......
source("http://bioconductor.org/biocLite.R")
biocLite("Biobase")
m <- matrix(rnorm(10000000), ncol=10)
system.time(rowMeans(m))
## user system elapsed
## 0.132 0.148 0.279
system.time(apply(m,1,min))
## user system elapsed
## 11.825 1.688 13.603
library(Biobase)
system.time(rowMin(m))
## user system elapsed
## 0.688 0.172 0.864
不如rowMeans
快,但比apply(...,1,min)
答案 4 :(得分:5)
我一直想在R 2.13.0中试用新的compiler
包。这基本上遵循Dirk here概述的帖子。
library(compiler)
library(rbenchmark)
rowMin <- function(x, ind) apply(x, ind, min)
crowMin <- cmpfun(rowMin)
benchmark(
rowMin(m,1)
, crowMin(m,1)
, columns=c("test", "replications","elapsed","relative")
, order="relative"
, replications=10)
)
结果:
test replications elapsed relative
2 crowMin(m, 1) 10 120.091 1.0000
1 rowMin(m, 1) 10 122.745 1.0221
至少可以说是反思,虽然看起来你已经有了一些其他好的选择。
答案 5 :(得分:2)
不是特别R-idiosyncratic,但肯定最快的方法是使用pmin
并循环列:
x <- m[,1]
for (i in 2:ncol(m)) x <- pmin(x, m[,i])
在我的机器上,对于1e + 07x10矩阵,其行程仅比rowMeans长3倍,并且通过do.call
比data.frame
方法略快。