exl*_*exl 41 foreach r progress-bar
有关如何在R程序中创建循环计数器的一些信息性帖子.但是,在使用带有"foreach()"的并行化版本时,如何创建类似的功能?
thi*_*e1e 42
编辑:在更新 doSNOW软件包之后,在使用时显示一个很好的进度条变得非常简单%dopar%
,它可以在Linux,Windows和OS X上运行
doSNOW
现在通过.options.snow
参数正式支持进度条.
library(doSNOW)
cl <- makeCluster(2)
registerDoSNOW(cl)
iterations <- 100
pb <- txtProgressBar(max = iterations, style = 3)
progress <- function(n) setTxtProgressBar(pb, n)
opts <- list(progress = progress)
result <- foreach(i = 1:iterations, .combine = rbind,
.options.snow = opts) %dopar%
{
s <- summary(rnorm(1e6))[3]
return(s)
}
close(pb)
stopCluster(cl)
Run Code Online (Sandbox Code Playgroud)
另一种跟踪进度的方法,如果你记住迭代的总数,就要设置.verbose = T
为这将打印到控制台哪些迭代已经完成.
以前的Linux和OS X解决方案
在Ubuntu 14.04(64位)和OS X(El Capitan)上,即使%dopar%
在makeCluster
功能oufile = ""
设置中使用if,也会显示进度条.它似乎不适用于Windows.从帮助makeCluster
:
outfile:从工作者那里引导stdout和stderr连接输出的位置.""表示没有重定向(这可能仅对本地计算机上的工作人员有用).默认为'/ dev/null'(Windows上为'nul:').
示例代码:
library(foreach)
library(doSNOW)
cl <- makeCluster(4, outfile="") # number of cores. Notice 'outfile'
registerDoSNOW(cl)
iterations <- 100
pb <- txtProgressBar(min = 1, max = iterations, style = 3)
result <- foreach(i = 1:iterations, .combine = rbind) %dopar%
{
s <- summary(rnorm(1e6))[3]
setTxtProgressBar(pb, i)
return(s)
}
close(pb)
stopCluster(cl)
Run Code Online (Sandbox Code Playgroud)
这就是进度条的样子.它看起来有点奇怪,因为每个条形图都会打印一个新的条形图,因为工作人员可能会滞后一点,导致进度条偶尔会来回走动.
此代码是doRedis示例的修改版本,即使在使用%dopar%
并行后端时也会生成进度条:
#Load Libraries
library(foreach)
library(utils)
library(iterators)
library(doParallel)
library(snow)
#Choose number of iterations
n <- 1000
#Progress combine function
f <- function(){
pb <- txtProgressBar(min=1, max=n-1,style=3)
count <- 0
function(...) {
count <<- count + length(list(...)) - 1
setTxtProgressBar(pb,count)
Sys.sleep(0.01)
flush.console()
c(...)
}
}
#Start a cluster
cl <- makeCluster(4, type='SOCK')
registerDoParallel(cl)
# Run the loop in parallel
k <- foreach(i = icount(n), .final=sum, .combine=f()) %dopar% {
log2(i)
}
head(k)
#Stop the cluster
stopCluster(cl)
Run Code Online (Sandbox Code Playgroud)
您必须提前知道迭代次数和组合函数.
现在可以使用该parallel
包.在OSX 10.11上使用R 3.2.3进行测试,在RStudio中运行,使用"PSOCK"
-type集群.
library(doParallel)
# default cluster type on my machine is "PSOCK", YMMV with other types
cl <- parallel::makeCluster(4, outfile = "")
registerDoParallel(cl)
n <- 10000
pb <- txtProgressBar(0, n, style = 2)
invisible(foreach(i = icount(n)) %dopar% {
setTxtProgressBar(pb, i)
})
stopCluster(cl)
Run Code Online (Sandbox Code Playgroud)
奇怪的是,它只能正确显示style = 3
.
您可以Sys.time()
在循环之前保存开始时间.循环遍历行或列或您知道总数的内容.然后,在循环内部,您可以计算到目前为止的时间(参见difftime
),完成百分比,速度和估计剩余时间.每个进程都可以使用该message
函数打印这些进度线.你会得到类似的输出
1/1000 complete @ 1 items/s, ETA: 00:00:45
2/1000 complete @ 1 items/s, ETA: 00:00:44
Run Code Online (Sandbox Code Playgroud)
显然循环顺序将极大地影响它的工作效果.不知道foreach
,但与multicore
的mclapply
你会用得到很好的效果mc.preschedule=FALSE
,这意味着项目被分配给进程一个接一个,以便为以前的项目完成.
小智 5
您也可以将此与progress
软件包一起使用。
# loading parallel and doSNOW package and creating cluster ----------------
library(parallel)
library(doSNOW)
numCores<-detectCores()
cl <- makeCluster(numCores)
registerDoSNOW(cl)
# progress bar ------------------------------------------------------------
library(progress)
iterations <- 100 # used for the foreach loop
pb <- progress_bar$new(
format = "letter = :letter [:bar] :elapsed | eta: :eta",
total = iterations, # 100
width = 60)
progress_letter <- rep(LETTERS[1:10], 10) # token reported in progress bar
# allowing progress bar to be used in foreach -----------------------------
progress <- function(n){
pb$tick(tokens = list(letter = progress_letter[n]))
}
opts <- list(progress = progress)
# foreach loop ------------------------------------------------------------
library(foreach)
foreach(i = 1:iterations, .combine = rbind, .options.snow = opts) %dopar% {
summary(rnorm(1e6))[3]
}
stopCluster(cl)
Run Code Online (Sandbox Code Playgroud)