本质上是添加了另一个版本的@fotNelson的解决方案,但做了一些修改:
- 支持所有mclapply函数的快速替换
- 捕获ctrl-c调用并优雅地中止
- 使用内置进度条(txtProgressBar)
- 选择是否跟踪进度、使用指定样式的进度条选项
- 使用
parallel
而不是已从CRAN中删除的multicore
- 按照mclapply将X强制转换为列表(因此length(X)可以得到预期结果)
- 顶部采用roxygen2风格的文档
希望对其他人有所帮助...
library(parallel)
mclapply2 <- function(X, FUN, ...,
mc.preschedule = TRUE, mc.set.seed = TRUE,
mc.silent = FALSE, mc.cores = getOption("mc.cores", 2L),
mc.cleanup = TRUE, mc.allow.recursive = TRUE,
mc.progress=TRUE, mc.style=3)
{
if (!is.vector(X) || is.object(X)) X <- as.list(X)
if (mc.progress) {
f <- fifo(tempfile(), open="w+b", blocking=T)
p <- parallel:::mcfork()
pb <- txtProgressBar(0, length(X), style=mc.style)
setTxtProgressBar(pb, 0)
progress <- 0
if (inherits(p, "masterProcess")) {
while (progress < length(X)) {
readBin(f, "double")
progress <- progress + 1
setTxtProgressBar(pb, progress)
}
cat("\n")
parallel:::mcexit()
}
}
tryCatch({
result <- mclapply(X, ..., function(...) {
res <- FUN(...)
if (mc.progress) writeBin(1, f)
res
},
mc.preschedule = mc.preschedule, mc.set.seed = mc.set.seed,
mc.silent = mc.silent, mc.cores = mc.cores,
mc.cleanup = mc.cleanup, mc.allow.recursive = mc.allow.recursive
)
}, finally = {
if (mc.progress) close(f)
})
result
}
package multicore
不再可用,有没有不使用multicore
包的解决方法? - forecasterparallel
包。 - fotNeltonparallel::parSapply
,可以看一下我编写的一个包,用于跟踪并行执行的任务进度。您可以在这里找到它。 - Mihai