future_apply() implements base::apply() using future with perfect
replication of results, regardless of future backend used.
It returns a vector or array or list of values obtained by applying a
function to margins of an array or matrix.
future_apply(
X,
MARGIN,
FUN,
...,
simplify = TRUE,
future.envir = parent.frame(),
future.stdout = TRUE,
future.conditions = "condition",
future.globals = TRUE,
future.packages = NULL,
future.seed = FALSE,
future.scheduling = 1,
future.chunk.size = NULL,
future.label = "future_apply-%d"
)an array, including a matrix.
A vector giving the subscripts which the function will be
applied over. For example, for a matrix 1 indicates rows, 2 indicates
columns, c(1, 2) indicates rows and columns.
Where X has named dimnames, it can be a character vector selecting
dimension names.
A function taking at least one argument.
a logical indicating whether results should be simplified if possible.
An environment passed as argument envir to
future::future() as-is.
If TRUE (default), then the standard output of the
underlying futures is captured, and re-outputted as soon as possible.
If FALSE, any output is silenced (by sinking it to the null device
as it is outputted).
If NA (not recommended), output is not intercepted.
A character string of conditions classes to be
captured and relayed. The default is the same as the condition
argument of future::Future().
To not intercept conditions, use conditions = character(0L).
Errors are always relayed.
A logical, a character vector, or a named list for controlling how globals are handled. For details, see below section.
(optional) a character vector specifying packages to be attached in the R environment evaluating the future.
A logical or an integer (of length one or seven),
or a list of length(X) with pre-generated random seeds.
For details, see below section.
Average number of futures ("chunks") per worker.
If 0.0, then a single future is used to process all elements
of X.
If 1.0 or TRUE, then one future per worker is used.
If 2.0, then each worker will process two futures
(if there are enough elements in X).
If Inf or FALSE, then one future per element of
X is used.
Only used if future.chunk.size is NULL.
The average number of elements per future ("chunk").
If Inf, then all elements are processed in a single future.
If NULL, then argument future.scheduling is used.
If a character string, then each future is assigned
a label sprintf(future.label, chunk_idx). If TRUE, then the
same as future.label = "future_lapply-%d". If FALSE, no labels
are assigned.
(optional) Additional arguments passed to FUN(), except
future.* arguments, which are passed on to future_lapply() used
internally.
Returns a vector or array or list of values obtained by applying a
function to margins of an array or matrix.
See base::apply() for details.
## ---------------------------------------------------------
## apply()
## ---------------------------------------------------------
X <- matrix(c(1:4, 1, 6:8), nrow = 2L)
Y0 <- apply(X, MARGIN = 1L, FUN = table)
Y1 <- future_apply(X, MARGIN = 1L, FUN = table)
print(Y1)
#> [[1]]
#> ...future.X_jj
#> 1 3 7
#> 2 1 1
#>
#> [[2]]
#> ...future.X_jj
#> 2 4 6 8
#> 1 1 1 1
#>
stopifnot(all.equal(Y1, Y0, check.attributes = FALSE)) ## FIXME
Y0 <- apply(X, MARGIN = 1L, FUN = stats::quantile)
Y1 <- future_apply(X, MARGIN = 1L, FUN = stats::quantile)
print(Y1)
#> [,1] [,2]
#> 0% 1 2.0
#> 25% 1 3.5
#> 50% 2 5.0
#> 75% 4 6.5
#> 100% 7 8.0
stopifnot(all.equal(Y1, Y0))
## ---------------------------------------------------------
## Parallel Random Number Generation
## ---------------------------------------------------------
# \donttest{
## Regardless of the future plan, the number of workers, and
## where they are, the random numbers produced are identical
X <- matrix(c(1:4, 1, 6:8), nrow = 2L)
plan(multisession)
set.seed(0xBEEF)
Y1 <- future_apply(X, MARGIN = 1L, FUN = sample, future.seed = TRUE)
print(Y1)
#> [,1] [,2]
#> [1,] 3 8
#> [2,] 1 6
#> [3,] 7 2
#> [4,] 1 4
plan(sequential)
set.seed(0xBEEF)
Y2 <- future_apply(X, MARGIN = 1L, FUN = sample, future.seed = TRUE)
print(Y2)
#> [,1] [,2]
#> [1,] 3 8
#> [2,] 1 6
#> [3,] 7 2
#> [4,] 1 4
stopifnot(all.equal(Y1, Y2))
# }