r-用lapply替换rbind-in for loop?(地狱的第二圈)



我在优化一段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)}

有问题的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
}

问题似乎出在rbind函数上我经常收到关于solution大小的错误消息,过一段时间后,它似乎太大了(超过50MB)。我想用列表和lapply和/或foreach替换这个循环和rbind。我已经开始将myframe转换为列表。

myframe_list <- lapply(seq_len(nrow(myframe)), function(i) myframe[i,])

虽然我尝试将这个非常好的介绍应用于并行处理,但我并没有真正做到这一点。

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

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

在这样的循环中使用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))

注释有点长,所以我把它放在这里:如果预先知道columns

    myfunction <- function(frame){
    athing = 0
       if(columns == 5){
       athing = 100
       }
       else{
       athing = 1000
       }
    value[colums+1] = athing
    return(value)}
    apply(myframe, 2, myfunction)

如果columns不是通过环境给出的,可以使用:

apply(myframe, 2, myfunction, columns)和您原来的myfunction定义。

最新更新