胶水和 rlang:如何在胶水字符串中传输数据变量?
glue and rlang: how to tunnel data-variables within a glue string?
根据 this 文章,rlang
和 glue
的最新版本允许将隧道 {{ 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
之前使用ensym
或enquo
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
您可以使用 deparse
和 substitute
:
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
根据 this 文章,rlang
和 glue
的最新版本允许将隧道 {{ 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
ensym
或enquo
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
您可以使用 deparse
和 substitute
:
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