在地图中使用局部
Using partial within map
我遇到了一个有趣的问题。我有一个包含三个变量的函数,假设(为了简单和透明)它是这样的:
my_fun <- function(a, b, c) paste(a, b, c, sep = '-')
我想为 a
和 b
的几种组合创建仅具有参数 c
的多个函数。我正在使用函数 map2
和 partial
(均来自包 purrr
)。
require(purrr)
funs <- map2(letters[1:5], LETTERS[1:5], partial, ...f = my_fun)
我希望函数列表中的每个函数产生不同的输出,但事实并非如此。
funs[[1]]('hi') # [1] "e-E-hi"
funs[[3]]('hi') # [1] "e-E-hi"
funs[[5]]('hi') # [1] "e-E-hi"
我可以为我的问题创建不同的解决方案,所以我的问题不是 "how to do it"。我对它为什么这样做很感兴趣。
另一个使用基数的例子mapply
:
mapply(partial, letters[1:5], LETTERS[1:5], MoreArgs = list(...f = my_fun))[[1]]('hi')
# [1] "e-E-hi"
问题源于 partial
使用惰性求值,在 map2
内意味着它存储 .x
和 .y
而不是 a
和 A
。幸运的是有一个函数参数,我们可以使用:
funs <- map2(letters[1:5], LETTERS[1:5], partial, ...f = my_fun, .lazy = FALSE)
funs[[1]]('hi')
# [1] "a-A-hi"
如果您查看您的版本,我们会看到:
funs[[1]]
# function (...)
# my_fun(.x[[i]], .y[[i]], ...)
# <environment: 0x00000000201d9598>
其他 4 个都一样。
现在,如果我们查看那个环境,我们可以看到:
ls(envir = environment(funs[[1]]))
# [1] "i"
所以那里存储了一个对象i
,它将决定我们得到哪个.x
和.y
,它的值是:
get('i', environment(funs[[1]]))
# [1] 5
另请注意,您的参数也存储在那里,但由于它们以 .
:
开头而被隐藏
ls(envir = environment(funs[[1]]), all.names = TRUE)
# [1] "..." ".f" ".x" ".y" "i"
get('.x', envir = environment(funs[[1]]))
# [1] "a" "b" "c" "d" "e"
所以对于所有这些,我们得到相同的结果。具体来说,执行的调用最终是:
my_fun(letters[1:5][[5]], LETTERS[1:5][[5]], 'hi')
惰性求值在这里不是很好,并且使用了 map2
中存储的内部循环计数器。
我遇到了一个有趣的问题。我有一个包含三个变量的函数,假设(为了简单和透明)它是这样的:
my_fun <- function(a, b, c) paste(a, b, c, sep = '-')
我想为 a
和 b
的几种组合创建仅具有参数 c
的多个函数。我正在使用函数 map2
和 partial
(均来自包 purrr
)。
require(purrr)
funs <- map2(letters[1:5], LETTERS[1:5], partial, ...f = my_fun)
我希望函数列表中的每个函数产生不同的输出,但事实并非如此。
funs[[1]]('hi') # [1] "e-E-hi"
funs[[3]]('hi') # [1] "e-E-hi"
funs[[5]]('hi') # [1] "e-E-hi"
我可以为我的问题创建不同的解决方案,所以我的问题不是 "how to do it"。我对它为什么这样做很感兴趣。
另一个使用基数的例子mapply
:
mapply(partial, letters[1:5], LETTERS[1:5], MoreArgs = list(...f = my_fun))[[1]]('hi')
# [1] "e-E-hi"
问题源于 partial
使用惰性求值,在 map2
内意味着它存储 .x
和 .y
而不是 a
和 A
。幸运的是有一个函数参数,我们可以使用:
funs <- map2(letters[1:5], LETTERS[1:5], partial, ...f = my_fun, .lazy = FALSE)
funs[[1]]('hi')
# [1] "a-A-hi"
如果您查看您的版本,我们会看到:
funs[[1]]
# function (...)
# my_fun(.x[[i]], .y[[i]], ...)
# <environment: 0x00000000201d9598>
其他 4 个都一样。
现在,如果我们查看那个环境,我们可以看到:
ls(envir = environment(funs[[1]]))
# [1] "i"
所以那里存储了一个对象i
,它将决定我们得到哪个.x
和.y
,它的值是:
get('i', environment(funs[[1]]))
# [1] 5
另请注意,您的参数也存储在那里,但由于它们以 .
:
ls(envir = environment(funs[[1]]), all.names = TRUE)
# [1] "..." ".f" ".x" ".y" "i"
get('.x', envir = environment(funs[[1]]))
# [1] "a" "b" "c" "d" "e"
所以对于所有这些,我们得到相同的结果。具体来说,执行的调用最终是:
my_fun(letters[1:5][[5]], LETTERS[1:5][[5]], 'hi')
惰性求值在这里不是很好,并且使用了 map2
中存储的内部循环计数器。