R/apply.R
vecvec_mapply.RdThe vecvec_mapply() function applies a function .f across the
vectors in .l, combining the results into a vecvec that preserves the
original (possibly heterogeneous) type of each element of any vecvec
inputs. Unlike mapply()/Map(), .f is not called once per logical
element - it is called once per contiguous run of positions that draw
from the same combination of underlying storage slots across every
vector in .l (the same slot-grouping used internally for
Ops.vecvec::vecvec, e.g. +/==). Each call therefore receives one
vector per element of .l (that group's values) rather than one scalar
per element of .l, so .f must itself be vectorised - an ordinary
operator or vectorised function (e.g. +, paste0) qualifies
automatically, but .f must return a result the same length as its
inputs, or vecvec_mapply() errors.
vecvec_mapply(.l, .f, ..., ptype = NULL, SIMPLIFY = !is.null(ptype))A list of vectors to apply .f over. Elements of .l may be
vecvec objects or plain vectors; plain vectors are treated as if
wrapped with vecvec(). All vectors in .l are recycled to a common
size following vctrs::vec_recycle_common() rules.
A vectorised function, applied once per group of positions
that share the same underlying storage slots across every vector in
.l. Called with one vector per element of .l (that group's values)
plus ....
Additional arguments passed to every call of .f.
A prototype to simplify the result to with unvecvec(). If
NULL and SIMPLIFY is TRUE, the common type is inferred from the
result as in unvecvec().
If TRUE, unvecvec() is applied to the result, using
ptype as the target type. If FALSE, the result is always a vecvec
object.
A vecvec object combining the results of calling .f on each
group of positions of .l, or (if SIMPLIFY is TRUE) that result
simplified to a single type with unvecvec(). Positions where any
input has a missing (NA) index form their own group and are not
passed to .f at all - they come back as NA directly, matching how
missing elements are treated elsewhere (e.g. vecvec_apply(), [<-,
is.na<-).
Because the number of calls to .f scales with the number of distinct
slot combinations rather than with length(.l[[1]]), this is cheap for
structured or replicated inputs (few distinct slot combinations) and
degrades toward one call per element only in the worst case (every
position drawing from a different combination of slots) - the same cost
profile as vecvec_apply() and Ops.vecvec::vecvec, and unlike a plain
mapply()/Map() call, which always calls .f once per element.
vecvec_apply() for the single-input equivalent, applying .f
once per underlying storage vector of a single vecvec.
Ops.vecvec::vecvec uses the same slot-grouping strategy for
arithmetic/comparison operators.