用lapply替换for循环中的rbind?(地狱的第二圈)

use*_*232 3 optimization for-loop r lapply rbind

我在优化一段R代码时遇到了麻烦.以下示例代码应说明我的优化问题:

一些初始化和函数定义:

a <- c(10,20,30,40,50,60,70,80)
b <- c(“a”,”b”,”c”,”d”,”z”,”g”,”h”,”r”)
c <- c(1,2,3,4,5,6,7,8)
myframe <- data.frame(a,b,c)
values <- vector(length=columns)
solution <- matrix(nrow=nrow(myframe),ncol=columns+3)

myfunction <- function(frame,columns){
athing = 0
   if(columns == 5){
   athing = 100
   }
   else{
   athing = 1000
   }
value[colums+1] = athing
return(value)}
Run Code Online (Sandbox Code Playgroud)

有问题的for循环看起来像这样:

columns = 6
for(i in 1:nrow(myframe){
   values <- myfunction(as.matrix(myframe[i,]), columns)
   values[columns+2] = i
   values[columns+3] = myframe[i,3]
   #more columns added with simple operations (i.e. sum)

   solution <- rbind(solution,values)
   #solution is a large matrix from outside the for-loop
}
Run Code Online (Sandbox Code Playgroud)

问题似乎是rbind功能.我经常收到有关其大小solution似乎在一段时间后(大于50 MB)大的错误消息.我想rbind用一个列表lapply和/或foreach 替换这个循环.我已经开始转换myframe为列表了.

myframe_list <- lapply(seq_len(nrow(myframe)), function(i) myframe[i,])
Run Code Online (Sandbox Code Playgroud)

虽然我尝试将这个非常好的介绍应用于并行处理,但我还没有真正走得更远.

如何在不必更改的情况下重建for循环myfunction?显然我对不同的解决方案持开放态度......

编辑:这个问题似乎是直接来自R Inferno第二个地狱圈.有什么建议?

kon*_*vas 7

rbind在这样的循环中使用是不好的做法,是在每次迭代中放大solution数据框然后将其复制到新对象,这是一个非常缓慢的过程,也可能导致内存问题.解决此问题的一种方法是创建一个列表,其第i个组件将存储第i个循环迭代的输出.最后一步是在该列表上调用rbind(最后一次).这看起来像

my.list <- vector("list", nrow(myframe))
for(i in 1:nrow(myframe)){
    # Call all necessary commands to create values
    my.list[[i]] <- values
}
solution <- rbind(solution, do.call(rbind, my.list))
Run Code Online (Sandbox Code Playgroud)