progressr icon indicating copy to clipboard operation
progressr copied to clipboard

Using custom progress tokens with the progress package

Open mattwarkentin opened this issue 4 years ago • 3 comments

Hi @HenrikBengtsson,

I am wondering if you can use custom tokens with progress progress bars. Here is an example (without progressr) of using custom progress tokens:

library(progress)
library(progressr)

pb <- progress_bar$new(
  format = "Custom token: :custom",
  clear = FALSE,
  show_after = 0
)

for (i in 1:10) {
  Sys.sleep(0.5)
  pb$tick(tokens = list(custom = i))
}

And this is my (non-working) attempt to make this work with progressr. It seems like the ... of p() aren't passed on to the progress handler, in this case, progress / pb$tick(...).

handlers(global = TRUE)
handlers(
  handler_progress(
    format = "Custom token: :custom"
  )
)

foo <- function() {
  p <- progressor(10)
  for (i in 1:10) {
    Sys.sleep(0.5)
    p(tokens = list(custom = i))
  }
  x
}
foo()

Is there a way to make this work?

mattwarkentin avatar May 06 '21 20:05 mattwarkentin

This works, but it means you need to format the message on the progressr side and not on the progress side of things, which I think goes against the progressr philosophy that the user should decide the format of the progress updates.

library(progress)
library(progressr)

handlers(global = TRUE)
handlers(
  handler_progress(
    format = ":message"
  )
)

foo <- function() {
  p <- progressor(10)
  for (i in 1:10) {
    Sys.sleep(0.5)
    p(
      message = glue::glue("Custom token: {i}")
    )
  }
}
foo()

mattwarkentin avatar May 06 '21 20:05 mattwarkentin

Hi. In order to support "tokens" we'd have to introduce that concept also in progressr. That is a design decision and not an implementation decision. The current design is minimal in what type of information you can pass in a progression update: (i) the amount of progress, and (ii) an (optional) message.

I'll add it to the list of things to consider, but since it's a matter of design, it's not something that's easy to introduce. For example, such tokens probably have to be standardized, because it'll be the developer who "adds" them and the user who "uses" them, so we don't want some code/packages name a token index and another idx when they mean the same thing.

Do you know if there are any restrictions on progress's tokens of what data types its element may contain in, or can it be anything?

HenrikBengtsson avatar Jul 13 '21 13:07 HenrikBengtsson

Sorry for the late reply, @HenrikBengtsson. As far as I can tell, the only real condition for tokens passed to the tick() method of a progress::progress_bar() is that it is a named list. Looks like whatever you pass as a token gets coerced to a string and possibly truncated if it is too long (or else it shows up as ??? if it can't be coerced).

pb <- progress::progress_bar$new(
  total = 100, 
  format = ":current/:total [:bar] :foo",
  clear = FALSE
)

for (i in 1:100) {
  pb$tick(tokens = list(foo = mtcars))
  Sys.sleep(0.1)
}
100/100 [=] c(21, 21, 22.8, 21.4, 18.7, 18.1, 14.3, 24.4, 22...

mattwarkentin avatar Jul 26 '21 22:07 mattwarkentin