Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

三 R package: An Inclusive, Unifying API for Progress Updates

NotificationsYou must be signed in to change notification settings

futureverse/progressr

 
 

Repository files navigation

CRAN check statusR CMD check statusTop reverse-dependency checks statusCoverage StatusLife cycle: maturing

progressr: An Inclusive, Unifying API for Progress Updates

Theprogressr package provides a minimal API for reportingprogress updates inR. The design is toseparate the representation of progress updates from how they arepresented. What type of progress to signal is controlled by thedeveloper. How these progress updates are rendered is controlled bythe end user. For instance, some users may prefer visual feedbacksuch as a horizontal progress bar in the terminal, whereas others mayprefer auditory feedback. Theprogressr framework is designedto work out-of-the-box also with parallel and distributed processing,especially with thefutureverse ecosystem.

Three strokes writing three in Chinese

Design motto:

The developer is responsible for providing progress updates but it'sonly the end user who decides if, when, and how progress should bepresented. No exceptions will be allowed.

Two Minimal APIs - One For Developers and One For End-Users

Developer's API

1. Set up a progressor with a certain number of steps:

p <- progressor(nsteps)p <- progressor(along = x)

2. Signal progress:

p()               # one-step progressp(amount = 0)     # "still alive"p("loading ...")  # pass on a message
    
End-user's API

1a. Subscribe to progress updates from everywhere:

handlers(global = TRUE)y <- slow_sum(1:5)y <- slow_sum(6:10)

1b. Subscribe to a specific expression:

with_progress({  y <- slow_sum(1:5)  y <- slow_sum(6:10)})

2. Configure how progress is presented:

handlers("progress")handlers("txtprogressbar", "beepr")handlers(handler_pbcol(enable_after = 3.0))handlers(handler_progress(complete = "#"))

A simple example

Assume that we have a functionslow_sum() for adding up the valuesin a vector. It is so slow, that we like to provide progress updatesto whoever might be interested in it. With theprogressr package,this can be done as:

slow_sum<-function(x) {p<-progressr::progressor(along=x)sum<-0for (kkin seq_along(x)) {    Sys.sleep(0.1)sum<-sum+x[kk]    p(message= sprintf("Adding %g",x[kk]))  }sum}

Note how there areno arguments (e.g..progress = TRUE) in thecode that specify how progress is presented. This is by design andbecause the only task for the developer is to decide on where in thecode it makes sense to signal that progress has been made. As we willsee next, it should be up to the end user, and end user only, of thiscode to decide whether they want to receive progress updates or not,and, if so, in what format. Asking them to specify a special"progress" argument adds a lot of friction, it clutters up the code,and, importantly, might not even be possible for end users to do(e.g. they call a package function that in turn calls the progressreporting function of interest).

Now, if we call this function, without further settings:

>y<- slow_sum(1:10)>y[1]55>

the default is that there will beno progress updates. To getprogress updates, we need to request them to be "handled", which we doby:

>progressr::handlers(global=TRUE)

After this, progress will be reported;

>y<- slow_sum(1:10)|====================|40%>y<- slow_sum(10:1)|========================================|80%

To disable reporting again, do:

> handlers(global=FALSE)

Customizing how progress is reported

By default,progressr presents progress via the built-inutils::txtProgressBar(). It presents itself as a rudimentaryASCII-based horizontal progress bar in the R terminal. Seehelp("handler_txtprogressbar") for how to customize the look of"txtprogressbar", e.g. colorization and Unicode. There are many otherways to report on progress, including visually, auditory, and vianotification systems. You can also use a mix of these, e.g.

handlers(c("cli","beepr","ntfy"))

See the 'Customizing How Progress is Reported' vignette for for examples.

Additional Features

Support for progressr elsewhere

Note that progression updates byprogressr is designed to work outof the box for any iterator framework in R. See the different packagevignettes for details. Prominent examples are:

  • lapply() etc. of base R
  • map() etc. by thepurrr package
  • llply() etc. by theplyr package
  • foreach() iterations by theforeach package

and near-live progress reporting in parallel and distributedprocessing via thefuture framework:

Other uses ofprogressr are:

  • make packages that report progress via thecli package(e.g.purrr) report progress viaprogressr
  • makeknit() of theknitr package report viaprogressr

Use regular output as usual alongside progress updates

In contrast to other progress-bar frameworks, output frommessage(),cat(),print() and so on, willnot interfere with progressreported viaprogressr. For example, say we have:

slow_sqrt<-function(xs) {p<- progressor(along=xs)  lapply(xs,function(x) {    message("Calculating the square root of",x)    Sys.sleep(2)    p(sprintf("x=%g",x))    sqrt(x)  })}

we will get:

> library(progressr)> handlers(global=TRUE)> handlers("progress")>y<- slow_sqrt(1:8)Calculatingthesquarerootof1Calculatingthesquarerootof2- [===========>-----------------------------------]25%x=2

This works becauseprogressr will briefly buffer any outputinternally and only release it when the next progress update isreceived just before the progress is re-rendered in the terminal.This is why you see a two second delay when running the above example.Note that, if we use progress handlers that do not output to theterminal, such ashandlers("beepr"), then output does not have to bebuffered and will appear immediately.

Comment: When signaling a warning usingwarning(msg, immediate. = TRUE) the message is immediately outputted to the standard-errorstream. However, this is not possible to emulate when warnings areintercepted using calling handlers. This is a limitation of R thatcannot be worked around. Because of this, the above call will behavethe same aswarning(msg) - that is, all warnings will be buffered byR internally and released only when all computations are done.

Sticky messages

As seen above, some progress handlers present the progress message aspart of its output, e.g. the "progress" handler will display themessage as part of the progress bar. It is also possible to "push"the message up together with other terminal output. This can be doneby adding class attribute"sticky" to the progression signaled.This works for several progress handlers that output to the terminal.For example, with:

slow_sum<-function(x) {p<-progressr::progressor(along=x)sum<-0for (kkin seq_along(x)) {    Sys.sleep(0.1)sum<-sum+x[kk]    p(sprintf("Step %d",kk),class=if (kk%%5==0)"sticky",amount=0)    p(message= sprintf("Adding %g",x[kk]))  }sum}

we get

> handlers("txtprogressbar")>y<- slow_sum(1:30)Step5Step10|====================|43%

and

> handlers("progress")>y<- slow_sum(1:30)Step5Step10/ [===============>-------------------------]43%Adding13

Installation

R package progressr is available onCRAN and can be installed in R as:

install.packages("progressr")

Pre-release version

To install the pre-release version that is available in Git branchdevelop on GitHub, use:

remotes::install_github("futureverse/progressr",ref="develop")

This will install the package from source.

Contributing

To contribute to this package, please seeCONTRIBUTING.md.

About

三 R package: An Inclusive, Unifying API for Progress Updates

Topics

Resources

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors5

Languages


[8]ページ先頭

©2009-2025 Movatter.jp