| Title: | Parallelize Common Functions via One Magic Function |
|---|---|
| Description: | The futurize() function turns sequential map-reduce functions such as base::lapply(), purrr::map(), 'foreach::foreach() %do% { ... }' into concurrent alternatives, providing you with a simple, straightforward path to scalable parallel computing via the 'future' ecosystem <doi:10.32614/RJ-2021-048>. By combining this transpiler function with R's native pipe operator, you have a convenient way for speeding up iterative computations with minimal refactoring, e.g. 'lapply(xs, fcn) |> futurize()', 'purrr::map(xs, fcn) |> futurize()', and 'foreach::foreach(x = xs) %do% { fcn(x) } |> futurize()'. Other map-reduce packages that can be "futurized" are 'BiocParallel', 'plyr', 'crossmap', 'pbapply' packages. There is also support for a growing set of domain-specific packages on CRAN (e.g. 'boot', 'caret', 'DiceKriging', 'ez', 'fgsea', 'fwb', 'gamlss', 'glmmTMB', 'glmnet', 'kernelshap', 'lme4', 'metafor', 'mgcv', 'modelsummary', 'parameters', 'partykit', 'pls', 'pvclust', 'riskRegression', 'rugarch', 'sandwich', 'seriation', 'shapr', 'Sim.DiffProc', 'SimDesign', 'stars', 'strucchange', 'SuperLearner', 'tm', 'TSP', and 'vegan') and on Bioconductor (e.g. 'DESeq2', 'GenomicAlignments', 'GSVA', 'Rsamtools', 'scater', 'scuttle', 'SingleCellExperiment', and 'sva'). |
| Authors: | Henrik Bengtsson [aut, cre, cph] (ORCID: <https://orcid.org/0000-0002-7579-5165>) |
| Maintainer: | Henrik Bengtsson <[email protected]> |
| License: | Apache License (>= 2) |
| Version: | 1.0.0 |
| Built: | 2026-06-12 17:59:28 UTC |
| Source: | https://github.com/cran/futurize |
futurize( expr, substitute = TRUE, options = futurize_options(...), ..., when = TRUE, eval = TRUE, envir = parent.frame() )futurize( expr, substitute = TRUE, options = futurize_options(...), ..., when = TRUE, eval = TRUE, envir = parent.frame() )
expr |
An R expression, typically a function call to futurize. If FALSE, then futurization is disabled, and if TRUE, it is re-enabled. |
substitute |
If TRUE, argument |
options, ...
|
Named options, passed to |
when |
If TRUE (default), the expression is futurized, otherwise not. |
eval |
If TRUE (default), the futurized expression is evaluated, otherwise it is returned. |
envir |
The environment from where global objects should be identified. |
Returns the value of the evaluated expression expr.
If expr is TRUE or FALSE, then a logical is returned indicating
whether futurization was previously enabled or disabled.
The transpilation mechanism includes logic to "unwrap" expressions
enclosed in constructs such as !, { }, ( ), local(), I(),
identity(), invisible(), suppressMessages(), suppressWarnings(),
and with(). The transpiler descends through wrapping
constructs until it finds a transpilable expression, avoiding the
need to place futurize() inside such constructs. This allows for
patterns like:
y <- {
lapply(xs, fcn)
} |> suppressMessages() |> futurize()
avoiding having to write:
y <- {
lapply(xs, fcn) |> futurize()
} |> suppressMessages()
It is possible to control whether futurization should take place at run-time. For example,
y <- lapply(xs, fun) |> futurize(when = { length(xs) >= 10 })
will be futurized, unless length(xs) is less than ten, in which case it is
evaluated as:
y <- lapply(xs, fun)
It is possible to globally disable the effect of all futurize() calls
by calling futurize(FALSE). The effect is as if futurize() was never
applied. For example,
futurize(FALSE) y <- lapply(xs, fun) |> futurize()
evaluates as:
y <- lapply(xs, fun)
To re-enable futurization, call futurize(TRUE).
Please note that it is only the end-user that may control whether
futurization should be disabled and enabled. A package must never
disable or enable futurization.
To see which CRAN and Bioconductor packages are supported, use
futurize_supported_packages().
To see which functions a specific package supports, use
futurize_supported_functions().
xs <- list(1, 1:2, 1:2, 1:5) # ------------------------------------------ # Base R apply functions # ------------------------------------------ # Sequential lapply() y <- lapply(X = xs, FUN = function(x) { sum(x) }) # Parallel version y <- lapply(X = xs, FUN = function(x) { sum(x) }) |> futurize() str(y) # ------------------------------------------ # purrr map-reduce functions with pipes # ------------------------------------------ if (require("purrr") && requireNamespace("furrr", quietly = TRUE)) { # Sequential map() y <- xs |> map(sum) # Parallel version y <- xs |> map(sum) |> futurize() str(y) } ## if (require ...) # ------------------------------------------ # foreach map-reduce functions # ------------------------------------------ if (require("foreach") && requireNamespace("doFuture", quietly = TRUE)) { # Sequential foreach() y <- foreach(x = xs) %do% { sum(x) } # Parallel version y <- foreach(x = xs) %do% { sum(x) } |> futurize() str(y) # Sequential times() y <- times(3) %do% rnorm(1) str(y) # Parallel version y <- times(3) %do% rnorm(1) |> futurize() str(y) } ## if (require ...) # ------------------------------------------ # plyr map-reduce functions # ------------------------------------------ if (require("plyr") && requireNamespace("doFuture", quietly = TRUE)) { # Sequential llply() y <- llply(xs, sum) # Parallel version y <- llply(xs, sum) |> futurize() str(y) } ## if (require ...)xs <- list(1, 1:2, 1:2, 1:5) # ------------------------------------------ # Base R apply functions # ------------------------------------------ # Sequential lapply() y <- lapply(X = xs, FUN = function(x) { sum(x) }) # Parallel version y <- lapply(X = xs, FUN = function(x) { sum(x) }) |> futurize() str(y) # ------------------------------------------ # purrr map-reduce functions with pipes # ------------------------------------------ if (require("purrr") && requireNamespace("furrr", quietly = TRUE)) { # Sequential map() y <- xs |> map(sum) # Parallel version y <- xs |> map(sum) |> futurize() str(y) } ## if (require ...) # ------------------------------------------ # foreach map-reduce functions # ------------------------------------------ if (require("foreach") && requireNamespace("doFuture", quietly = TRUE)) { # Sequential foreach() y <- foreach(x = xs) %do% { sum(x) } # Parallel version y <- foreach(x = xs) %do% { sum(x) } |> futurize() str(y) # Sequential times() y <- times(3) %do% rnorm(1) str(y) # Parallel version y <- times(3) %do% rnorm(1) |> futurize() str(y) } ## if (require ...) # ------------------------------------------ # plyr map-reduce functions # ------------------------------------------ if (require("plyr") && requireNamespace("doFuture", quietly = TRUE)) { # Sequential llply() y <- llply(xs, sum) # Parallel version y <- llply(xs, sum) |> futurize() str(y) } ## if (require ...)
Some futures require specific resources and capabilities (e.g., RNG, packages, and globals) in order to be evaluated. These can be declared via this function. In addition, this function can control how futures are evaluated, including what is collected from futures (e.g., standard output and conditions). It can also control how future are scheduled, including how a set of futures are partitioned (e.g. chunking).
futurize_options( seed = FALSE, globals = TRUE, packages = NULL, stdout = TRUE, conditions = "condition", scheduling = 1, chunk_size = NULL, ... )futurize_options( seed = FALSE, globals = TRUE, packages = NULL, stdout = TRUE, conditions = "condition", scheduling = 1, chunk_size = NULL, ... )
seed |
(resource; optional) If TRUE, the random seed, that is, the
state of the random number generator (RNG) will be set such that
statistically sound random numbers are produced (also during
parallelization).
If FALSE (default), it is assumed that the future expression neither
needs nor uses random number generation.
To use a fixed random seed, specify a L'Ecuyer-CMRG seed (seven integers)
or a regular RNG seed (a single integer). If the latter, then a
L'Ecuyer-CMRG seed will be automatically created based on the given seed.
Furthermore, if FALSE, then the future will be monitored to make sure it
does not use random numbers. If it does and depending on the value of
option future.rng.onMisuse, the check is
ignored, an informative warning, or error will be produced.
If |
globals |
(resource; optional) a logical, a character vector, or
a named list to control how globals are handled.
For details, see section 'Globals used by future expressions'
in the help for |
packages |
(resource; optional) a character vector specifying
packages to be attached in the R environment evaluating the future,
in addition to packages required by global variables specified or
identified via argument |
stdout |
(evaluation) If TRUE (default), then the standard output is
captured, and re-outputted when |
conditions |
(evaluation) A character string of condition classes to
be captured and relayed. The default is to relay all conditions,
including messages and warnings. To drop all conditions, use
|
scheduling |
(scheduling) Average number of futures ("chunks") per
worker.
If |
chunk_size |
(scheduling) The average number of elements per future
("chunk").
If |
... |
Additional named options. |
A named list of future options.
Attribute specified is a character vector of future options
that were explicitly specified.
# Default futurize options str(futurize_options())# Default futurize options str(futurize_options())
List packages and functions supporting futurization
futurize_supported_packages() futurize_supported_functions(package)futurize_supported_packages() futurize_supported_functions(package)
package |
A package name. |
A character vector of package or function names.
futurize_supported_functions() produces an error if packages
required by the futurize transpiler are not installed.
pkgs <- futurize_supported_packages() pkgs if (requireNamespace("future.apply")) { fcns <- futurize_supported_functions("base") print(fcns) } if (requireNamespace("doFuture")) { fcns <- futurize_supported_functions("foreach") print(fcns) }pkgs <- futurize_supported_packages() pkgs if (requireNamespace("future.apply")) { fcns <- futurize_supported_functions("base") print(fcns) } if (requireNamespace("doFuture")) { fcns <- futurize_supported_functions("foreach") print(fcns) }
Below are the R options and environment variables that are used by the
futurize package and packages enhancing it.
WARNING: Note that the names and the default values of these options may
change in future versions of the package. Please use with care until
further notice.
Just like for other R options, as a package developer you must not change
any of the below futurize.* options. Only the end-user should set these.
If you find yourself having to tweak one of the options, make sure to
undo your changes immediately afterward.
(logical) If TRUE, extensive debug messages are generated. (Default: FALSE)
(logical) If TRUE (default),
futurize() transpilation will be applied, otherwise not.
All of the above R futurize.* options can be set by corresponding
environment variable R_FUTURIZE_* when the futurize package is
loaded. This means that those environment variables must be set before
the futurize package is loaded in order to have an effect.
For example, if R_FUTURIZE_DEBUG=true, then option
futurize.debug is set to TRUE (logical).
To set R options or environment variables when R starts (even before the futurize package is loaded), see the Startup help page. The startup package provides a friendly mechanism for configuring R's startup process.