r - 为什么 `sapply` 在 R 中处理数据帧中的行比处理列慢得多?

标签 r

考虑以下脚本,我们将其称为 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

请注意,我知道标准求和函数 rowSumscolSums ,但我仅将 sum 用作这种奇怪的不对称性能行为的示例。

最佳答案

这不是 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 

如果您需要按行快速地做事,数据框通常是一个糟糕的选择。要对行进行操作,它必须从每个列表项中提取相应的元素。要对列进行操作,它只需要遍历列。

关于r - 为什么 `sapply` 在 R 中处理数据帧中的行比处理列慢得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20319318/

相关文章:

r - 至少相差 30 分钟的子集观测值

r - 文本在 R 图中无法正确显示

r - 仅从向量中选择整数

r - 如何绘制平滑函数的一阶导数?

c - 使用 R 从 C 程序绘制函数

R:行数不等的列绑定(bind)

r - 建立总线连接失败;运行命令 'timedatectl' 的状态为 1

r - 如何更改 R 中的矩阵列类型

r - 密度曲线下的阴影(填充或颜色)面积(按分位数)

r - 使用 Optimize R 优化向量