create_progress_bar in recursive functions in R

183 views Asked by At

I'm trying to improve the log of a recursive functions of mine that splits the vector input in pages and call itself for each page for doing stuff.

To do so, I'd like to use the progress_bar wrapper provided by the plyr package. Here's a reproducible example:

ric <- function(v, .progress = create_progress_bar("text")){

  f <- rep(seq_len(ceiling(length(v) / 10)), each = 10,length.out = length(v))
  chunks <- split(v, f = f)

  if(length(chunks) > 1){
    .progress$init(length(v))
    do.call(cbind,
            lapply(chunks, function(single.chunk) {
              ric(v = single.chunk, .progress = .progress)

            })
    )

  } else {

    lapply(v, function(item) {

      tryCatch(.progress$step(), error = .progress$init(length(v)))
      #.progress$step()

      return(item)
      })

  }

}

a <- ric(v = seq(1:1340))

The idea is that if the step() function fails it means that we're in the first iteration of a single.chunk execution, so I need to init() the bar first.

But for some reason the tryCatch seems always to fail and init() the bar even if it should already be set. I'm totally puzzled for that..

PS I know the output from single vs multi chunks is different, but it doesn't matter for the purpose of the example

1

There are 1 answers

1
BrodieG On

I haven't tried to mess with your code, but one problem almost certainly is that the value of the error parameter to tryCatch is supposed to be a function, not an unquoted expression. Consider:

tryCatch(TRUE, error=cat("hello\n"))
# hello
# [1] TRUE

vs:

tryCatch(TRUE, error=function(e) cat("hello\n"))
# [1] TRUE
tryCatch(stop("boom"), error=function(e) cat("hello\n"))
# "hello"

R under some circumstances evaluates the function arguments (including this one), so in this case the expression cat("hello\n") is evaluated when the tryCatch line is called, irrespective of whether an error happens or not.

You could also just use the simpler try:

if(inherits(try(.progress$step(), silent=T), "try-error") .progress$init(length(v))