【问题标题】:progress bar for non-loop functions非循环函数的进度条
【发布时间】:2019-01-22 03:26:41
【问题描述】:

我目前正在大型数据集上运行一些函数,每个操作都需要很长时间才能执行。

要查看我的计算进度,打印完成计算的迭代次数/百分比会很方便。使用循环,这可以很容易地完成。

但是,是否有可能对矢量化函数或预定义函数进行类似的工作,而无需实际更改这些函数的源代码?

示例数据:

generate_string 取自这里:Generating Random Strings

generate_string <- function(n = 5000) {
a <- do.call(paste0, replicate(5, sample(LETTERS, n, TRUE), FALSE))
paste0(a, sprintf("%04d", sample(9999, n, TRUE)), sample(LETTERS, n, TRUE))
}
x <- generate_string(10000)
y <- generate_string(10000)

要监控的示例函数:

(即打印完成的百分比):

library(stringdist)
# amatch will find for each element in x the index of the most similar element in y
ind <- amatch(x,y, method = "jw", maxDist = 1)

【问题讨论】:

  • 所以你想分发一个你无法控制的任务,当它“闭门造车”工作时,不打断它,让它向你报告它的进展情况?
  • 完全正确(如果可能的话......)
  • 我正在考虑使用promises 将工作发送到处理器中,然后不时对其执行 ping 操作以查看是否完成。这不是进度条,但它表明该过程是实时的或至少仍在计算中。有兴趣看看是否有机会为您无权访问的功能实现进度条。
  • @RomanLuštrik 我目前唯一的想法是将数据简单地拆分为几个块并将函数与一些进度信息一起应用于每个块,但我希望有一些更优雅的解决方案。
  • 用声音代替进度条怎么样? beepr 可以发出声音,同时您不必看着屏幕做其他事情。当然你不会知道你在哪里使用这个程序。

标签: r performance


【解决方案1】:

pbapply 是一个选项,但比直接调用要慢:

system.time({ind <- amatch(x,y, method = "jw", maxDist = 1)})
   user  system elapsed 
  27.79    0.05    9.72 

library(pbapply)
ind <- pbsapply(x, function(xi) amatch(xi,y, method = "jw", maxDist = 1))
 |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 30s

此外,您注释的选项(将数据拆分成块)不太优雅但速度更快,而且很容易并行化。

library(progress)
system.time({
nloops <- 20
pp <- floor(nloops * (0:(length(x)-1))/length(x)) + 1
ind <- c()
pb <- progress_bar$new(total = nloops)
for(i in 1:nloops) {
  pb$tick()
  ind <- c(ind, amatch(x[pp == i],y, method = "jw", maxDist = 1))
}
pb$terminate()
})
[===================================================================================] 100%
   user  system elapsed 
  25.96    0.06    9.21 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多