将 mutate 与 map2 和 exec 一起使用而不是 invoke_map
Using mutate with map2 and exec instead of invoke_map
“R for Data Science”中的这个示例使用现已停用的 invoke_map
。
sim <- tribble(
~f, ~params,
"runif", list(min = -1, max = 1),
"rnorm", list(sd = 5),
"rpois", list(lambda = 10)
)
sim %>%
mutate(sim = invoke_map(f, params, n = 10))
如果我单独提取列,那么它适用于 map2
和 exec
map2(sim$f, sim$params, function(fn, args) exec(fn, !!!args, n = 10))
但是,我无法让 mutate
与 map2
和 exec
一起工作
sim %>%
mutate(sim = map2(f, params, function(fn, args) exec(fn, !!!args, n = 10)))
我收到错误“错误:无法拼接闭包类型的对象,因为它不是向量”
有人可以帮忙吗?
我认为问题出在 exec
的某个地方,或者更具体地说,是 big-bang (!!!
) 部分,由于某种原因它试图拼接不是你的变量 args
,但函数 base::args
(因此,您收到的错误消息)。您可以尝试将 args
重命名为其他名称,您会得到一个不同的错误:
> sim %>%
mutate(sim = map2(f, params, .f = function(fn, x) {exec(fn, !!!x, n = 10)}))
Error in splice(dot_call(capture_dots, frame_env = frame_env, named = named, :
object 'x' not found
我必须说我还不够深入,无法解决这个问题,但如果您需要快速解决,请改用 do.call
并使用 c
将 n = 10
拉入 args :
sim %>%
mutate(sim = map2(f, params, .f = function(fn, args) {do.call(fn, c(args, n = 10))}))
!!!
运算符优先于匿名函数的创建。因此,它会在数据框的范围内立即args
求值,如果找不到这样的列,则会在全局范围内求值。一种解决方案是将函数定义移到 map2
调用之外:
myfun <- function(fn, args) exec(fn, !!!args, n = 10)
sim %>%
mutate(sim = map2(f, params, myfun)) # Now works
另一种解决方案是将函数名称和所有参数连接到一个列表中,然后将该列表及其 domain lifted:
传递给 exec
sim %>%
mutate(temp = map2(f, params, c, n=10),
sim = map(temp, lift(exec)),
temp = NULL)
“R for Data Science”中的这个示例使用现已停用的 invoke_map
。
sim <- tribble(
~f, ~params,
"runif", list(min = -1, max = 1),
"rnorm", list(sd = 5),
"rpois", list(lambda = 10)
)
sim %>%
mutate(sim = invoke_map(f, params, n = 10))
如果我单独提取列,那么它适用于 map2
和 exec
map2(sim$f, sim$params, function(fn, args) exec(fn, !!!args, n = 10))
但是,我无法让 mutate
与 map2
和 exec
sim %>%
mutate(sim = map2(f, params, function(fn, args) exec(fn, !!!args, n = 10)))
我收到错误“错误:无法拼接闭包类型的对象,因为它不是向量”
有人可以帮忙吗?
我认为问题出在 exec
的某个地方,或者更具体地说,是 big-bang (!!!
) 部分,由于某种原因它试图拼接不是你的变量 args
,但函数 base::args
(因此,您收到的错误消息)。您可以尝试将 args
重命名为其他名称,您会得到一个不同的错误:
> sim %>%
mutate(sim = map2(f, params, .f = function(fn, x) {exec(fn, !!!x, n = 10)}))
Error in splice(dot_call(capture_dots, frame_env = frame_env, named = named, :
object 'x' not found
我必须说我还不够深入,无法解决这个问题,但如果您需要快速解决,请改用 do.call
并使用 c
将 n = 10
拉入 args :
sim %>%
mutate(sim = map2(f, params, .f = function(fn, args) {do.call(fn, c(args, n = 10))}))
!!!
运算符优先于匿名函数的创建。因此,它会在数据框的范围内立即args
求值,如果找不到这样的列,则会在全局范围内求值。一种解决方案是将函数定义移到 map2
调用之外:
myfun <- function(fn, args) exec(fn, !!!args, n = 10)
sim %>%
mutate(sim = map2(f, params, myfun)) # Now works
另一种解决方案是将函数名称和所有参数连接到一个列表中,然后将该列表及其 domain lifted:
传递给exec
sim %>%
mutate(temp = map2(f, params, c, n=10),
sim = map(temp, lift(exec)),
temp = NULL)