reduce()
是将向量的元素组合成单个值的运算。该组合由 .f
驱动,这是一个采用两个值并返回单个值的二元函数:在 1:3
上减少 f
可计算值 f(f(1, 2), 3)
。
参数
- .x
-
列表或原子向量。
- .f
-
对于
reduce()
,一个 2 参数函数。该函数将传递累积值作为第一个参数,"next" 值作为第二个参数。对于
reduce2()
,一个 3 参数函数。该函数将传递累加值作为第一个参数,.x
的下一个值作为第二个参数,.y
的下一个值作为第三个参数。如果
.f
返回包含在done()
中的值,则缩减会提前终止。 - ...
-
传递给映射函数的附加参数。
我们现在通常建议不要使用
...
将附加(常量)参数传递给.f
。相反,使用简写匿名函数:# Instead of x |> map(f, 1, 2, collapse = ",") # do: x |> map(\(x) f(x, 1, 2, collapse = ","))
这使得更容易理解哪些参数属于哪个函数,并且往往会产生更好的错误消息。
- .init
-
如果提供,将用作开始累加的第一个值,而不是使用
.x[[1]]
。如果您想确保reduce
在.x
为空时返回正确的值,这非常有用。如果丢失,并且.x
为空,将抛出错误。 - .dir
-
作为字符串的缩减方向,
"forward"
(默认)或"backward"
之一。请参阅下面有关方向的部分。 - .y
-
对于
reduce2()
和accumulate2()
,传递给.f
的附加参数。如果未设置init
,则.y
应比.x
短 1 个元素。
方向
当 .f
是像 +
或 c()
这样的关联运算时,减少的方向并不重要。例如,使用二元函数 +
约简向量 1:3
会计算左侧的和 ((1 + 2) + 3)
,以及右侧的相同和 (1 + (2 + 3))
。
在其他情况下,方向对降低的值有重要影响。例如,从左侧减少 list()
向量会产生一个左倾嵌套列表(或树),而从右侧减少 list()
则会产生一个右倾列表。
生命周期
从 purrr 0.3.0 开始,reduce_right()
已被软弃用。请改用reduce()
的.dir
参数。请注意,算法已更改。 reduce_right()
计算 f(f(3, 2), 1)
, reduce(.dir = \"backward\")
计算 f(1, f(2, 3))
。这是从右侧减少的标准方法。
要使用与 reduce_right()
相同的归约更新代码,只需反转向量并使用左归约:
# Before:
reduce_right(1:3, f)
# After:
reduce(rev(1:3), f)
reduce2_right()
自 purrr 0.3.0 起已被软弃用,无需替换。目前尚不清楚在这种情况下正确的归约应具有哪些算法属性。如果您了解使用三元函数进行正确约简的用例,请联系我们。
也可以看看
accumulate()
用于返回归约的所有中间值的版本。
例子
# Reducing `+` computes the sum of a vector while reducing `*`
# computes the product:
1:3 |> reduce(`+`)
#> [1] 6
1:10 |> reduce(`*`)
#> [1] 3628800
# 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)
#> [1] 5.293988
# When the operation is associative, the direction of reduction
# does not matter:
reduce(1:4, `+`)
#> [1] 10
reduce(1:4, `+`, .dir = "backward")
#> [1] 10
# 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))
#> List of 2
#> $ :List of 2
#> ..$ :List of 2
#> .. ..$ : int 1
#> .. ..$ : int 2
#> ..$ : int 3
#> $ : int 4
str(reduce(1:4, list, .dir = "backward"))
#> List of 2
#> $ : int 1
#> $ :List of 2
#> ..$ : int 2
#> ..$ :List of 2
#> .. ..$ : int 3
#> .. ..$ : int 4
# 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)
#> [1] "a.b.c.d"
letters[1:4] |> reduce2(c("-", ".", "-"), paste2)
#> [1] "a-b.c-d"
x <- list(c(0, 1), c(2, 3), c(4, 5))
y <- list(c(6, 7), c(8, 9))
reduce2(x, y, paste)
#> [1] "0 2 6 4 8" "1 3 7 5 9"
# 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)
#> [1] "a.b.c"
# 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)
#> [1] "a.b.c.d.e.f.g.h.i"
相关用法
- R purrr rerun 多次重新运行表达式
- R purrr rbernoulli 从伯努利分布生成随机样本
- R purrr rate-helpers 创建延迟率设置
- R purrr accumulate 累积向量缩减的中间结果
- R purrr imap 将函数应用于向量的每个元素及其索引
- R purrr list_transpose 转置列表
- R purrr as_vector 将列表强制转换为向量
- R purrr map_if 有条件地将函数应用于向量的每个元素
- R purrr map2 映射两个输入
- R purrr array-coercion 强制数组列出
- R purrr auto_browse 包装一个函数,以便在出错时自动 browser()
- R purrr pluck 安全地获取或设置嵌套数据结构深处的元素
- R purrr insistently 将函数转换为等待,然后在错误后重试
- R purrr map_depth 在给定深度映射/修改元素
- R purrr list_simplify 将列表简化为原子或 S3 向量
- R purrr quietly 包装一个函数来捕获副作用
- R purrr list_flatten 压平列表
- R purrr pmap 同时映射多个输入(“并行”)
- R purrr possibly 包装函数以返回值而不是错误
- R purrr head_while 查找全部满足谓词的头/尾。
- R purrr keep_at 根据元素的名称/位置保留/丢弃元素
- R purrr keep 根据元素的值保留/丢弃元素
- R purrr transpose 转置列表。
- R purrr flatten 将列表的列表展平为简单的向量
- R purrr every 列表中的每个元素、部分元素还是没有一个元素满足谓词?
注:本文由纯净天空筛选整理自Hadley Wickham等大神的英文原创作品 Reduce a list to a single value by iteratively applying a binary function。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。