繁体   English   中英

如何在 R 中为数据加载创建进度条?

[英]How do I create a progress bar for data loading in R?

是否可以使用load()为加载到 R 的数据创建进度条?

对于数据分析项目,大型矩阵正在从.RData 文件加载到 R 中,这需要几分钟才能加载。 我想要一个进度条来监控加载数据之前需要多长时间。 R 已经集成了不错的进度条功能,但 load() 没有用于监控已读取数据量的挂钩。 如果我不能直接使用负载,有没有间接的方法可以创建这样一个进度条? 也许将 .RData 文件加载到卡盘中并将它们放在一起以用于 R。 有没有人对此有任何想法或建议?

我想出了以下解决方案,它适用于小于 2^32 - 1 字节的文件大小。

R object 需要序列化并保存到文件中,如下代码所示。

saveObj <- function(object, file.name){
    outfile <- file(file.name, "wb")
    serialize(object, outfile)
    close(outfile)
}

然后我们以块的形式读取二进制数据,跟踪读取了多少并相应地更新进度条。

loadObj <- function(file.name){
    library(foreach)
    filesize <- file.info(file.name)$size
    chunksize <- ceiling(filesize / 100)
    pb <- txtProgressBar(min = 0, max = 100, style=3)
    infile <- file(file.name, "rb")
    data <- foreach(it = icount(100), .combine = c) %do% {
        setTxtProgressBar(pb, it)
        readBin(infile, "raw", chunksize)
    }
    close(infile)
    close(pb)
    return(unserialize(data))
}

代码可以如下运行:

> a <- 1:100000000
> saveObj(a, "temp.RData")
> b <- loadObj("temp.RData")
  |======================================================================| 100%
> all.equal(b, a)
[1] TRUE

如果我们将进度条方法与读取单个块中的文件进行基准测试,我们会看到进度条方法稍微慢一些,但还不足以担心。

> system.time(unserialize(readBin(infile, "raw", file.info("temp.RData")$size)))
   user  system elapsed
  2.710   0.340   3.062
> system.time(b <- loadObj("temp.RData"))
  |======================================================================| 100%
   user  system elapsed
  3.750   0.400   4.154

因此,虽然上述方法有效,但由于文件大小的限制,我觉得它完全没用。 进度条仅对需要很长时间才能读入的大文件有用。

如果有人能想出比这个解决方案更好的东西,那就太好了!

我是否可以建议加快加载(和保存)时间,以便不需要进度条? 如果读取一个矩阵“快速”,那么您可能会报告每个读取矩阵之间的进度(如果您有很多)。

这里有一些测量。 通过简单地设置compress=FALSE,加载速度加倍。 但是通过编写一个简单的矩阵串行器,加载速度几乎快了 20 倍。

x <- matrix(runif(1e7), 1e5) # Matrix with 100k rows and 100 columns

system.time( save('x', file='c:/foo.bin') ) # 13.26 seconds
system.time( load(file='c:/foo.bin') ) # 2.03 seconds

system.time( save('x', file='c:/foo.bin', compress=FALSE) ) # 0.86 seconds
system.time( load(file='c:/foo.bin') ) # 0.92 seconds

system.time( saveMatrix(x, 'c:/foo.bin') ) # 0.70 seconds
system.time( y <- loadMatrix('c:/foo.bin') ) # 0.11 seconds !!!
identical(x,y)

其中 saveMatrix/loadMatrix 定义如下。 他们目前不处理 dimnames 和其他属性,但可以轻松添加。

saveMatrix <- function(m, fileName) {
    con <- file(fileName, 'wb')
    on.exit(close(con))
    writeBin(dim(m), con)
    writeBin(typeof(m), con)
    writeBin(c(m), con)
}

loadMatrix <- function(fileName) {
    con <- file(fileName, 'rb')
    on.exit(close(con))
    d <- readBin(con, 'integer', 2)
    type <- readBin(con, 'character', 1)
    structure(readBin(con, type, prod(d)), dim=d)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM