String interpolation is a common feature of many programming languages and is used to insert the value of variables directly into character strings. This is useful to compose dynamic messages in a natural way. For example "Hello {x}" will be interpolated as “Hello John” if x = "John".

What if you want to apply some modifications to the variable before insertion? Like normalizing the case, trimming at 40 characters, or concatenating? In general, you can’t. Well, actually you can but have to use the language’s own native tools. And it can be surprising how performing a few basic operations can quickly amount to lot of typing.

The aim of the package stringmagic is to simplify and empower string interpolation. With the string_magic function, you can apply 50+ basic operations to interpolated variables, interpolations can be nested, there is advanced support for pluralization, and much more.

1 Basic interpolation

string_magic behaves in a similar way to the well known function glue. Almost anything glue can do, string_magic can do. Use curly brackets to interpolate variables: i.e to insert their value directly in the string:

x = "John" ; y = "Mary"
string_magic("Hi {x}! How's {y} doing?")
#> [1] "Hi John! How's Mary doing?"

You can either interpolate a variable that already exists, as above, or provide the variable as an argument:

string_magic("Hi {x}! How's {y} doing?", y = "Jane")
#> [1] "Hi John! How's Jane doing?"

So far, so good. Now let’s come to string_magic’s originality: the ability to add operations to interpolations.

2 How to add operations to interpolations

In string_magic you can apply any arbitrary chain of operations to the interpolated variables. The syntax is as follows:

The operations are a comma separated sequence of keywords, each keyword being bound to a specific function. Here is an example in which we apply two operations:

lovers = c("romeo", "juliet")
string_magic("Famous lovers: {title, enum ? lovers}.")
#> [1] "Famous lovers: Romeo and Juliet."

As shown, title puts to title case and enum creates an enumeration (i.e. turns the elements of a vector into a single character string). These two operations are applied sequentially from left to right to the variable lovers. You can stack as many operations as you wish.

Here is a short list of common operations: enum to enumerate; lower, upper and title to change the case; unik to create the vector of unique elements; n, N to format integers; split to break the string with respect to a pattern; replace to make pattern replacements; collapse to concatenate the strings; first to select the first elements; q, Q and bq for quoting; align to align the elements.

The question mark defines the separation between the operations and the expression. After the question mark, you can use any valid R expression. For example:

string_magic("The max of each variable is: {enum ? sapply(iris[, 1:4], max)}.")
#> [1] "The max of each variable is: 7.9, 4.4, 6.9 and 2.5."

2.1 Adding arguments to operations

Many operations use arguments. Arguments are passed using quoted text just before the operation. The syntax is:

Let’s take the example of splitting an email address and keeping the text before the domain:

email = ""
string_magic("This message comes from {'@'split, first ? email}.")
#> [1] "This message comes from John."