% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/future_apply.R
\name{future_apply}
\alias{future_apply}
\title{Apply Functions Over Array Margins via Futures}
\usage{
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"
)
}
\arguments{
\item{X}{an array, including a matrix.}

\item{MARGIN}{A vector giving the subscripts which the function will be
applied over. For example, for a matrix \code{1} indicates rows, \code{2} indicates
columns, \code{c(1, 2)} indicates rows and columns.
Where \code{X} has named dimnames, it can be a character vector selecting
dimension names.}

\item{FUN}{A function taking at least one argument.}

\item{simplify}{a logical indicating whether results should be simplified
if possible.}

\item{future.envir}{An \link{environment} passed as argument \code{envir} to
\code{\link[future:future]{future::future()}} as-is.}

\item{future.stdout}{If \code{TRUE} (default), then the standard output of the
underlying futures is captured, and re-outputted as soon as possible.
If \code{FALSE}, any output is silenced (by sinking it to the null device
as it is outputted).
If \code{NA} (not recommended), output is \emph{not} intercepted.}

\item{future.conditions}{A character string of conditions classes to be
captured and relayed.  The default is the same as the \code{condition}
argument of \code{\link[future:Future-class]{future::Future()}}.
To not intercept conditions, use \code{conditions = character(0L)}.
Errors are always relayed.}

\item{future.globals}{A logical, a character vector, or a named list for
controlling how globals are handled. For details, see below section.}

\item{future.packages}{(optional) a character vector specifying packages
to be attached in the R environment evaluating the future.}

\item{future.seed}{A logical or an integer (of length one or seven),
or a list of \code{length(X)} with pre-generated random seeds.
For details, see below section.}

\item{future.scheduling}{Average number of futures ("chunks") per worker.
If \code{0.0}, then a single future is used to process all elements
of \code{X}.
If \code{1.0} or \code{TRUE}, then one future per worker is used.
If \code{2.0}, then each worker will process two futures
(if there are enough elements in \code{X}).
If \code{Inf} or \code{FALSE}, then one future per element of
\code{X} is used.
Only used if \code{future.chunk.size} is \code{NULL}.}

\item{future.chunk.size}{The average number of elements per future ("chunk").
If \code{Inf}, then all elements are processed in a single future.
If \code{NULL}, then argument \code{future.scheduling} is used.}

\item{future.label}{If a character string, then each future is assigned
a label \code{sprintf(future.label, chunk_idx)}.  If TRUE, then the
same as \code{future.label = "future_lapply-\%d"}.  If FALSE, no labels
are assigned.}

\item{\ldots}{(optional) Additional arguments passed to \code{FUN()}, except
\verb{future.*} arguments, which are passed on to \code{\link[=future_lapply]{future_lapply()}} used
internally.}
}
\value{
Returns a vector or array or list of values obtained by applying a
function to margins of an array or matrix.
See \code{\link[base:apply]{base::apply()}} for details.
}
\description{
\code{future_apply()} implements \code{\link[base:apply]{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.
}
\examples{
## ---------------------------------------------------------
## 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)
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)
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)

plan(sequential)
set.seed(0xBEEF)
Y2 <- future_apply(X, MARGIN = 1L, FUN = sample, future.seed = TRUE)
print(Y2)

stopifnot(all.equal(Y1, Y2))
}

\dontshow{
## R CMD check: make sure any open connections are closed afterward
if (!inherits(plan(), "sequential")) plan(sequential)
}
}
\author{
The implementations of \code{future_apply()} is adopted from the source code
of the corresponding base \R function, which is licensed under GPL (>= 2)
with 'The R Core Team' as the copyright holder.
}
