[英]How to use purrr::map (not to be iterated) additional arguments?
我以為我已經了解如何使用purrr::map
的附加 arguments 參數( ...
)。 這是一些代碼,希望能說明purrr::map
的(對我而言)意外行為:
似乎在purrr::map
參數a
作為附加參數傳遞不起作用:
library(purrr)
f <- function(a, b) {
a + b
}
g <- function(a = 0, b) {
a + b
}
map(1:3, .f = ~ f(b = .x, a = 1))
#> [[1]]
#> [1] 2
#>
#> [[2]]
#> [1] 3
#>
#> [[3]]
#> [1] 4
map(1:3, .f = ~ f(b = .x), a = 1)
#> Error in f(b = .x): argument "a" is missing, with no default
map(1:3, .f = ~ g(b = .x, a = 1))
#> [[1]]
#> [1] 2
#>
#> [[2]]
#> [1] 3
#>
#> [[3]]
#> [1] 4
map(1:3, .f = ~ g(b = .x), a = 1)
#> [[1]]
#> [1] 1
#>
#> [[2]]
#> [1] 2
#>
#> [[3]]
#> [1] 3
lapply(1:3, function(b, a = 1) f(a, b))
#> [[1]]
#> [1] 2
#>
#> [[2]]
#> [1] 3
#>
#> [[3]]
#> [1] 4
lapply(1:3, function(b, a) f(a, b), a = 1)
#> [[1]]
#> [1] 2
#>
#> [[2]]
#> [1] 3
#>
#> [[3]]
#> [1] 4
我的問題是為什么代碼:
map(1:3, .f = ~ f(b = .x), a = 1)
拋出錯誤?
我們可以在沒有任何匿名 function 的情況下傳遞剩余的 arguments
library(purrr)
map(1:3, f, a = 1)
#[[1]]
#[1] 2
#[[2]]
#[1] 3
#[[3]]
#[1] 4
或者另一個選項是rlang::as_function
或purrr:as_mapper
map(1:3, as_mapper(f), a = 1)
或動態創建f
map(1:3, as_mapper(~ .x + .y), a = 1)
或者在調用中invoke
它
map(1:3, ~ invoke(f, b = .x, a = 1))
#[[1]]
#[1] 2
#[[2]]
#[1] 3
#[[3]]
#[1] 4
這將使它比.f = ~ f(b =.x), a = 1
更容易閱讀
在幕后, map()
調用 as_mapper() 。 我們可以手動執行此操作以查看發生了什么:
purrr::as_mapper( ~ f(b = .x, a = 1) )
# <lambda>
# function (..., .x = ..1, .y = ..2, . = ..1)
# f(b = .x, a = 1) <----
# attr(,"class")
# [1] "rlang_lambda_function" "function"
purrr::as_mapper( ~ f(b = .x), a=1 )
# <lambda>
# function (..., .x = ..1, .y = ..2, . = ..1)
# f(b = .x) <----
# attr(,"class")
# [1] "rlang_lambda_function" "function"
我強調了與<---
的重要區別。 請注意,在第二種情況下,創建的 lambda function 沒有包含您的額外a=1
參數,這會導致您觀察到的錯誤。
為了解決您的評論, a=1
實際上正在傳遞給 lambda function。 你的 lambda function 只是沒有做任何事情。 要正確合並a
, lambda function 定義需要處理...
點:
g <- function(a, b, ...) {a + b} # ... are needed to catch all extra
# arguments from as_mapper
purrr::as_mapper( .f = ~ g(b=.x, ...) )
# <lambda>
# function (..., .x = ..1, .y = ..2, . = ..1)
# g(b = .x, ...) <-- dots are now forwarded to g()
# attr(,"class")
# [1] "rlang_lambda_function" "function"
purrr::map(1:3, .f = ~ g(b=.x, ...), a=1 ) # a now properly gets passed to g
# [[1]]
# [1] 2
#
# [[2]]
# [1] 3
#
# [[3]]
# [1] 4
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.