【问题标题】:Monitoring R data loading progress when using read.table [duplicate]使用 read.table 时监控 R 数据加载进度 [重复]
【发布时间】:2011-06-15 19:39:37
【问题描述】:

我找到了很多其他类型数据加载的答案,但没有找到 R 使用 read.table(...) 读取数据时显示进度的答案。我有一个简单的命令:

data = read.table(file=filename,
                sep="\t",
                col.names=c("time","id","x","y"),
                colClasses=c("integer","NULL","NULL","NULL"))

这会在大约 30 秒左右加载大量数据,但进度条会非常好:-D

【问题讨论】:

  • 我认为如果没有对read.table 的深度破解,将很难做到这一点。甚至不清楚read.table 的哪个组件是慢速部分......我会debug() read.table [或使用R 分析],找出它是哪个组件,并尝试在其中嵌入对txtProgressBar 的调用(希望缓慢的部分不会落入C代码中......)
  • 如果它相当复杂并且需要十多分钟,那就不值得了。我有点假设有一种简单的方法让 R 1)计算文件中的行数,2)每次读取一行时更新进度条
  • scanwhat=list(integer(), NULL, NULL, NULL) 可能会(很多)更快?

标签: r progress-bar read.table


【解决方案1】:

继续实验:

构造一个临时工作文件:

n <- 1e7
dd <- data.frame(time=1:n,id=rep("a",n),x=1:n,y=1:n)
fn <- tempfile()
write.table(dd,file=fn,sep="\t",row.names=FALSE,col.names=FALSE)

使用read.table(指定和不指定colClasses)和scan运行10次复制:

编辑:更正scan 响应评论的调用,更新结果:

library(rbenchmark)
(b1 <- benchmark(read.table(fn,
                     col.names=c("time","id","x","y"),
                            colClasses=c("integer",
                              "NULL","NULL","NULL")),
                 read.table(fn,
                            col.names=c("time","id","x","y")),
          scan(fn,
               what=list(integer(),NULL,NULL,NULL)),replications=10))

结果:

2 read.table(fn, col.names = c("time", "id", "x", "y"))
1 read.table(fn, col.names = c("time", "id", "x", "y"), 
      colClasses = c("integer", "NULL", "NULL", "NULL"))
3  scan(fn, what = list(integer(), NULL, NULL, NULL))

  replications elapsed relative user.self sys.self 
2           10 278.064 1.857016   232.786   30.722    
1           10 149.737 1.011801   141.365    2.388  
3           10 143.118 1.000000   140.617    2.105  

(警告,这些值有点熟/不一致,因为我重新运行了基准测试并合并了结果......但定性结果应该没问题)。

没有colClassesread.table 是最慢的(这并不奇怪),但对于这个例子来说,只有(?)比scan 慢大约85%。 scan 只比指定了colClassesread.table 快一点点。

使用scanread.table 可以编写一个“分块”版本,使用skipnrows (read.table) 或n (scan) 参数来读取位一次归档,然后在最后将它们粘贴在一起。我不知道这会减慢多少进程,但它允许在块之间调用txtProgressBar ...

【讨论】:

  • scan 想要list(integer(), NULL, NULL, NULL) 而不是引用字符(否则它将读取四个字符向量)。
  • 实际上,分块版本是fl = file(fn, "r"); while (length(r &lt;- scan(fl, what, nmax)[[1]])) { },例如,nmax=400000。将进度条放入{}
  • 附言。我花费的时间超出了我应该在scan 调用中将这种分块放在read.table 的黑客副本中的时间。然后才意识到添加进度条有问题,就是我们事先不知道文件有多长!这可以通过快速调用wc 在类 Unix 环境中相当快地解决,但这一切开始看起来有点……
猜你喜欢
  • 1970-01-01
  • 2011-05-21
  • 1970-01-01
  • 1970-01-01
  • 2015-10-02
  • 1970-01-01
  • 1970-01-01
  • 2014-04-30
  • 2014-08-17
相关资源
最近更新 更多