使用 rlang 从向量中获取不带引号的变量名
Getting unquoted variable names from a vector using rlang
我正在构建一个函数,我希望用户能够为其传递未加引号的变量。稍后在准备输出时,我将需要这些变量的名称作为字符串。
如果每个参数只携带一个变量,这没有问题。我可以使用 deparse(substitute(x))
或 rlang::as_name(rlang::enquo(x))
来获取名称(后者可能是更好的方法)。但是,如果我让他们使用 c()
在一个参数中传递多个变量,我该怎么做?
在阅读了一大堆关于 quosures 等内容之后,到目前为止我想出的唯一方法是 names(dplyr::select(data,{{x}}))
但我无法想象这是正确的方法.
nameprinter <- function(x, manynames, onename) {
manynames <- names(dplyr::select(x, {{manynames}}))
onename <- rlang::as_name(rlang::enquo(onename))
c(manynames,onename)
}
df <- data.frame(a=1:10,b=1:10,c=1:10)
nameprinter(df,c(a,b),c)
# [1] "a" "b" "c"
获取传入 manynames
的变量名称的方法有什么比我这里的方法更好的方法?谢谢。
我认为您不需要直接使用 rlang::enquo
函数来解决此问题:
library("dplyr")
nameprinter <- function(x, manynames, onename) {
select(df, !!manynames) %>% print()
select(df, !!onename) %>% print()
c(manynames, onename)
}
df <- tibble(a = 1:10, b = 1:10, c = 1:10)
nameprinter(df, c("a", "b"), "c")
这是你想要的吗?
您可以使用基础 R 来完成此操作:
nameprinter <- function(x, manynames, onename) {
manynames <- substitute(manynames)
names_env <- setNames(as.list(names(x)), names(x))
manynames_quo <- eval(manynames, names_env)
onename <- deparse(substitute(onename))
c(manynames_quo,onename)
}
df <- data.frame(a=1:10,b=1:10,c=1:10)
nameprinter(df,c(a,b),c)
#[1] "a" "b" "c"
这会根据 df 中的变量名称评估我们的 manynames 向量。这应该比使用 select
然后提取名称快一点。
实际上已经有它的功能了。我们可以使用 vars_select
tidyselect::vars_select(names(df), c(a,b), c)
# a b c
#"a" "b" "c"
tidyselect::vars_select(names(df), a, b)
# a b
# "a" "b"
我想到了一种更通用且不依赖于数据框的方法。它使用 as_name
并使用 vapply
...
将其应用于 quosures
foo <- function(.data, value_col, ...) {
group_cols <- enquos(...)
value_col <- enquo(value_col)
# do stuff
.data %>% group_by(!!!group_cols) %>% summarize_at(vars(!!value_col), mean) %>% print()
# passed columns as a character vector
vapply(c(group_cols, value_col), rlang::as_name, "")
}
foo(mtcars, mpg, cyl, vs)
我正在构建一个函数,我希望用户能够为其传递未加引号的变量。稍后在准备输出时,我将需要这些变量的名称作为字符串。
如果每个参数只携带一个变量,这没有问题。我可以使用 deparse(substitute(x))
或 rlang::as_name(rlang::enquo(x))
来获取名称(后者可能是更好的方法)。但是,如果我让他们使用 c()
在一个参数中传递多个变量,我该怎么做?
在阅读了一大堆关于 quosures 等内容之后,到目前为止我想出的唯一方法是 names(dplyr::select(data,{{x}}))
但我无法想象这是正确的方法.
nameprinter <- function(x, manynames, onename) {
manynames <- names(dplyr::select(x, {{manynames}}))
onename <- rlang::as_name(rlang::enquo(onename))
c(manynames,onename)
}
df <- data.frame(a=1:10,b=1:10,c=1:10)
nameprinter(df,c(a,b),c)
# [1] "a" "b" "c"
获取传入 manynames
的变量名称的方法有什么比我这里的方法更好的方法?谢谢。
我认为您不需要直接使用 rlang::enquo
函数来解决此问题:
library("dplyr")
nameprinter <- function(x, manynames, onename) {
select(df, !!manynames) %>% print()
select(df, !!onename) %>% print()
c(manynames, onename)
}
df <- tibble(a = 1:10, b = 1:10, c = 1:10)
nameprinter(df, c("a", "b"), "c")
这是你想要的吗?
您可以使用基础 R 来完成此操作:
nameprinter <- function(x, manynames, onename) {
manynames <- substitute(manynames)
names_env <- setNames(as.list(names(x)), names(x))
manynames_quo <- eval(manynames, names_env)
onename <- deparse(substitute(onename))
c(manynames_quo,onename)
}
df <- data.frame(a=1:10,b=1:10,c=1:10)
nameprinter(df,c(a,b),c)
#[1] "a" "b" "c"
这会根据 df 中的变量名称评估我们的 manynames 向量。这应该比使用 select
然后提取名称快一点。
实际上已经有它的功能了。我们可以使用 vars_select
tidyselect::vars_select(names(df), c(a,b), c)
# a b c
#"a" "b" "c"
tidyselect::vars_select(names(df), a, b)
# a b
# "a" "b"
我想到了一种更通用且不依赖于数据框的方法。它使用 as_name
并使用 vapply
...
foo <- function(.data, value_col, ...) {
group_cols <- enquos(...)
value_col <- enquo(value_col)
# do stuff
.data %>% group_by(!!!group_cols) %>% summarize_at(vars(!!value_col), mean) %>% print()
# passed columns as a character vector
vapply(c(group_cols, value_col), rlang::as_name, "")
}
foo(mtcars, mpg, cyl, vs)