Search code examples
rpurrrr-packagecran

Using a progress bar with pmap for a function that can go in package on CRAN


I am trying to write a function that will download different vectors and combine them to return a data frame. I am using pmap() in the purrr package to loop through each of the vectors. I want to add a progress bar, from the progress package, to show the end user the progress of the data frame. This is possible using the <<- as suggested in the package Read Me...

A simplified version of the code:

library(tidyverse)
library(progress)

f_one_col <- function(x, m, s){
  d <- tibble(i = rnorm(n = 5, mean = m, sd = s))
  names(d) <- x
  # slow things down to check if the progress bar is appearing
  Sys.sleep(1)
  pb$tick()
  return(d)
} 

f <- function(d){
  pb <<- progress_bar$new(total = nrow(d))
  pb$tick(0)
  d$col <- pmap(.l = d, .f = f_one_col)
  pb$terminate() 
  rm(pb, envir = .GlobalEnv)
  return(bind_cols(d$col))
}

d0 <- tibble(
  x = c("a", "b", "c"),
  m = c(10, 20, 30),
  s = c(5, 200, 1000)
)
f(d = d0)
# # A tibble: 5 x 3
#        a     b      c
#    <dbl> <dbl>  <dbl>
# 1  6.50   70.8 -1071.
# 2  3.51  -52.0  -542.
# 3  3.76  369.   -351.
# 4 11.4   171.   1745.
# 5  0.421 111.   1886.

But when i come to putting the function into my R package I get an ERROR in the build check...

no visible binding for '<<-' assignment to 'pb'

and from what I have read so far, using <<- seems to be a no no for CRAN. Is there any other way to use a progress bar without having to use <<- or a hacky way to allow <<- in a package?


Solution

  • Avoid having to use <<- by placing the helper function (f_one_col()) directly in the pmap() function.

    ... and use pmap_dfc() rather than pmap() and bind_cols()

    f <- function(d){
      pb <- progress_bar$new(total = nrow(d))
      pb$tick(0)
      pmap_dfc(
        .l = d, 
        .f = function(x, m, s){
          d <- tibble(i = rnorm(n = 5, mean = m, sd = s))
          names(d) <- x
          pb$tick()
          Sys.sleep(0.5)
          return(d)
        })
    }