胶水和 rlang:如何在胶水字符串中传输数据变量?

glue and rlang: how to tunnel data-variables within a glue string?

根据 this 文章,rlangglue 的最新版本允许将隧道 {{ myobj }} 组合成 glue 字符串:

library(dplyr)
library(rlang)
library(glue)

mean_by <- function(data, by, var, prefix = "avg") {
  data %>%
    group_by({{ by }}) %>%
    summarise("{prefix}_{{ var }}" := mean({{ var }}, na.rm = TRUE))
}

iris %>% mean_by(Species, Sepal.Width)
#> # A tibble: 3 x 2
#>   Species    avg_Sepal.Width
#>   <fct>                <dbl>
#> 1 setosa                3.43
#> 2 versicolor            2.77
#> 3 virginica             2.97

但是如果我想在等式的另一边合并,我不能这样做:

analyze_by <- function(data, by, var, prefix = "avg") {
  data %>%
    group_by({{ by }}) %>%
    summarise(analysis = glue("{ prefix } by {{ var }}"))
}

iris %>% analyze_by(Species, Sepal.Width)

#> # A tibble: 3 x 2
#>   Species    analysis      
#>   <fct>      <glue>        
#> 1 setosa     avg by { var }
#> 2 versicolor avg by { var }
#> 3 virginica  avg by { var }

解决此问题的最佳方法是什么?

或许,我们可以在传入glue

之前使用ensymenquo
analyze_by <- function(data, by, var, prefix = "avg") {
 
   var <- rlang::ensym(var)
  
   data %>%
     dplyr::group_by({{ by }}) %>%
     dplyr::summarise(analysis =  glue::glue("{ prefix } by {var}"))
 }

iris %>% 
      analyze_by(Species, Sepal.Width)
# A tibble: 3 x 2
#  Species    analysis          
#  <fct>      <glue>            
#1 setosa     avg by Sepal.Width
#2 versicolor avg by Sepal.Width
#3 virginica  avg by Sepal.Width

您可以使用 deparsesubstitute :

library(dplyr)
library(rlang)

analyze_by <- function(data, by, var, prefix = "avg") {

    var_char <- deparse(substitute(var))
    data %>%
       group_by({{ by }}) %>%
       summarise(analysis = glue::glue("{ prefix } by {var_char}"))
}

iris %>% analyze_by(Species, Sepal.Width)

# A tibble: 3 x 2
#  Species    analysis          
#  <fct>      <glue>            
#1 setosa     avg by Sepal.Width
#2 versicolor avg by Sepal.Width
#3 virginica  avg by Sepal.Width