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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。