R:循环处理大数据集(GB)的块?

Posted

技术标签:

【中文标题】R:循环处理大数据集(GB)的块?【英文标题】:R:Loops to process large dataset(GBs) in chunks? 【发布时间】:2013-09-05 01:25:22 【问题描述】:

我有一个以 GB 为单位的大型数据集,我必须在分析它们之前对其进行处理。 我尝试创建一个连接器,它允许我循环遍历大型数据集并一次提取块。这允许我隔离满足某些条件的数据。

我的问题是,我无法为连接器创建一个指标,规定它为空,并在到达数据集末尾时执行 close(connector)。此外,对于提取的第一块数据,我必须跳过 17 行,因为该文件包含 R 无法读取的标头。

有效的手动尝试:

filename="nameoffile.txt"    
con<<-file(description=filename,open="r")    
data<-read.table(con,nrows=1000,skip=17,header=FALSE)    
data<-read.table(con,nrows=1000,skip=0,header=FALSE)    
.    
.    
.    
till end of dataset

由于我想避免手动键入上述命令,直到我到达数据集的末尾,我尝试编写一个循环来自动化该过程,但没有成功。

我尝试循环失败:

filename="nameoffile.txt"    
con<<-file(description=filename,open="r")    
data<-read.table(con,nrows=1000,skip=17,header=FALSE)        
if (nrow(rval)==0)     
  con <<-NULL    
  close(con)    
  else    
    if(nrow(rval)!=0)    
    con <<-file(description=filename, open="r")    
    data<-read.table(conn,nrows=1000,skip=0,header=FALSE)      
      

【问题讨论】:

你调查过ff包和read.table.ffdf吗? 仅使用基本 R 来解决这个问题并不是一个好主意。包ffbigmemory 甚至data.table 浮现在脑海。 文本文件中以GB为单位存储的文件实际上并不是很大。在分析之前尝试压缩它们。主要限制是读取磁盘 (I/O)。您可以使用 read.table 并将其保存为压缩级别为 9 的 RData 格式。压缩率约为 10%,具体取决于您的内容,最后您的文件只有 MB。 也许包 LaF 对你也有用? 【参考方案1】:

看起来你走在正确的轨道上。只需打开一次连接(您不需要使用&lt;&lt;-,只需&lt;-;使用更大的块大小,以便可以使用R的矢量化操作来有效地处理每个块),沿线

filename <- "nameoffile.txt"
nrows <- 1000000
con <- file(description=filename,open="r")    
## N.B.: skip = 17 from original prob.! Usually not needed (thx @Moody_Mudskipper)
data <- read.table(con, nrows=nrows, skip=17, header=FALSE)
repeat 
    if (nrow(data) == 0)
        break
    ## process chunk 'data' here, then...
    ## ...read next chunk
    if (nrow(data) != nrows)   # last chunk was final chunk
        break
    data <- tryCatch(
        read.table(con, nrows=nrows, skip=0, header=FALSE)
    , error=function(err) 
       ## matching condition message only works when message is not translated
       if (identical(conditionMessage(err), "no lines available in input"))
          data.frame()
       else stop(err)
    )

close(con)    

在我看来,迭代是一种很好的策略,尤其是对于您将要处理一次而不是像数据库一样重复引用的文件。答案是修改以尝试更稳健地检测文件末尾的读取。

【讨论】:

您在阅读最后一次迭代时是否收到此错误消息? Error in read.table(infile, header = FALSE, nrows = 10, sep = ",", stringsAsFactors = FALSE) : no lines available in input In addition: Warning message: In read.table(infile, header = FALSE, nrows = 10, sep = ",", stringsAsFactors = FALSE) : incomplete final line found by readTableHeader on 'data/temp.csv' 有什么办法吗? @mchangun 试图详细说明,但它有点像黑客。 我实际上找到了另一种解决方法:***.com/questions/19441236/…。显得优雅一些。不过感谢您的回复! @mchangun 在文件的行数等于 nrows 的某个倍数时失败——您读取最后一个完整块,然后尝试读取零行。 对于那些只是来这里快速获取代码并运行的人,请注意您可能想要删除的skip=17 ;)

以上是关于R:循环处理大数据集(GB)的块?的主要内容,如果未能解决你的问题,请参考以下文章

sparkR处理Gb级数据集

用 ff 处理大数据

如何处理大型但不是大数据的数据集?

加快R中大数据的for循环处理时间

在 R 中处理大型数据集

将非常大的 CSV 数据集加载到 Python 和 R 中,Pandas 陷入困境