如何优化嵌套的Loop R

时间:2017-09-27 22:04:43

标签: r loops for-loop optimization nested

我正在尝试优化这个嵌套for循环,它取2个数字的最小值,然后将结果添加到数据帧。我能够使用矢量化和初始化显着降低它,但我不太确定如何将该逻辑应用于嵌套的for循环。有没有快速的方法让这个运行得更快?坐在超过5小时的运行时间。

“模拟”具有100k值,“限制”具有5427个值

output <- data.frame(matrix(nrow = nrow(simulation),ncol = nrow(limits)))
res <- character(nrow(simulation))

for(i in 1:nrow(limits)){
    for(j in 1:nrow(simulation)){
        res[j] <- min(limits[i,1],simulation[j,1])
    }
    output[,i] <- res
}

编辑*

dput(head(simulation))
    structure(list(simulation = c(124786.7479,269057.2118,80432.47896,119513.0161,660840.5843,190983.7893)), .Names = "simulation", row.names = c(NA,6L), class = "data.frame")

dput(head(limits))
    structure(list(limits = c(5000L,10000L,20000L,25000L,30000L)), .Names = "limits", row.names = c(NA, 6L), class = "data.frame")

2 个答案:

答案 0 :(得分:1)

如果RAM中有> 15GB(每个数字大约100K * 5500 * 8个字节* 3(结果+外部x个值+外部y个值)),您可以尝试:

outer(simulation[[1]], limits[[1]], pmin)

虽然实际上你可能需要超过15GB,因为我认为pmin会更复杂。如果您没有ram,则必须解决问题(例如,依赖于一次执行某个列的代码或某些代码)。

答案 1 :(得分:1)

基本上,当你有一个双循环时,使用Rcpp通常很有用。

此外,我将使用包 bigstatsr 来节省一些RAM。您可以创建和访问存储在磁盘上的矩阵。

所以,你可以这样做:

// [[Rcpp::depends(bigstatsr, BH)]]
#include <bigstatsr/BMAcc.h>
#include <Rcpp.h>
using namespace Rcpp;


// [[Rcpp::export]]
void fillMat(Environment BM,
             const NumericVector& limits,
             const NumericVector& simulation) {

  XPtr<FBM> xpBM = BM["address"];
  BMAcc<double> macc(xpBM);

  int n = macc.nrow();
  int m = macc.ncol();

  for (int i = 0; i < m; i++)
    for (int j = 0; j < n; j++)
      macc(j, i) = std::min(limits[i], simulation[j]);
}

其中'fill-FBM.cpp'是

{
  «Address» : {
    «AddressOne» : {
      "address" : "Москва, Пресненская набережная д.8, квартира 195, подъезд 94",
    },
    "AddressTwo» : {
      "address" : "Москва, ул. Правды д.24 строение 3",
    },
    "AddressThree» : {
      "address" : "Москва,ул.Электрозаводская д.21",
    }
  }
}