reduce | R Documentation |
reduce()
is an operation that combines the elements of a vector
into a single value. The combination is driven by .f
, a binary
function that takes two values and returns a single value: reducing
f
over 1:3
computes the value f(f(1, 2), 3)
.
reduce(.x, .f, ..., .init, .dir = c("forward", "backward"))
reduce2(.x, .y, .f, ..., .init)
.x |
A list or atomic vector. |
.f |
For For The reduction terminates early if |
... |
Additional arguments passed on to the mapped function. We now generally recommend against using # Instead of x |> map(f, 1, 2, collapse = ",") # do: x |> map(\(x) f(x, 1, 2, collapse = ",")) This makes it easier to understand which arguments belong to which function and will tend to yield better error messages. |
.init |
If supplied, will be used as the first value to start
the accumulation, rather than using |
.dir |
The direction of reduction as a string, one of
|
.y |
For |
When .f
is an associative operation like +
or c()
, the
direction of reduction does not matter. For instance, reducing the
vector 1:3
with the binary function +
computes the sum ((1 + 2) + 3)
from the left, and the same sum (1 + (2 + 3))
from the
right.
In other cases, the direction has important consequences on the
reduced value. For instance, reducing a vector with list()
from
the left produces a left-leaning nested list (or tree), while
reducing list()
from the right produces a right-leaning list.
reduce_right()
is soft-deprecated as of purrr 0.3.0. Please use
the .dir
argument of reduce()
instead. Note that the algorithm
has changed. Whereas reduce_right()
computed f(f(3, 2), 1)
,
reduce(.dir = \"backward\")
computes f(1, f(2, 3))
. This is the
standard way of reducing from the right.
To update your code with the same reduction as reduce_right()
,
simply reverse your vector and use a left reduction:
# Before: reduce_right(1:3, f) # After: reduce(rev(1:3), f)
reduce2_right()
is soft-deprecated as of purrr 0.3.0 without
replacement. It is not clear what algorithmic properties should a
right reduction have in this case. Please reach out if you know
about a use case for a right reduction with a ternary function.
accumulate()
for a version that returns all intermediate
values of the reduction.
# Reducing `+` computes the sum of a vector while reducing `*`
# computes the product:
1:3 |> reduce(`+`)
1:10 |> reduce(`*`)
# By ignoring the input vector (nxt), you can turn output of one step into
# the input for the next. This code takes 10 steps of a random walk:
reduce(1:10, \(acc, nxt) acc + rnorm(1), .init = 0)
# When the operation is associative, the direction of reduction
# does not matter:
reduce(1:4, `+`)
reduce(1:4, `+`, .dir = "backward")
# However with non-associative operations, the reduced value will
# be different as a function of the direction. For instance,
# `list()` will create left-leaning lists when reducing from the
# right, and right-leaning lists otherwise:
str(reduce(1:4, list))
str(reduce(1:4, list, .dir = "backward"))
# reduce2() takes a ternary function and a second vector that is
# one element smaller than the first vector:
paste2 <- function(x, y, sep = ".") paste(x, y, sep = sep)
letters[1:4] |> reduce(paste2)
letters[1:4] |> reduce2(c("-", ".", "-"), paste2)
x <- list(c(0, 1), c(2, 3), c(4, 5))
y <- list(c(6, 7), c(8, 9))
reduce2(x, y, paste)
# You can shortcircuit a reduction and terminate it early by
# returning a value wrapped in a done(). In the following example
# we return early if the result-so-far, which is passed on the LHS,
# meets a condition:
paste3 <- function(out, input, sep = ".") {
if (nchar(out) > 4) {
return(done(out))
}
paste(out, input, sep = sep)
}
letters |> reduce(paste3)
# Here the early return branch checks the incoming inputs passed on
# the RHS:
paste4 <- function(out, input, sep = ".") {
if (input == "j") {
return(done(out))
}
paste(out, input, sep = sep)
}
letters |> reduce(paste4)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.