发布在R中分配矩阵的最佳方法,NULL与NA?表明在R中编写自己的矩阵分配函数比使用R的内置matrix()函数预分配大矩阵快8到10倍.
有谁知道为什么手工制作的功能如此之快?R在矩阵()内部做什么这么慢?谢谢.
这是我系统上的代码:
create.matrix <- function( nrow, ncol ) {
x<-matrix()
length(x) <- nrow*ncol
dim(x) <- c(nrow,ncol)
x
}
system.time( x <- matrix(nrow=10000, ncol=9999) )
user system elapsed
1.989 0.136 2.127
system.time( y <- create.matrix( 10000, 9999 ) )
user system elapsed
0.192 0.141 0.332
identical(x,y)
[1] TRUE
Run Code Online (Sandbox Code Playgroud)
我向那些评论认为用户定义函数较慢的人道歉,因为上述链接中的答案中发布的内容不一致.我在查看用户时间,在上面的链接中快了大约8倍,而在我的系统上,用户定义的vs内置速度快了大约10倍.
回应约书亚的会议信息请求:
> sessionInfo()
R version 2.12.1 (2010-12-16)
Platform: x86_64-unknown-linux-gnu (64-bit)
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=C LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] tools_2.12.1
Run Code Online (Sandbox Code Playgroud)
另外,我试着运行Simon的三个例子,而Simon给出的最快的第三个例子对我来说是最慢的:
> system.time(matrix(NA, nrow=10000, ncol=9999))
user system elapsed
2.011 0.159 2.171
> system.time({x=NA; length(x)=99990000; dim(x)=c(10000,9999); x})
user system elapsed
0.194 0.137 0.330
> system.time(matrix(logical(0), nrow=10000, ncol=9999))
user system elapsed
4.180 0.200 4.385
Run Code Online (Sandbox Code Playgroud)
然而,我仍然认为西蒙可能在正确的轨道上,matrix()最初分配1x1矩阵然后复制它.有人知道关于R内部的任何好的文档吗?谢谢.
问题是你的matrix电话比你想象的要复杂一些.比较以下版本:
# copy NA matrix
> system.time(matrix(NA, nrow=10000, ncol=9999))
user system elapsed
1.272 0.224 1.496
# replicate NA vector (faster version of what you used)
> system.time({x=NA; length(x)=99990000; dim(x)=c(10000,9999); x})
user system elapsed
0.292 0.260 0.552
# fastest - just allocate a matrix filled with NAs
> system.time(matrix(logical(0), nrow=10000, ncol=9999))
user system elapsed
0.184 0.308 0.495
Run Code Online (Sandbox Code Playgroud)
因此,在您的示例中,您基本上创建了一个1 x 1 NA矩阵,该矩阵被复制到您指定的大小 - 最慢的方法.对矢量执行相同操作更快(因为它不需要对列使用模数) - 您以一种复杂的方式(通过创建矩阵,将其转换为矢量然后再转换回矩阵)来执行此操作,但是这个想法是一样的.最后,如果你只使用一个空向量,那么矩阵将简单地用NA你想要的东西填充,因此不需要额外的工作(最快).
编辑一个重要的注意事项:马修的建议是正确的,虽然没有涉及(因为他引用的代码就是这种logical(0)情况,而不是NA案例).不经意间我在上面的时间里运行了R-devel,所以发布的R中的时间会有所不同.
我将对这些评论提出异议,尽管我对其中的大多数都很了解.问题在于,引用的帖子有一个答案,其内部矛盾是评论者在没有检查的情况下依赖的.用户和系统的时间不会正确累加到它们应该的时间.
create.matrix <- function(size) {
x <- matrix()
length(x) <- size^2
dim(x) <- c(size,size)
x
}
system.time(x <- matrix(data=NA,nrow=10000,ncol=10000))
# user system elapsed
# 0.464 0.226 0.688
system.time(y <- create.matrix(size=10000))
# user system elapsed
# 0.177 0.239 0.414
Run Code Online (Sandbox Code Playgroud)
我怀疑效率实际上是通过用户定义的函数只能创建一个方阵来实现的,而'矩阵'需要检查参数的有效性以获得更一般的情况.
编辑:我看你已经证伪的假设我(关于方阵限制)之一,我也注意到,我的其他假设,这在某种程度上是由于懒惰的评估也没有我的测试.这种差异确实没有意义,因为用户代码使用了这个matrix功能.