% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/future_eapply.R, R/future_lapply.R,
%   R/future_replicate.R, R/future_sapply.R, R/future_tapply.R,
%   R/future_vapply.R
\name{future_eapply}
\alias{future_eapply}
\alias{future_lapply}
\alias{future_replicate}
\alias{future_sapply}
\alias{future_tapply}
\alias{future_vapply}
\title{Apply a Function over a List or Vector via Futures}
\usage{
future_eapply(
  env,
  FUN,
  ...,
  all.names = FALSE,
  USE.NAMES = TRUE,
  future.envir = parent.frame(),
  future.label = "future_eapply-\%d"
)

future_lapply(
  X,
  FUN,
  ...,
  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_lapply-\%d"
)

future_replicate(
  n,
  expr,
  simplify = "array",
  future.seed = TRUE,
  ...,
  future.envir = parent.frame(),
  future.label = "future_replicate-\%d"
)

future_sapply(
  X,
  FUN,
  ...,
  simplify = TRUE,
  USE.NAMES = TRUE,
  future.envir = parent.frame(),
  future.label = "future_sapply-\%d"
)

future_tapply(
  X,
  INDEX,
  FUN = NULL,
  ...,
  default = NA,
  simplify = TRUE,
  future.envir = parent.frame(),
  future.label = "future_tapply-\%d"
)

future_vapply(
  X,
  FUN,
  FUN.VALUE,
  ...,
  USE.NAMES = TRUE,
  future.envir = parent.frame(),
  future.label = "future_vapply-\%d"
)
}
\arguments{
\item{env}{An \R environment.}

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

\item{all.names}{If \code{TRUE}, the function will also be applied to variables
that start with a period (\code{.}), otherwise not.
See \code{\link[base:eapply]{base::eapply()}} for details.}

\item{USE.NAMES}{See \code{\link[base:lapply]{base::sapply()}}.}

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

\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{X}{An \R object for which a \code{\link[base]{split}} method
exists.  Typically vector-like, allowing subsetting with
\code{\link[base]{[}}, or a data frame.}

\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{n}{The number of replicates.}

\item{expr}{An \R expression to evaluate repeatedly.}

\item{simplify}{See \code{\link[base:lapply]{base::sapply()}} and \code{\link[base:tapply]{base::tapply()}}, respectively.}

\item{INDEX}{A list of one or more factors, each of same length as \code{X}.
The elements are coerced to \code{\link[base]{factor}}s by
\code{\link[base:as.factor]{as.factor()}}. Can also be a formula, which
is useful if \code{X} is a data frame; see the \code{f} argument in
\code{\link[base:split]{split()}} for interpretation.}

\item{default}{See \code{\link[base:tapply]{base::tapply()}}.}

\item{FUN.VALUE}{A template for the required return value from
each \code{FUN(X[ii], ...)}.
Types may be promoted to a higher type within the ordering
logical < integer < double < complex, but not demoted.
See \code{\link[base:lapply]{base::vapply()}} for details.}

\item{\ldots}{(optional) Additional arguments passed to \code{FUN()}.
For \code{future_*apply()} functions and \code{replicate()}, any \verb{future.*} arguments
part of \verb{\\ldots} are passed on to \code{future_lapply()} used internally.}
}
\value{
A named (unless \code{USE.NAMES = FALSE}) list.
See \code{\link[base:eapply]{base::eapply()}} for details.

For \code{future_lapply()}, a list with same length and names as \code{X}.
See \code{\link[base:lapply]{base::lapply()}} for details.

\code{future_replicate()} is a wrapper around \code{future_sapply()} and return
simplified object according to the \code{simplify} argument.
See \code{\link[base:lapply]{base::replicate()}} for details.
Since \code{future_replicate()} usually involves random number generation (RNG),
it uses \code{future.seed = TRUE} by default in order produce sound random
numbers regardless of future backend and number of background workers used.

For \code{future_sapply()}, a vector with same length and names as \code{X}.
See \code{\link[base:lapply]{base::sapply()}} for details.

\code{future_tapply()} returns an array with mode \code{"list"}, unless
\code{simplify = TRUE} (default) \emph{and} \code{FUN} returns a scalar, in which
case the mode of the array is the same as the returned scalars.
See \code{\link[base:tapply]{base::tapply()}} for details.

For \code{future_vapply()}, a vector with same length and names as \code{X}.
See \code{\link[base:lapply]{base::vapply()}} for details.
}
\description{
\code{future_lapply()} implements \code{\link[base:lapply]{base::lapply()}} using futures with perfect
replication of results, regardless of future backend used.
Analogously, this is true for all the other \code{future_nnn()} functions.
}
\section{Global variables}{

Argument \code{future.globals} may be used to control how globals
should be handled similarly how the \code{globals} argument is used with
\code{future()}.
Since all function calls use the same set of globals, this function can do
any gathering of globals upfront (once), which is more efficient than if
it would be done for each future independently.
If \code{TRUE} (default), then globals are automatically identified and gathered.
If a character vector of names is specified, then those globals are gathered.
If a named list, then those globals are used as is.
In all cases, \code{FUN} and any \verb{\\ldots} arguments are automatically
passed as globals to each future created as they are always needed.
}

\section{Reproducible random number generation (RNG)}{

Unless \code{future.seed} is \code{FALSE} or \code{NULL}, this function guarantees to
generate the exact same sequence of random numbers \emph{given the same initial
seed / RNG state} - this regardless of type of futures, scheduling
("chunking") strategy, and number of workers.

RNG reproducibility is achieved by pregenerating the random seeds for all
iterations (over \code{X}) by using L'Ecuyer-CMRG RNG streams.  In each
iteration, these seeds are set before calling \code{FUN(X[[ii]], ...)}.
\emph{Note, for large \code{length(X)} this may introduce a large overhead.}

If \code{future.seed = TRUE}, then \code{\link[base:Random]{.Random.seed}}
is used if it holds a L'Ecuyer-CMRG RNG seed, otherwise one is created
randomly.

If \code{future.seed = FALSE}, it is expected that none of the
\code{FUN(X[[ii]], ...)} function calls use random number generation.
If they do, then an informative warning or error is produces depending
on settings. See \link[future:future]{future::future} for more details.
Using \code{future.seed = NULL}, is like \code{future.seed = FALSE} but without
the check whether random numbers were generated or not.

As input, \code{future.seed} may also take a fixed initial seed (integer),
either as a full L'Ecuyer-CMRG RNG seed (vector of 1+6 integers), or
as a seed generating such a full L'Ecuyer-CMRG seed. This seed will
be used to generated \code{length(X)} L'Ecuyer-CMRG RNG streams.

In addition to the above, it is possible to specify a pre-generated
sequence of RNG seeds as a list such that
\code{length(future.seed) == length(X)} and where each element is an
integer seed vector that can be assigned to
\code{\link[base:Random]{.Random.seed}}.  One approach to generate a
set of valid RNG seeds based on fixed initial seed (here \code{42L}) is:

\if{html}{\out{<div class="sourceCode r">}}\preformatted{seeds <- future_lapply(seq_along(X), FUN = function(x) .Random.seed,
                       future.chunk.size = Inf, future.seed = 42L)
}\if{html}{\out{</div>}}

\strong{Note that \code{as.list(seq_along(X))} is \emph{not} a valid set of such
\code{.Random.seed} values.}

In all cases but \code{future.seed = FALSE} and \code{NULL}, the RNG state of the
calling R processes after this function returns is guaranteed to be
"forwarded one step" from the RNG state that was before the call and
in the same way regardless of \code{future.seed}, \code{future.scheduling}
and future strategy used.  This is done in order to guarantee that an \R
script calling \code{future_lapply()} multiple times should be numerically
reproducible given the same initial seed.
}

\section{Control processing order of elements}{

Attribute \code{ordering} of \code{future.chunk.size} or \code{future.scheduling} can
be used to control the ordering the elements are iterated over, which
only affects the processing order and \emph{not} the order values are returned.
This attribute can take the following values:
\itemize{
\item index vector - an numeric vector of length \code{length(X)}
\item function     - an function taking one argument which is called as
\code{ordering(length(X))} and which must return an
index vector of length \code{length(X)}, e.g.
\code{function(n) rev(seq_len(n))} for reverse ordering.
\item \code{"random"}   - this will randomize the ordering via random index
vector \code{sample.int(length(X))}.
For example, \code{future.scheduling = structure(TRUE, ordering = "random")}.
\emph{Note}, when elements are processed out of order, then captured standard
output and conditions are also relayed in that order, that is out of order.
}
}

\examples{
## ---------------------------------------------------------
## lapply(), sapply(), tapply()
## ---------------------------------------------------------
x <- list(a = 1:10, beta = exp(-3:3), logic = c(TRUE, FALSE, FALSE, TRUE))
y0 <- lapply(x, FUN = quantile, probs = 1:3/4)
y1 <- future_lapply(x, FUN = quantile, probs = 1:3/4)
print(y1)
stopifnot(all.equal(y1, y0))

y0 <- sapply(x, FUN = quantile)
y1 <- future_sapply(x, FUN = quantile)
print(y1)
stopifnot(all.equal(y1, y0))

y0 <- vapply(x, FUN = quantile, FUN.VALUE = double(5L))
y1 <- future_vapply(x, FUN = quantile, FUN.VALUE = double(5L))
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

plan(multisession)
set.seed(0xBEEF)
y1 <- future_lapply(1:5, FUN = rnorm, future.seed = TRUE)
str(y1)

plan(sequential)
set.seed(0xBEEF)
y2 <- future_lapply(1:5, FUN = rnorm, future.seed = TRUE)
str(y2)

stopifnot(all.equal(y1, y2))
}


## ---------------------------------------------------------
## Process chunks of data.frame rows in parallel
## ---------------------------------------------------------
iris <- datasets::iris
chunks <- split(iris, seq(1, nrow(iris), length.out = 3L))
y0 <- lapply(chunks, FUN = function(iris) sum(iris$Sepal.Length))
y0 <- do.call(sum, y0)
y1 <- future_lapply(chunks, FUN = function(iris) sum(iris$Sepal.Length))
y1 <- do.call(sum, y1)
print(y1)
stopifnot(all.equal(y1, y0))


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