Posted on Categories Coding, Opinion, TutorialsTags ,

More on Macros in R

Recently ran into something interesting in the R macros/quasi-quotation/substitution/syntax front:

D0FD431X0AI4pM8

Romain François: “.@_lionelhenry reveals planned double curly syntax At #satRdayParis as a possible replacement, addition to !! and enquo()”

It appears !! is no longer the last word in substitution (it certainly wasn’t the first).

The described effect is actually already pretty easy to achieve in R.

suppressPackageStartupMessages(library("dplyr"))

group_by <- wrapr::bquote_function(group_by)
summarize <- wrapr::bquote_function(summarize)

my_average <- function(data, grp_var, avg_var) {
  data %>%
    group_by(.( grp_var )) %>%
    summarize(avg = mean(.( avg_var ), na.rm = TRUE))
}

data <- data.frame(x = 1:10, g = rep(c(0,1), 5))

my_average(data, as.name("g"), as.name("x"))

## # A tibble: 2 x 2
##       g   avg
##   <dbl> <dbl>
## 1     0     5
## 2     1     6

Or if you don’t want to perform the quoting by hand.

my_average <- function(data, grp_var, avg_var,
                       grp_var_name = substitute(grp_var),
                       avg_var_name = substitute(avg_var)
                       ) {
  data %>%
    group_by(.( grp_var_name )) %>%
    summarize(avg = mean(.( avg_var_name ), na.rm = TRUE))
}

my_average(data, g, x)

## # A tibble: 2 x 2
##       g   avg
##   <dbl> <dbl>
## 1     0     5
## 2     1     6

And we can use the same Thomas Lumley / bquote() notation for string interpolation.

group_var <- as.name("g")
avg_var <- as.name("x")

wrapr::sinterp("group_var was .(group_var), and avg_var was .(avg_var)")

# [1] "group_var was g, and avg_var was x"

The .() notation has a great history in R and has been used by data.table for years.

One thought on “More on Macros in R”

  1. BTW: the second function is a great way to simultaneously present a workable Non Standard Evaluation and standard evaluation interface at the same time (so that NSE isn’t a barrier to programming).

Comments are closed.