Skip to content

Instantly share code, notes, and snippets.

@cszang
Last active February 14, 2023 13:31
Show Gist options
  • Save cszang/1199b4fc77ba205a531cfc987f09e74f to your computer and use it in GitHub Desktop.
Save cszang/1199b4fc77ba205a531cfc987f09e74f to your computer and use it in GitHub Desktop.
A progressbar that fits into a dplyr::mutate -> purrr::map* pipeline
library(rlang)
library(tidyr)
library(dplyr)
library(purrr)
spawn_progressbar <- function(x, .name = .pb, .times = 1) {
.name <- substitute(.name)
n <- nrow(x) * .times
eval(substitute(.name <<- dplyr::progress_estimated(n)))
x
}
## make function to be map'ed accept progressbar as argument and
## update on call
slow_mean <- function(x, .var, .pb) {
Sys.sleep(1)
.pb$tick()$print()
.var <- rlang::enexpr(.var)
mean(x[[.var]])
}
## setting up and updating progressbar is now part of the pipeline;
## it's default name is .pb
mtcars %>%
dplyr::group_by(carb) %>%
tidyr::nest() %>%
spawn_progressbar() %>%
dplyr::mutate(mean_qsec = purrr::map_dbl(data, slow_mean, qsec, .pb))
## this means we can have multiple sequential progress bars, like so:
mtcars %>%
dplyr::group_by(carb) %>%
tidyr::nest() %>%
spawn_progressbar(.pb_qsec) %>%
spawn_progressbar(.pb_disp) %>%
dplyr::mutate(mean_qsec = purrr::map_dbl(data, slow_mean, qsec, .pb_qsec),
mean_disp = purrr::map_dbl(data, slow_mean, disp, .pb_disp))
## or one progress bar for all computations by knowing the number of
## calls to map* in advance, like so:
mtcars %>%
dplyr::group_by(carb) %>%
tidyr::nest() %>%
spawn_progressbar(.times = 2) %>%
dplyr::mutate(mean_qsec = purrr::map_dbl(data, slow_mean, qsec, .pb),
mean_disp = purrr::map_dbl(data, slow_mean, disp, .pb))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment