使用 furrr 进行 tidy 评估

jpq*_*ast 2 future r purrr tidyeval furrr

我想让以下函数使用furrr包而不是purrr包并行运行。

library(furrr)
library(tidyverse)

input <- list(element1 = tibble::tibble(a = c(1, 2), b = c(2, 2)),
              element2 = tibble::tibble(a = c(1, 2), b = c(4, 4))
)

multiplier <- function(data, var1, var2){
  purrr::map_df(.x = data,
                .f = ~ .x %>% 
                  dplyr::mutate(product = {{var1}} * {{var2}})
  )
}

multiplier(input, a, b)
Run Code Online (Sandbox Code Playgroud)

但是,当我将其转换为furrr等效项时,出现错误。

multiplier_parallel <- function(data, var1, var2){
  furrr::future_map_dfr(.x = data,
                .f = ~ .x %>% 
                  dplyr::mutate(product = {{var1}} * {{var2}})
  )
}

future::plan(multiprocess)

multiplier_parallel(input, a, b)
Run Code Online (Sandbox Code Playgroud)
Error in get(name, envir = env, inherits = FALSE) : 
Identified global objects via static code inspection (structure(function (..., .x = ..1, .y = ..2, . = 
..1); .x %>% dplyr::mutate(product = {; {; var1; }; } * {; {; var2; }; }), class = 
c("rlang_lambda_function", "function"))). Object 'a' not found 
Run Code Online (Sandbox Code Playgroud)

我认为原因是该future包会查找要导出给工作人员的所有必要变量。在这种情况下,它正在寻找列名“a”作为全局变量,但找不到它,因此出现错误。

当我只是将变量名插入到调用中时,它可以工作,但是现在该函数不再使用任何变量名:

multiplier_parallel <- function(data, var1, var2){
  furrr::future_map_dfr(.x = data,
                .f = ~ .x %>% 
                  dplyr::mutate(product = a * b)
  )
}

multiplier_parallel(input, a, b)
Run Code Online (Sandbox Code Playgroud)

到目前为止,我尝试了几件事,包括为 .future_options 提供名称,但似乎都不起作用。有什么办法可以使这项工作?我的实际功能要复杂得多,但我认为主要是相同的。如果有人可以提供帮助,那就太好了!

sta*_*rja 5

future尝试自动确定您在代码中使用的全局变量。因为整洁的评价,它识别ab但没有找到它。您可以使用 禁用此设置future_options(globals = FALSE)

future::plan(future::multiprocess)

input <- list(element1 = tibble::tibble(a = c(1, 2), b = c(2, 2)),
              element2 = tibble::tibble(a = c(1, 2), b = c(4, 4))
)

multiplier_parallel <- function(data, var1, var2){
      furrr::future_map_dfr(.x = data,
                            .f = ~ .x %>% 
                                  dplyr::mutate(product = {{var1}} * {{var2}}),
                            .options = furrr::future_options(globals = FALSE)
      )
}

multiplier_parallel(input, a, b)
# A tibble: 4 x 3
      a     b product
  <dbl> <dbl>   <dbl>
1     1     2       2
2     2     2       4
3     1     4       4
4     2     4       8
Run Code Online (Sandbox Code Playgroud)