请考虑以下脚本,我们将调用它Foo.r
.
set.seed(1) x=matrix(rnorm(1000*1000),ncol=1000) x=data.frame(x) dummy = sapply(1:1000,function(i) sum(x[i,]) ) #dummy = sapply(1:1000,function(i) sum(x[,i]) )
当第一dummy
行被注释掉时,我们将对列进行求和,并且代码在我的机器上运行不到一秒钟.
$ time Rscript Foo.r real 0m0.766s user 0m0.536s sys 0m0.080s
当第二dummy
行被注释掉(并且第一行被注释掉)时,我们对行进行求和,并且运行时间接近30秒.
$ time Rscript Foo.r real 0m30.589s user 0m30.248s sys 0m0.104s
请注意,我知道的标准功能总结rowSums
和colSums
,但我使用金额仅作为这个奇怪的不对称的性能行为的一个例子.
这不是真正的结果sapply
,而是与数据帧的存储方式以及提取行与列的含义有关.数据框存储为列表,其中列表的每个元素都是列.
这意味着提取列比提取行更容易.
要证明这与此无关,请sapply
考虑使用您的数据框x
:
foo1 <- function(){ + for (i in 1:1000){ + tmp <- x[i, ] + } + } > > foo2 <- function(){ + for (i in 1:1000){ + tmp <- x[ ,i] + } + } > system.time(foo2()) user system elapsed 0.029 0.000 0.031 > system.time(foo1()) user system elapsed 15.986 0.074 15.894
如果您需要按行和快速执行操作,数据框通常是一个糟糕的选择.要对行进行操作,必须从每个列表项中提取相应的元素.要对列进行操作,只需循环遍历列.