Di seguito è riportato un MWE del mio problema: ho programmato una barra di avanzamento per alcune funzioni utilizzando il bootstrap (tramite la funzione di avvio dal pacchetto di avvio).txtProgressBar per bootstrap parallelo non visualizzato correttamente
Questo funziona bene finché non utilizzo l'elaborazione parallela (res_1core
di seguito). Se desidero utilizzare l'elaborazione parallela impostando parallel = "multicore"
e ncpus = 2
, la barra di avanzamento non viene visualizzata correttamente (res_2core
di seguito).
library(boot)
rsq <- function(formula, data, R, parallel = c("no", "multicore", "snow"), ncpus = 1) {
env <- environment()
counter <- 0
progbar <- txtProgressBar(min = 0, max = R, style = 3)
bootfun <- function(formula, data, indices) {
d <- data[indices,]
fit <- lm(formula, data = d)
curVal <- get("counter", envir = env)
assign("counter", curVal + 1, envir = env)
setTxtProgressBar(get("progbar", envir = env), curVal + 1)
return(summary(fit)$r.square)
}
res <- boot(data = data, statistic = bootfun, R = R, formula = formula, parallel = parallel, ncpus = ncpus)
return(res)
}
res_1core <- rsq(mpg ~ wt + disp, data = mtcars, R = 1000)
res_2core <- rsq(mpg ~ wt + disp, data = mtcars, R = 1000, parallel = "multicore", ncpus = 2)
Ho letto che questo è legato al fatto che la funzione di avvio invita lapply
per singolo core e mclapply
per l'elaborazione multicore. Qualcuno sa di una soluzione facile per affrontare questo? Voglio dire, vorrei mostrare i progressi tenendo conto di tutti i processi paralleli.
Aggiornamento
Grazie all'ingresso di Karolis Koncevičius, ho trovato una soluzione alternativa (basta utilizzare la versione aggiornata di rsq
funzione qui sotto):
rsq <- function(formula, data, R, parallel = c("no", "multicore", "snow"), ncpus = 1) {
bootfun <- function(formula, data, indices) {
d <- data[indices,]
fit <- lm(formula, data = d)
return(summary(fit)$r.square)
}
env <- environment()
counter <- 0
progbar <- txtProgressBar(min = 0, max = R, style = 3)
flush.console()
intfun <- function(formula, data, indices) {
curVal <- get("counter", envir = env) + ncpus
assign("counter", curVal, envir = env)
setTxtProgressBar(get("progbar", envir = env), curVal)
bootfun(formula, data, indices)
}
res <- boot(data = data, statistic = intfun, R = R, formula = formula, parallel = parallel, ncpus = ncpus)
return(res)
}
Purtroppo, questo funziona solo per l'elaborazione multicore quando Eseguo R dal terminale. Qualche idea su come applicare la patch in modo che venga visualizzata correttamente anche in R console o Rstudio?
non è sorprendente che questo è difficile - che avrebbe dovuto costituire un 'ascoltatore' di qualche tipo per ricevere i messaggi di avanzamento dei singoli lavoratori ... –
Per quanto riguarda 'mclapply', che viene chiamato da' boot' quando 'parallel = 'multicore'':" È fortemente sconsigliato usare queste funzioni nella GUI o negli ambienti embedded, perché porta a diversi processi che condividono la stessa GUI che probabilmente causerà il caos (e probabilmente si blocca). " https://stat.ethz.ch/R-manual/R-devel/library/parallel/html/mclapply.html – Thomas
Grazie! Non avevo letto questa raccomandazione prima. – johansteen