concatenate quosures and string

949 views Asked by At

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
1

There are 1 answers

4
acylam On BEST ANSWER

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:

  1. quosures are quoted expressions that keep track of an environment.
  2. 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.
  3. quo_name formats a quosure into a string, which can be used later in the function.
  4. quo_text is similar to quo_name but does not check for whether the input is a symbol.

Check these:

  1. rlang documentation
  2. Non-Standard Evaluation in R
  3. ?enquo
  4. ?quo_name