Use rlang and glue syntax to create new variables

rlang
glue
sym
englue
name injection
curly curly
Author
Affiliations

Layal Christine Lettry

cynkra GmbH

University of Fribourg, Dept. of Informatics, ASAM Group

Published

March 29, 2024

How can you create, transform and filter several variables in a function by using the glue syntax and rlang?

The following example helps me to remind how to deal with the rlang and glue syntax. However, this is very complicated and this is intended to be a simple means of finding working ways of using the operators curly-curly ({ x }) and the name injection (:=) as well as the functions englue and sym in other use cases.

Please always try to find an easy way to solve your problem. If it is too complicated (like it is below), try to think again about how you can solve your problem in an easier way.

You may want to look at the article sections about indirection and name injection. Additionally, you will find further information in the vignette about dynamic dots.

my_mean <- function(data,
                    input_var1,
                    output_var) {
  input_var1_name_torgersen <- rlang::englue("{{ input_var1 }}.Torgersen")
  input_var1_name_biscoe <- rlang::englue("{{ input_var1 }}.Biscoe")
  input_var1 <- rlang::englue("{{ input_var1 }}")
  output_name_torgersen <- rlang::englue("{{ output_var }}.Torgersen")
  output_name_biscoe <- rlang::englue("{{ output_var }}.Biscoe")

  res <- data |>
    dplyr::filter(island %in% c("Torgersen", "Biscoe")) |>
    tidyr::pivot_wider(
      names_from = c(species, island),
      names_sep = ".",
      values_from = body_mass_g
    ) |>
    dplyr::reframe(
      "{output_name_torgersen}" := mean(eval(rlang::sym({
        input_var1_name_torgersen
      })), na.rm = TRUE),
      "{output_name_biscoe}" := mean(eval(rlang::sym({
        input_var1_name_biscoe
      })), na.rm = TRUE),
      .by = c(year, sex)
    ) |>
    dplyr::distinct() |> 
    tidyr::drop_na()
}
out <- palmerpenguins::penguins |>
  dplyr::mutate(
    species = as.character(species),
    island = as.character(island)
  ) |>
  my_mean(
    input_var1 = Adelie,
    output_var = Adelie.mean_bodymass
  )
out
# A tibble: 6 × 4
   year sex    Adelie.mean_bodymass.Torgersen Adelie.mean_bodymass.Biscoe
  <int> <fct>                           <dbl>                       <dbl>
1  2007 male                            4139.                       3770 
2  2007 female                          3475                        3470 
3  2008 female                          3519.                       3244.
4  2008 male                            4194.                       4011.
5  2009 female                          3194.                       3447.
6  2009 male                            3784.                       4269.

Easy alternative solution

A simple way to obtain a much better result in a tidied data frame would be using dplyr::across().

palmerpenguins::penguins |>
  dplyr::reframe(dplyr::across(body_mass_g, \(x) mean(x, na.rm = TRUE), .names = "mean_{.col}"),
    .by = c(year, sex, island, species)
  ) |>
  dplyr::filter(
    island %in% c("Torgersen", "Biscoe"),
    species == "Adelie"
  ) |> 
  tidyr::drop_na(sex)
# A tibble: 12 × 5
    year sex    island    species mean_body_mass_g
   <int> <fct>  <fct>     <fct>              <dbl>
 1  2007 male   Torgersen Adelie             4139.
 2  2007 female Torgersen Adelie             3475 
 3  2007 female Biscoe    Adelie             3470 
 4  2007 male   Biscoe    Adelie             3770 
 5  2008 female Biscoe    Adelie             3244.
 6  2008 male   Biscoe    Adelie             4011.
 7  2008 female Torgersen Adelie             3519.
 8  2008 male   Torgersen Adelie             4194.
 9  2009 female Biscoe    Adelie             3447.
10  2009 male   Biscoe    Adelie             4269.
11  2009 female Torgersen Adelie             3194.
12  2009 male   Torgersen Adelie             3784.

Citation

BibTeX citation:
@online{lettry2024,
  author = {Lettry, Layal Christine},
  title = {Use Rlang and Glue Syntax to Create New Variables},
  date = {2024-03-29},
  url = {https://rdiscovery.netlify.app/posts/2024-03-29_rlang-glue/},
  langid = {en}
}
For attribution, please cite this work as:
Lettry, Layal Christine. 2024. “Use Rlang and Glue Syntax to Create New Variables.” March 29, 2024. https://rdiscovery.netlify.app/posts/2024-03-29_rlang-glue/.