当使用Openxlsx在循环中写入Excel时,R的速度会大大降低

当使用Openxlsx在循环中写入Excel时,R的速度会大大降低,r,excel,performance,R,Excel,Performance,我有一个函数,它返回64个数据帧的列表,一个大(525行,3000列),另一个小(10 x 10)。我编写了一些简单的代码将dataframes写入Excel(见下文),并将代码重复了64次(虽然不优雅,但可以正常工作): 代码大约在20分钟内运行——虽然不是很好,但可以接受。我观察到数据帧自然地分组为3组,因此我尝试编写21个循环,例如 options("openxlsx.numFmt" = NULL) headers = c("Full Algorith

我有一个函数,它返回64个数据帧的列表,一个大(525行,3000列),另一个小(10 x 10)。我编写了一些简单的代码将dataframes写入Excel(见下文),并将代码重复了64次(虽然不优雅,但可以正常工作):

代码大约在20分钟内运行——虽然不是很好,但可以接受。我观察到数据帧自然地分组为3组,因此我尝试编写21个循环,例如

  options("openxlsx.numFmt" = NULL)
  headers = c("Full Algorithm: Number well", 
              "Full Algorithm: Number unwell",
              "Full Algorithm: % well vs Threshold (x) and # Criteria met (y)")
  
  for(j in 2:4){
    if(j==4){   options("openxlsx.numFmt" = "0.0%")}
    writeData(wb, Sheetname, "Criteria met", startCol = 1, startRow = 13*(j-2) + 8)
    writeData(wb, Sheetname, df_tmp[[j]],    startCol = 2, startRow = 13*(j-2) + 3,  rowNames = TRUE)
    writeData(wb, Sheetname, headers[j-1],   startCol = 6, startRow = 13*(j-2) + 1)
    writeData(wb, Sheetname, "Threshold",    startCol = 8, startRow = 13*(j-2) + 2)
  
  }
令我惊讶的是,该程序现在需要6个小时才能运行,而且所有的时间似乎都花在了编写这些循环中的Excel上。有没有人想过可能会发生什么,以及我应该在哪里寻找业绩的显著下降?我完全无法解释它

诚恳


Thomas Philips

xlsx代码非常慢。这是XML代码。因此,您正在以一种奇怪的方式查找和插入行。内存分配(以及将数据块移动到新分配)本质上是缓慢的。为什么不能先用
bind_rows
之类的东西连接R中的数据,然后一次性创建xlsx工作簿?我故意不使用bind_rows,因为数据帧的大小不同,有些需要在它们下面写入文本和派生统计信息。我想知道如果我写csv文件是否会更快,尽管我怀疑我仍然需要移动所有的数据块。
  options("openxlsx.numFmt" = NULL)
  headers = c("Full Algorithm: Number well", 
              "Full Algorithm: Number unwell",
              "Full Algorithm: % well vs Threshold (x) and # Criteria met (y)")
  
  for(j in 2:4){
    if(j==4){   options("openxlsx.numFmt" = "0.0%")}
    writeData(wb, Sheetname, "Criteria met", startCol = 1, startRow = 13*(j-2) + 8)
    writeData(wb, Sheetname, df_tmp[[j]],    startCol = 2, startRow = 13*(j-2) + 3,  rowNames = TRUE)
    writeData(wb, Sheetname, headers[j-1],   startCol = 6, startRow = 13*(j-2) + 1)
    writeData(wb, Sheetname, "Threshold",    startCol = 8, startRow = 13*(j-2) + 2)
  
  }