super is a fork / reimplementation of the glue package with a focus on efficiency and simplicity at a cost of flexibility.
As of the 0.0.1 release it should be considered ‘experimental’.
super::glue()
takes only two arguments: A character string that is used as
a template and an environment to look up the embraced inputs. There is no
option to change the delimiters from being a pair of braces (e.g. {name}
).
Embraced inputs are always looked up in the provided environment (akin to
calling get()
) and are not evaluated. This is similar to glue::glue_safe()
and glue::glue_data_safe()
but note that this is not the default behaviour
of glue::glue()
.
super::glue()
does not trim inputs. Instead this is done by either the
function super::glut()
or explicitly by glue(trim(x))
.
super::glue()
returns an unclassed character vector whereas glue::glue()
returns a <glue>
object and provides a variety of methods to work on that
object.
At present, super::glue()
does not provide any allowance for different
handling of NA
and NULL
values, instead following the behaviour of
paste()
.
Recycling of embraced arguments currently follows standard R recycling rules where the arguments will be recycled to the length of the longest one.
glue::glue()
arguments (and their associated behaviours) .comment
,
.literal
and .transformer
are not implemented.
library(super)
bar <- "baz"
glue("foo{bar}")
#> [1] "foobaz"
dat <- head(cbind(car = rownames(mtcars), mtcars))
glue("{car} does {mpg} mpg.", dat)
#> [1] "Mazda RX4 does 21 mpg." "Mazda RX4 Wag does 21 mpg."
#> [3] "Datsun 710 does 22.8 mpg." "Hornet 4 Drive does 21.4 mpg."
#> [5] "Hornet Sportabout does 18.7 mpg." "Valiant does 18.1 mpg."
name <- "Fred"
age <- 50
anniversary <- as.Date("1991-10-12")
out <- glut("
My name is {name},
my age next year is {age},
my anniversary is {anniversary}.
")
cat(out)
#> My name is Fred,
#> my age next year is 50,
#> my anniversary is 1991-10-12.
Over embraced arguments
head(glue("Item {LETTERS}"))
#> [1] "Item A" "Item B" "Item C" "Item D" "Item E" "Item F"
But not over input strings (yet)
tryCatch(
glue(letters),
error = function(e) conditionMessage(e)
)
#> [1] "`x` must be a character vector of length <= 1."
library(microbenchmark)
bar <- "baz"
bob <- 20
microbenchmark(
sprintf = sprintf("foo%s %d", bar, bob),
paste0 = paste0("foo", bar, " ", bob),
super = super::glue("foo{bar} {bob}"),
glue = as.character(glue::glue_safe("foo{bar} {bob}", .trim = FALSE)),
unit = "relative",
check = "identical"
)
#> Unit: relative
#> expr min lq mean median uq max neval
#> sprintf 1.000000 1.000000 1.000000 1.000000 1.000000 1.0000000 100
#> paste0 2.941176 2.638655 2.311134 2.321429 2.235294 0.5853018 100
#> super 9.647059 8.781513 7.945124 7.628571 7.215686 7.3202100 100
#> glue 77.019608 67.689076 58.144985 58.185714 54.104575 22.7874016 100
dat <- head(cbind(car = rownames(mtcars), mtcars))
microbenchmark(
sprintf = with(dat, sprintf("%s does %.3g mpg.", car, mpg)),
paste0 = with(dat, paste(car, "does", mpg, "mpg.")),
super = super::glue("{car} does {mpg} mpg.", dat),
glue = as.character(glue::glue_data(dat, "{car} does {mpg} mpg.")),
unit = "relative",
check = "identical"
)
#> Unit: relative
#> expr min lq mean median uq max neval
#> sprintf 1.000000 1.000000 1.000000 1.000000 1.000000 1.0000000 100
#> paste0 1.650456 1.618497 1.513562 1.551213 1.536585 0.6293149 100
#> super 2.762918 2.726879 2.618338 2.659030 2.620026 1.9612321 100
#> glue 16.753799 16.417630 15.124414 15.576954 15.093710 6.6601699 100
microbenchmark(
super = super::glut("
My name is {name},
my age next year is {age},
my anniversary is {anniversary}.
"),
glue = as.character(glue::glue("
My name is {name},
my age next year is {age},
my anniversary is {anniversary}.
")),
unit = "relative",
check = "identical"
)
#> Unit: relative
#> expr min lq mean median uq max neval
#> super 1.000000 1.000000 1.000000 1.000000 1.00000 1.000000 100
#> glue 4.018403 3.921805 3.742982 3.729639 3.71174 1.862811 100
For larger input with both glue::glue()
and super::glue()
, the performance
becomes dominated by the internally constructed call to paste0()
, hence the
convergence observed below.
bar <- rep("baz", 1e5)
microbenchmark(
sprintf = sprintf("foo%s %d", bar, bob),
paste0 = paste0("foo", bar, " ", bob),
super = super::glue("foo{bar} {bob}"),
glue = as.character(glue::glue_safe("foo{bar} {bob}", .trim = FALSE)),
unit = "relative",
check = "identical"
)
#> Unit: relative
#> expr min lq mean median uq max neval
#> sprintf 1.1303083 1.1148474 1.1091331 1.107672 1.1090690 1.069603 100
#> paste0 0.9926361 0.9981395 0.9983145 1.003376 0.9995117 1.002943 100
#> super 1.0000000 1.0000000 1.0000000 1.000000 1.0000000 1.000000 100
#> glue 1.1099883 1.1234326 1.1346951 1.114802 1.1283944 1.305985 100