Reputation: 430
I'm looking for a way to concatenate a quosure and a string whose result is a quosure. Actually, if I use paste0()
and quo_name()
, I can do it. But I wonder if there is a more elegant alternative to write a function in my package. This is a generic example:
library(dplyr)
df <- data_frame(
z_1 = 1,
z_2 = 2,
y_1 = 10,
y_2 = 20
)
get_var <- function(.data, var) {
xx = enquo(var)
select(.data, paste0(quo_name(xx), "_1"), paste0(quo_name(xx), "_2"))
}
get_var(df, z)
# A tibble: 1 x 2
z_1 z_2
<dbl> <dbl>
1 1 2
Upvotes: 4
Views: 968
Reputation: 18681
Without a function, this is how you do it using dplyr
:
library(dplyr)
df %>%
select(starts_with("z_"))
You can also create a function and pass in a string for the variable name like this:
get_var= function(df, var){
df %>%
select(starts_with(paste0(var, "_")))
}
get_var(df, "z")
Now, the tricky part comes when you are trying to pass in the variable name without quoting it into a function (the R code, not the value it contains). One way of doing it would be deparse
+ substitute
in Base R. This converts the symbol supplied to var
to a string, which is convenient for later use within the function:
get_var = function(df, var){
var_quo = deparse(substitute(var))
df %>%
select(starts_with(paste0(var_quo, "_")))
}
Finally, here is how to do the same with enquo
and quo_name
in rlang/tidyverse
package:
library(rlang)
get_var = function(df, var){
var_quo = quo_name(enquo(var))
df %>%
select(starts_with(paste0(var_quo, "_")))
}
get_var(df, z)
get_var(df, y)
Result:
# A tibble: 1 x 2
z_1 z_2
<dbl> <dbl>
1 1 2
# A tibble: 1 × 2
y_1 y_2
<dbl> <dbl>
1 10 20
Notes:
enquo
takes a symbol referring to a function's argument, quotes the R code and bundles it with the function's environment in a quosure.quo_name
formats a quosure into a string, which can be used later in the function.quo_text
is similar to quo_name
but does not check for whether the input is a symbol.Check these:
rlang
documentation?enquo
?quo_name
Upvotes: 5