在 R 中动态创建和评估函数

Dynamically create and evaluate function in R

我正在尝试根据字符串输入动态创建和评估函数,但在 meta-programming/evaluation (https://adv-r.hadley.nz/metaprogramming.html) 上再次挂断。我觉得这在 SO 上得到了回答,但我进行了搜索,但无法通过其他帖子找出解决方案;但是,如果有现有答案,请告诉我并标记为重复。非常感谢您的宝贵时间和帮助!以下是问题的代表。

library(dplyr)
library(purrr)
library(rlang)
library(palmerpenguins)

# Create data to join with penguins
penguin_colors <-
  tibble(
    species = c("Adelie", "Chinstrap", "Gentoo"),
    color = c("orange", "purple", "green")
)

# Create function to do specified join and print join type
foo <- function(JOINTYPE) {
  
  # DOESN'T RUN
  # JOINTYPE_join(penguins, penguin_colors, by = "species")
  # call2(sym(paste0(JOINTYPE, "_join")), x = penguins, y = penguin_colors, by = "species")
  
  print(JOINTYPE)
}

# Desired behavior of foo when JOINTYPE == "inner"
inner_join(penguins, penguin_colors, by = "species")
#> # A tibble: 344 x 9
#>    species island bill_length_mm bill_depth_mm flipper_length_… body_mass_g
#>    <chr>   <fct>           <dbl>         <dbl>            <int>       <int>
#>  1 Adelie  Torge…           39.1          18.7              181        3750
#>  2 Adelie  Torge…           39.5          17.4              186        3800
#>  3 Adelie  Torge…           40.3          18                195        3250
#>  4 Adelie  Torge…           NA            NA                 NA          NA
#>  5 Adelie  Torge…           36.7          19.3              193        3450
#>  6 Adelie  Torge…           39.3          20.6              190        3650
#>  7 Adelie  Torge…           38.9          17.8              181        3625
#>  8 Adelie  Torge…           39.2          19.6              195        4675
#>  9 Adelie  Torge…           34.1          18.1              193        3475
#> 10 Adelie  Torge…           42            20.2              190        4250
#> # … with 334 more rows, and 3 more variables: sex <fct>, year <int>,
#> #   color <chr>
print("inner")
#> [1] "inner"

# Use function in for loop
for (JOINTYPE in c("inner", "left", "right")) {
  foo(JOINTYPE)
}
#> [1] "inner"
#> [1] "left"
#> [1] "right"

# Use function in vectorised fashion
walk(c("inner", "left", "right"), foo)
#> [1] "inner"
#> [1] "left"
#> [1] "right"

reprex package (v0.3.0)

于 2020-10-27 创建

一种选择是使用 get() 检索适当的函数:

join <- function(JOINTYPE) {
    get( paste0(JOINTYPE, "_join") )
}

join("inner")(penguins, penguin_colors, by="species")

如果使用rlang,这里比较合适的函数是rlang::exec:

join2 <- function(JOINTYPE, ...) {
    rlang::exec( paste0(JOINTYPE, "_join"), ... )
}

join2("inner", penguins, penguin_colors, by="species")