如何通过将字符串转换为环境中可用的同名函数来改变包含函数的 list-column?

How to mutate a list-column that holds functions by converting strings to functions with the same name that are available in the environment?

我正在构建一个 tibble,我在其中组织数据 object 的名称(如 chr)以及每个数据的相关整理函数.

例如,我有一个用于争论的函数 mtcars 和一个用于争论的函数 iris:

library(dplyr)

wrangle_mtcars <- function() {
  mtcars %>%
    group_by(am) %>%
    summarise(mean_mpg = mean(mpg))
}

wrangle_iris <- function() {
  iris %>%
    group_by(Species) %>%
    summarise(across(starts_with("Sepal"), mean))
}

我想将它们组织在一个 table 中,看起来像这样:

library(tibble)

my_trb <-
  tribble(~data_name, ~.fn_wrangling,
          "mtcars", wrangle_mtcars,
          "iris", wrangle_iris)

my_trb
#> # A tibble: 2 x 2
#>   data_name .fn_wrangling
#>   <chr>     <list>       
#> 1 mtcars    <fn>         
#> 2 iris      <fn>

但是我不想像上面那样my_trb手动构建,而是想以编程方式构建。也就是说,如果我已经得到一个包含数据名称 object 的 1 列 table,我想简单地粘贴一个 "wrangle_" 前缀并让小标题“理解”我指的是全局环境中同名的函数。

换句话说我想从:

given_table <- tibble(data_name = c("mtcars", "iris"))

## # A tibble: 2 x 2
##   data_name .fn_wrangling
##   <chr>     <list>       
## 1 mtcars    <fn>         
## 2 iris      <fn>  

通过做类似的事情:

given_table %>%
  mutate(.fn_wrangling = list(paste0("wrangle_", data_name) %>% as.name))

## # A tibble: 2 x 2
##   data_name .fn_wrangling
##   <chr>     <list>       
## 1 mtcars    <sym>  # <----| but I want it to be <fn> as in `my_trb`, not <sym>       
## 2 iris      <sym>  # <----|

但是如果我使用 as.function() 而不是 as.name() 它会抛出一个错误:

given_table %>%
  mutate(.fn_wrangling = list(paste0("wrangle_", data_name) %>% as.function))

Error: Problem with mutate() column .fn_wrangling.
i .fn_wrangling = list(paste0("wrangle_", data_name) %>% as.function).
x list argument expected

我们可以使用 match.fun

library(dplyr)
given_table %>% 
  rowwise %>%
   mutate(.fn_wrangling = list(match.fun(paste0("wrangle_", data_name)))) %>% 
  ungroup
# A tibble: 2 × 2
  data_name .fn_wrangling
  <chr>     <list>       
1 mtcars    <fn>         
2 iris      <fn>