Home > OS >  Using glue-like constructs on RHS in R/Tidyeval
Using glue-like constructs on RHS in R/Tidyeval

Time:10-13

I've spent hours trying to make glue on the RHS of a formula work and out of clues. Here is a simple reprex.

meta <- function(x, var, suffix){
  x<- x %>% mutate("{{var}}_{suffix}":= 5)
  
  x<- x %>% mutate("{{var}}_{suffix}_new":= {{var}} - "{{var}}_{suffix}")
  
  
}

x<- meta(mtcars, mpg, suf)

#Should be equivalent to

x<- mtcars %>% mutate(mpg_suf:= 5)

x<- x%>% mutate(mpg_suf_new:= mpg - mpg_suf)

#N: Tried https://stackoverflow.com/questions/70427403/how-to-correctly-glue-together-prefix-suffix-in-a-function-call-rhs but none of the methods in it worked, unfortunately

Meta function gives me "Error in local_error_context(dots = dots, .index = i, mask = mask) : promise already under evaluation: recursive default argument reference or earlier problems? "

Went over all hits for the searchwords for it on SO but nothing worked at the moment.

Would really appreciate any insights. Thank you!

CodePudding user response:

Here is a working version:

meta <- function(x, var, suffix){
  new_name <- rlang::englue("{{ var }}_{{ suffix }}")
  x %>%
    mutate("{new_name}" := 5) %>%
    mutate("{new_name}_new" := {{ var }} - .data[[new_name]])
}

names(meta(mtcars, mpg, suf))
#>  [1] "mpg"         "cyl"         "disp"        "hp"
#>  [5] "drat"        "wt"          "qsec"        "vs"
#>  [9] "am"          "gear"        "carb"        "mpg_suf"
#> [13] "mpg_suf_new"

To understand what is going on:

See also the general topic: https://rlang.r-lib.org/reference/topic-data-mask-programming.html

CodePudding user response:

I think it's best if we define the pieces we need first, then we can use them as needed on the LHS or the RHS of the calculation. I will add that it doesn't make much sense to me to pass the suffix argument as a bare name. I think it would be a clearer choice to make it string only.

library(dplyr)

meta <- function(x, var, suffix) {

  var <- rlang::as_name(enquo(var))
  suffix <- rlang::as_name(enquo(suffix))  # Remove this to make "suffix" string only.
  new_var <- glue::glue("{var}_{suffix}")
  
  x %>%
    mutate("{new_var}" := 5,
           "{new_var}_new" := !!sym(var) - !!sym(new_var))
}

mtcars %>%
  head() %>%
  meta(mpg, suf)

                   mpg cyl disp  hp drat    wt  qsec vs am gear carb mpg_suf mpg_suf_new
Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4       5        16.0
Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4       5        16.0
Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1       5        17.8
Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1       5        16.4
Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2       5        13.7
Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1       5        13.1
  • Related