【问题标题】:Using mutate with map2 and exec instead of invoke_map将 mutate 与 map2 和 exec 一起使用,而不是 invoke_map
【发布时间】:2021-01-29 00:46:31
【问题描述】:

“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))

如果我分别提取列,则它适用于 map2exec

map2(sim$f, sim$params, function(fn, args) exec(fn, !!!args, n = 10))

但是,我无法让 mutatemap2exec 一起工作

sim %>% 
  mutate(sim = map2(f, params, function(fn, args) exec(fn, !!!args, n = 10)))

我收到错误“错误:无法拼接闭包类型的对象,因为它不是向量”

有人可以帮忙吗?

【问题讨论】:

    标签: r dplyr tidyverse purrr rlang


    【解决方案1】:

    !!! 运算符优先于匿名函数的创建。因此,它会在数据框范围内评估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)
    

    【讨论】:

      【解决方案2】:

      我认为问题出在 exec 的某个地方,或者更具体地说,是大爆炸 (!!!) 部分,由于某种原因,它试图拼接的不是你的变量 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 并使用cn = 10 拉入args:

      sim %>% 
        mutate(sim = map2(f, params, .f = function(fn, args) {do.call(fn, c(args, n = 10))}))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-06-24
        • 2023-03-06
        • 1970-01-01
        • 1970-01-01
        • 2018-05-30
        • 1970-01-01
        • 2019-11-21
        • 1970-01-01
        相关资源
        最近更新 更多