Posted on Categories Coding, Opinion, Programming, TutorialsTags , ,

Quoting Concatenate

In our last note we used wrapr::qe() to help quote expressions. In this note we will discuss quoting and code-capturing interfaces (interfaces that capture user source code) a bit more.

My position on code-capturing interfaces (or non-standard-evaluation/NSE) is: if poorly handled, they can be a large interface price/risk to pay for the minor convenience of eliding a few quotation marks.

Computation is meant to be over values. In fact one can think of computation as transforming code plus initial values to resulting values.

Our wrapr R package has the sensible design principle: NSE can be convenient, but we are going to isolate it to a few methods. Users then pass the objects that those methods create as values to other methods.

The primary place code capturing shows up in our wrapr R package is in the qc() and qchar_frame() methods.

qc() is “quoting concatenate” it is much like c(), but it quotes its arguments.

It lets you replace this:

   dplyr::select(iris, Petal.Width, Petal.Length)

with this:

   library("wrapr")
   iris[, qc(Petal.Width, Petal.Length)]

We skipped the quotes, and the NSE stuff is safely isolated from the rest of the system.

A nice addition is: the latest version of wrapr incorporates base::bquote() based quasiquotation.

Quasiquotation was introduced into R by Thomas Lumley in 2003, and allows users to signal they want to turn off quotation for portions of their code. The user indicates they do not wish a portion of their code to be quoted (but instead want it evaluated for its value) by surrounding that portion with the function-notation “.()“.

An example of this is given here.

  library("wrapr")

  OTHER_SYMBOL <- "Petal.Length"

  qc(Petal.Width, OTHER_SYMBOL)
  # [1] "Petal.Width"  "OTHER_SYMBOL"

  qc(Petal.Width, .(OTHER_SYMBOL))
  # [1] "Petal.Width"  "Petal.Length"

base::bquote() was a significant contribution to R that deserves a lot more attention, respect, credit, priority, and deference than it appears to have received recently. I would suggest package authors look into incorporating base::bquote() into own their work, before moving on to newer extension packages. We are not saying here “use the wrapr package” (though we do say that often, as it makes our own work much easier and very much want to share the wrapr package). We are saying: “give base::bquote() a try in your own packages.” The “.()“-notation is already standard to R, and a good standard notation for users to expect from R packages.

For our part, we have found incorporating base::bquote() into our own work to be easy and rewarding.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.