{"id":21128800,"url":"https://github.com/futureverse/progressr","last_synced_at":"2025-12-12T01:05:20.283Z","repository":{"id":46118586,"uuid":"180921189","full_name":"futureverse/progressr","owner":"futureverse","description":"三 R package: An Inclusive, Unifying API for Progress Updates","archived":false,"fork":false,"pushed_at":"2025-04-19T16:49:25.000Z","size":3108,"stargazers_count":293,"open_issues_count":44,"forks_count":11,"subscribers_count":6,"default_branch":"develop","last_synced_at":"2025-05-03T01:01:13.770Z","etag":null,"topics":["conditions","package","progress","r"],"latest_commit_sha":null,"homepage":"https://progressr.futureverse.org","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/futureverse.png","metadata":{"files":{"readme":"README.md","changelog":"NEWS.md","contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-04-12T03:12:33.000Z","updated_at":"2025-04-29T00:33:37.000Z","dependencies_parsed_at":"2023-12-12T17:56:58.766Z","dependency_job_id":"0ee4aff3-4173-486e-814b-2ccd4a08dc3e","html_url":"https://github.com/futureverse/progressr","commit_stats":{"total_commits":688,"total_committers":6,"mean_commits":"114.66666666666667","dds":0.04505813953488369,"last_synced_commit":"eb8cb1fd95644c1712f36ead93ff1a45e59df3dd"},"previous_names":["futureverse/progressr","henrikbengtsson/progressr"],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/futureverse%2Fprogressr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/futureverse%2Fprogressr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/futureverse%2Fprogressr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/futureverse%2Fprogressr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/futureverse","download_url":"https://codeload.github.com/futureverse/progressr/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254037252,"owners_count":22003781,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["conditions","package","progress","r"],"created_at":"2024-11-20T05:02:51.028Z","updated_at":"2025-12-12T01:05:20.277Z","avatar_url":"https://github.com/futureverse.png","language":"R","readme":"\n\n\u003cdiv id=\"badges\"\u003e\u003c!-- pkgdown markup --\u003e\n\u003ca href=\"https://CRAN.R-project.org/web/checks/check_results_progressr.html\"\u003e\u003cimg border=\"0\" src=\"https://www.r-pkg.org/badges/version/progressr\" alt=\"CRAN check status\"/\u003e\u003c/a\u003e \u003ca href=\"https://github.com/futureverse/progressr/actions?query=workflow%3AR-CMD-check\"\u003e\u003cimg border=\"0\" src=\"https://github.com/futureverse/progressr/actions/workflows/R-CMD-check.yaml/badge.svg?branch=develop\" alt=\"R CMD check status\"/\u003e\u003c/a\u003e \u003ca href=\"https://github.com/futureverse/progressr/actions?query=workflow%3Arevdepcheck-top\"\u003e\u003cimg border=\"0\" src=\"https://github.com/futureverse/progressr/actions/workflows/revdepcheck-top.yaml/badge.svg?branch=develop\" alt=\"Top reverse-dependency checks status\"/\u003e\u003c/a\u003e    \u003ca href=\"https://app.codecov.io/gh/futureverse/progressr\"\u003e\u003cimg border=\"0\" src=\"https://codecov.io/gh/futureverse/progressr/branch/develop/graph/badge.svg\" alt=\"Coverage Status\"/\u003e\u003c/a\u003e \u003ca href=\"https://lifecycle.r-lib.org/articles/stages.html\"\u003e\u003cimg border=\"0\" src=\"man/figures/lifecycle-maturing-blue.svg\" alt=\"Life cycle: maturing\"/\u003e\u003c/a\u003e\n\u003c/div\u003e\n\n# progressr: An Inclusive, Unifying API for Progress Updates \n\nThe **[progressr]** package provides a minimal API for reporting\nprogress updates in [R](https://www.r-project.org/).  The design is to\nseparate the representation of progress updates from how they are\npresented.  What type of progress to signal is controlled by the\ndeveloper.  How these progress updates are rendered is controlled by\nthe end user.  For instance, some users may prefer visual feedback\nsuch as a horizontal progress bar in the terminal, whereas others may\nprefer auditory feedback.  The **[progressr]** framework is designed\nto work out-of-the-box also with parallel and distributed processing,\nespecially with the **[futureverse]** ecosystem.\n\n\u003cimg src=\"vignettes/imgs/three_in_chinese.gif\" alt=\"Three strokes writing three in Chinese\" style=\"float: right; margin-right: 1ex; margin-left: 1ex;\"/\u003e\n\nDesign motto:\n\n\u003e The developer is responsible for providing progress updates but it's\n\u003e only the end user who decides if, when, and how progress should be\n\u003e presented. No exceptions will be allowed.\n\n\n## Two Minimal APIs - One For Developers and One For End-Users\n\n\u003cdiv style=\"overflow: hidden\"\u003e\n\u003cdiv style=\"float: left\"\u003e\n\u003ctable style=\"border: 1px solid #999; box-shadow: 2px 2px 2px #999;\"\u003e\n\u003ctr\u003e\u003cth\u003eDeveloper's API\u003c/th\u003e\u003c/tr\u003e\n\u003ctr style=\"vertical-align: top\"\u003e\n\u003ctd\u003e\n\u003cp\u003e\n1. Set up a progressor with a certain number of steps:\n\u003c/p\u003e\n\u003cpre\u003e\np \u0026lt;- progressor(nsteps)\np \u0026lt;- progressor(along = x)\n\u003c/pre\u003e\n\n\u003cp\u003e\n2. Signal progress:\n\u003c/p\u003e\n\n\u003cpre\u003e\np()               # one-step progress\np(amount = 0)     # \"still alive\"\np(\"loading ...\")  # pass on a message\n\u003c/pre\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\u003c/div\u003e\n\u003cdiv style=\"float: left\"\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u003c/div\u003e\n\u003cdiv style=\"float: left\"\u003e\n\u003ctable style=\"border: 1px solid #999; box-shadow: 2px 2px 2px #999;\"\u003e\n\u003ctr\u003e\u003cth\u003eEnd-user's API\u003c/th\u003e\u003c/tr\u003e\n\u003ctr style=\"vertical-align: top\"\u003e\n\u003ctd\u003e\n\u003cp\u003e\n1a. Subscribe to progress updates from everywhere:\n\u003c/p\u003e\n\n\u003cpre\u003e\nhandlers(global = TRUE)\n\ny \u0026lt;- slow_sum(1:5)\ny \u0026lt;- slow_sum(6:10)\n\u003c/pre\u003e\n\n\u003cp\u003e\n1b. Subscribe to a specific expression:\n\u003c/p\u003e\n\n\u003cpre\u003e\nwith_progress({\n  y \u0026lt;- slow_sum(1:5)\n  y \u0026lt;- slow_sum(6:10)\n})\n\u003c/pre\u003e\n\n\u003cp\u003e\n2. Configure how progress is presented:\n\u003c/p\u003e\n\n\u003cpre\u003e\nhandlers(\"progress\")\nhandlers(\"txtprogressbar\", \"beepr\")\nhandlers(handler_pbcol(enable_after = 3.0))\nhandlers(handler_progress(complete = \"#\"))\n\u003c/pre\u003e\n\u003c/td\u003e\n\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\n## A simple example\n\nAssume that we have a function `slow_sum()` for adding up the values\nin a vector.  It is so slow, that we like to provide progress updates\nto whoever might be interested in it.  With the **progressr** package,\nthis can be done as:\n\n```r\nslow_sum \u003c- function(x) {\n  p \u003c- progressr::progressor(along = x)\n  sum \u003c- 0\n  for (kk in seq_along(x)) {\n    Sys.sleep(0.1)\n    sum \u003c- sum + x[kk]\n    p(message = sprintf(\"Adding %g\", x[kk]))\n  }\n  sum\n}\n```\n\nNote how there are _no_ arguments (e.g. `.progress = TRUE`) in the\ncode that specify how progress is presented. This is by design and\nbecause the only task for the developer is to decide on where in the\ncode it makes sense to signal that progress has been made. As we will\nsee next, it should be up to the end user, and end user only, of this\ncode to decide whether they want to receive progress updates or not,\nand, if so, in what format. Asking them to specify a special\n\"progress\" argument adds a lot of friction, it clutters up the code,\nand, importantly, might not even be possible for end users to do\n(e.g. they call a package function that in turn calls the progress\nreporting function of interest).\n\nNow, if we call this function, without further settings:\n\n```r\n\u003e y \u003c- slow_sum(1:10)\n\u003e y\n[1] 55\n\u003e\n``` \n\nthe default is that there will be _no_ progress updates. To get\nprogress updates, we need to request them to be \"handled\", which we do\nby:\n\n```r\n\u003e progressr::handlers(global = TRUE)\n```\n\nAfter this, progress will be reported;\n\n```r\n\u003e y \u003c- slow_sum(1:10)\n  |====================                               |  40%\n\u003e y \u003c- slow_sum(10:1)\n  |========================================           |  80%\n```\n\nTo disable reporting again, do:\n\n```r\n\u003e handlers(global = FALSE)\n```\n\n\n## Customizing how progress is reported\n\nBy default, **[progressr]** presents progress via the built-in\n`utils::txtProgressBar()`. It presents itself as a rudimentary\nASCII-based horizontal progress bar in the R terminal. See\n`help(\"handler_txtprogressbar\")` for how to customize the look of\n\"txtprogressbar\", e.g. colorization and Unicode.  There are many other\nways to report on progress, including visually, auditory, and via\nnotification systems. You can also use a mix of these, e.g.\n\n```r\nhandlers(c(\"cli\", \"beepr\", \"ntfy\"))\n```\n\nSee the 'Customizing How Progress is Reported' vignette for for examples.\n\n\n## Additional Features\n\n### Support for progressr elsewhere\n\nNote that progression updates by **progressr** is designed to work out\nof the box for any iterator framework in R. See the different package\nvignettes for details. Prominent examples are:\n\n * `lapply()` etc. of base R\n * `map()` etc. by the **[purrr]** package\n * `llply()` etc. by the **[plyr]** package\n * `foreach()` iterations by the **[foreach]** package\n\nand near-live progress reporting in parallel and distributed\nprocessing via the **[future]** framework:\n\n * `future_lapply()` etc.  by the **[future.apply]** package\n * `future_map()` etc. by the **[furrr]** package\n * `llply()` etc. by the **[plyr]** and **[doFuture]** packages\n * `foreach()` iterations via the **foreach** and **[doFuture]** packages\n * `bplapply()` etc. by the **[BiocParallel]** and **[doFuture]** packages\n\nOther uses of **progressr** are:\n\n * make packages that report progress via the **[cli]** package\n   (e.g. **purrr**) report progress via **progressr**\n * make `knit()` of the **[knitr]** package report via **progressr**\n\n\n### Use regular output as usual alongside progress updates\n\nIn contrast to other progress-bar frameworks, output from `message()`,\n`cat()`, `print()` and so on, will _not_ interfere with progress\nreported via **progressr**.  For example, say we have:\n\n```r\nslow_sqrt \u003c- function(xs) {\n  p \u003c- progressor(along = xs)\n  lapply(xs, function(x) {\n    message(\"Calculating the square root of \", x)\n    Sys.sleep(2)\n    p(sprintf(\"x=%g\", x))\n    sqrt(x)\n  })\n}\n```\n\nwe will get:\n\n```r\n\u003e library(progressr)\n\u003e handlers(global = TRUE)\n\u003e handlers(\"progress\")\n\u003e y \u003c- slow_sqrt(1:8)\nCalculating the square root of 1\nCalculating the square root of 2\n- [===========\u003e-----------------------------------]  25% x=2\n```\n\nThis works because **progressr** will briefly buffer any output\ninternally and only release it when the next progress update is\nreceived just before the progress is re-rendered in the terminal.\nThis is why you see a two second delay when running the above example.\nNote that, if we use progress handlers that do not output to the\nterminal, such as `handlers(\"beepr\")`, then output does not have to be\nbuffered and will appear immediately.\n\n\n_Comment_: When signaling a warning using `warning(msg, immediate. =\nTRUE)` the message is immediately outputted to the standard-error\nstream.  However, this is not possible to emulate when warnings are\nintercepted using calling handlers.  This is a limitation of R that\ncannot be worked around.  Because of this, the above call will behave\nthe same as `warning(msg)` - that is, all warnings will be buffered by\nR internally and released only when all computations are done.\n\n\n### Sticky messages\n\nAs seen above, some progress handlers present the progress message as\npart of its output, e.g. the \"progress\" handler will display the\nmessage as part of the progress bar.  It is also possible to \"push\"\nthe message up together with other terminal output.  This can be done\nby adding class attribute `\"sticky\"` to the progression signaled.\nThis works for several progress handlers that output to the terminal.\nFor example, with:\n\n```r\nslow_sum \u003c- function(x) {\n  p \u003c- progressr::progressor(along = x)\n  sum \u003c- 0\n  for (kk in seq_along(x)) {\n    Sys.sleep(0.1)\n    sum \u003c- sum + x[kk]\n    p(sprintf(\"Step %d\", kk), class = if (kk %% 5 == 0) \"sticky\", amount = 0)\n    p(message = sprintf(\"Adding %g\", x[kk]))\n  }\n  sum\n}\n```\n\nwe get\n\n```r\n\u003e handlers(\"txtprogressbar\")\n\u003e y \u003c- slow_sum(1:30)\nStep 5\nStep 10\n  |====================                               |  43%\n```\n\nand\n\n```r\n\u003e handlers(\"progress\")\n\u003e y \u003c- slow_sum(1:30)\nStep 5\nStep 10\n/ [===============\u003e-------------------------]  43% Adding 13\n```\n\n\n\n[futureverse]: https://www.futureverse.org\n[progressr]: https://progressr.futureverse.org\n[future]: https://future.futureverse.org\n[future.apply]: https://future.apply.futureverse.org\n[furrr]: https://furrr.futureverse.org\n[doFuture]: https://doFuture.futureverse.org\n[beepr]: https://cran.r-project.org/package=beepr\n[cli]: https://cran.r-project.org/package=cli\n[foreach]: https://cran.r-project.org/package=foreach\n[progress]: https://cran.r-project.org/package=progress\n[purrr]: https://cran.r-project.org/package=purrr\n[doParallel]: https://cran.r-project.org/package=doParallel\n[knitr]: https://cran.r-project.org/package=knitr\n[pbapply]: https://cran.r-project.org/package=pbapply\n[pbmcapply]: https://cran.r-project.org/package=pbmcapply\n[plyr]: https://cran.r-project.org/package=plyr\n[BiocParallel]: https://www.bioconductor.org/packages/BiocParallel/\n\n## Installation\nR package progressr is available on [CRAN](https://cran.r-project.org/package=progressr) and can be installed in R as:\n```r\ninstall.packages(\"progressr\")\n```\n\n\n### Pre-release version\n\nTo install the pre-release version that is available in Git branch `develop` on GitHub, use:\n```r\nremotes::install_github(\"futureverse/progressr\", ref=\"develop\")\n```\nThis will install the package from source.  \n\n\u003c!-- pkgdown-drop-below --\u003e\n\n\n## Contributing\n\nTo contribute to this package, please see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n","funding_links":[],"categories":["R"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffutureverse%2Fprogressr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffutureverse%2Fprogressr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffutureverse%2Fprogressr/lists"}