R 在 glue 语句中使用 bang-bang
R use bang-bang within a glue statement
我想创建一个简单的函数,它接受一个数据框和用户为该数据框中的两列提供的名称。目的是让它可以轻松地与 dplyr
管道一起使用。它将产生一个粘合字符串的字符向量:
func <- function(data, last, first) {
last <- rlang::enquo(last)
first <- rlang::enquo(first)
glue::glue_data(data, "{!!last}, {!!first}")
}
理想情况下,我希望用户能够致电:
df %>% func(lastName, firstName)
这将生成一个包含多个值的字符向量,格式为 Smith, John
。
我的函数目前不起作用,因为 bang-bang 运算符在 glue_data
的上下文中不起作用。我如何在仍然使用 NSE 的同时解决这个问题?我收到的错误是:
Error: Quosures can only be unquoted within a quasiquotation context.
代表:
df <- data.frame(lastName = c("Smith", "Bond", "Trump"), firstName = c("John","James","Donald"))
> df
lastName firstName
1 Smith John
2 Bond James
3 Trump Donald
预期输出
> glue::glue_data(df, "{lastName}, {firstName}")
Smith, John
Bond, James
Trump, Donald
但是,我希望能够通过使用我的函数并调用来实现预期的输出:
df %>% func(lastName, firstName)
以上是我实际用例的简化版本,我实际上将调用 glue
语句作为后续函数中的参数:
biggerfn <- function(data, subject, first, last) {
subject <- rlang::enquo(subject)
first <- rlang::enquo(first)
last <- rlang::enquo(last)
data %>%
dplyr::distinct(!!subject, !!first, !!last) %>%
smallerfunc(!!subject, glue::glue_data(data, "{!!last}, {!!first}"))
}
我认为你不想强制计算 first
和 last
。您只需要名称来构造字符串 "{lastName}, {firstName}"
.
library(dplyr)
library(rlang)
library(glue)
func <- function(data, last, first) {
first <- as_name(enquo(first))
last <- as_name(enquo(last))
glue_data(
data,
glue("{[last]}, {[first]}", .open = "[", .close = "]")
)
}
df %>% func(lastName, firstName)
#> Smith, John
#> Bond, James
#> Trump, Donald
对于您的新示例,在内部 glue
调用中调用 as_name
。
df <- data.frame(
lastName = c("Smith", "Bond", "Trump"),
firstName = c("John","James","Donald"),
other = 1:3
)
biggerfn <- function(data, subject, first, last) {
subject <- enquo(subject)
first <- enquo(first)
last <- enquo(last)
data %>%
distinct(!!subject, !!first, !!last) %>%
transmute(
!!subject := glue_data(
data,
glue("{[as_name(last)]}, {[as_name(first)]}", .open = "[", .close = "]")
)
)
}
biggerfn(df, other, firstName, lastName)
#> other
#> 1 Smith, John
#> 2 Bond, James
#> 3 Trump, Donald
我不知道您是否致力于 glue
,但这可以使用 tidyr::unite
轻松完成:
func <- function(data, last, first) {
data %>%
tidyr::unite(result, {{last}}, {{first}}, sep=", ")
}
df %>% func(lastName, firstName)
# result
# 1 Smith, John
# 2 Bond, James
# 3 Trump, Donald
# Optionally, follow up with:
# %>% dplyr::pull(result)
# to retrieve the column
这里,{{x}}
是!!enquo(x)
的shorthand。
我想创建一个简单的函数,它接受一个数据框和用户为该数据框中的两列提供的名称。目的是让它可以轻松地与 dplyr
管道一起使用。它将产生一个粘合字符串的字符向量:
func <- function(data, last, first) {
last <- rlang::enquo(last)
first <- rlang::enquo(first)
glue::glue_data(data, "{!!last}, {!!first}")
}
理想情况下,我希望用户能够致电:
df %>% func(lastName, firstName)
这将生成一个包含多个值的字符向量,格式为 Smith, John
。
我的函数目前不起作用,因为 bang-bang 运算符在 glue_data
的上下文中不起作用。我如何在仍然使用 NSE 的同时解决这个问题?我收到的错误是:
Error: Quosures can only be unquoted within a quasiquotation context.
代表:
df <- data.frame(lastName = c("Smith", "Bond", "Trump"), firstName = c("John","James","Donald"))
> df
lastName firstName
1 Smith John
2 Bond James
3 Trump Donald
预期输出
> glue::glue_data(df, "{lastName}, {firstName}")
Smith, John
Bond, James
Trump, Donald
但是,我希望能够通过使用我的函数并调用来实现预期的输出:
df %>% func(lastName, firstName)
以上是我实际用例的简化版本,我实际上将调用 glue
语句作为后续函数中的参数:
biggerfn <- function(data, subject, first, last) {
subject <- rlang::enquo(subject)
first <- rlang::enquo(first)
last <- rlang::enquo(last)
data %>%
dplyr::distinct(!!subject, !!first, !!last) %>%
smallerfunc(!!subject, glue::glue_data(data, "{!!last}, {!!first}"))
}
我认为你不想强制计算 first
和 last
。您只需要名称来构造字符串 "{lastName}, {firstName}"
.
library(dplyr)
library(rlang)
library(glue)
func <- function(data, last, first) {
first <- as_name(enquo(first))
last <- as_name(enquo(last))
glue_data(
data,
glue("{[last]}, {[first]}", .open = "[", .close = "]")
)
}
df %>% func(lastName, firstName)
#> Smith, John
#> Bond, James
#> Trump, Donald
对于您的新示例,在内部 glue
调用中调用 as_name
。
df <- data.frame(
lastName = c("Smith", "Bond", "Trump"),
firstName = c("John","James","Donald"),
other = 1:3
)
biggerfn <- function(data, subject, first, last) {
subject <- enquo(subject)
first <- enquo(first)
last <- enquo(last)
data %>%
distinct(!!subject, !!first, !!last) %>%
transmute(
!!subject := glue_data(
data,
glue("{[as_name(last)]}, {[as_name(first)]}", .open = "[", .close = "]")
)
)
}
biggerfn(df, other, firstName, lastName)
#> other
#> 1 Smith, John
#> 2 Bond, James
#> 3 Trump, Donald
我不知道您是否致力于 glue
,但这可以使用 tidyr::unite
轻松完成:
func <- function(data, last, first) {
data %>%
tidyr::unite(result, {{last}}, {{first}}, sep=", ")
}
df %>% func(lastName, firstName)
# result
# 1 Smith, John
# 2 Bond, James
# 3 Trump, Donald
# Optionally, follow up with:
# %>% dplyr::pull(result)
# to retrieve the column
这里,{{x}}
是!!enquo(x)
的shorthand。