`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"
)
```

- X
an array, including a matrix.

- MARGIN
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.- FUN
A function taking at least one argument.

- simplify
a logical indicating whether results should be simplified if possible.

- future.envir
An environment passed as argument

`envir`

to`future::future()`

as-is.- future.stdout
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.- future.conditions
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.- future.globals
A logical, a character vector, or a named list for controlling how globals are handled. For details, see below section.

- future.packages
(optional) a character vector specifying packages to be attached in the R environment evaluating the future.

- future.seed
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.- future.scheduling
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`

.- future.chunk.size
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.- future.label
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))
# }
# \dontshow{
## R CMD check: make sure any open connections are closed afterward
if (!inherits(plan(), "sequential")) plan(sequential)
# }
```