Programming the tidyverse: quoted and unqouted parameters

1 Load packages

library(tidyverse)  # data wrangling

2 Motivation

If a project reaches some level of complexity, sooner or later, more systematical meausures of coding need to be employed.

Using the tidyverse ecosystem, programming - instead of interactive use - may be something different or unusual and it may take some time to wrap your head around it.

In this post, I’ll show how to deal with a standard situation (using tidyvserse’ nonstandard evaluation). More precisely, there are two (complementary) situations we’ll address:

  1. How to work with a nonquoted (bare, no quotation marks) parameter in a function call, e.g., draw_cool_diagram(mtcars, hp).

    1. How to work with a nquoted (with quotation marks) parameter in a function call, e.g., draw_cool_diagram(mtcars, "hp").

3 First: Quoted (string) parameter

For the ease of comprehension, let’s make a very simple function: A function that pulls a column out of tibble, returning a vector of the values.

The point is that we use a string as parameter value in the function that uses tidyverse commands internally.

pull_string <- function(data, var){
  
  var_symbol <- as.name(var)
  
  out <- 
  data %>% 
    pull({{var_symbol}})
  
  return(out)
}

Ok, here’s comes the function call, note the quoted parameter “hp”:

out1 <- pull_string(mtcars, "hp")
out1
#>  [1] 110 110  93 110 175 105 245  62  95 123 123 180 180 180 205 215 230  66  52
#> [20]  65  97 150 150 245 175  66  91 113 264 175 335 109

The “curly curly” {{ operator provides the candy here. It explains to the tidyverse function that var_symbol needs to evaluated in the environment of the data frame.

Note that we first translated var from a string to a symbol, using as.name():

as.name("hp")
#> hp

Next to as.name() the curly-curly operator can be made use of.

4 Second: Unquoted parameter

Ok, let’s move on, next, the unquoted parameter in our function.

pull_unquoted <- function(data, var) {
  
  out <-
    data %>% 
    pull({{var}})
  
  return(out)
}

out2 <- pull_unquoted(mtcars, hp)
out2
#>  [1] 110 110  93 110 175 105 245  62  95 123 123 180 180 180 205 215 230  66  52
#> [20]  65  97 150 150 245 175  66  91 113 264 175 335 109

Even more simple than method 1. Here, we don’t need to translate var to a symbol, because we already got in unquoted, ie., as a “symbol”.

5 Check

Did it work out?

identical(out1, out2)
#> [1] TRUE

Seems so!

6 Bonus

To translate from symbol to string, we can use the following expression:

deparse(substitute(var))
#> [1] "var"