Search code examples
rdplyr

How to automatically generate pairs of expressions/ LHS and RHS in dplyr


Suppose I have a formula and some values. I am trying to do the following mutate statement, which is in the form result{value}=my_formula({value},col1,col2,col3):

library(dplyr)

my_formula <- function(value,col1,col2,col3){
  step1 <- value*col1*col2+col3
  step2 <- 50000<step1 & step1<100000
  return(step2)
}

values=c(2,11,14)

mtcars%>%
  mutate(result2=my_formula(2,disp,hp,carb),
         result11=my_formula(11,disp,hp,carb),
         result14=my_formula(14,disp,hp,carb)) %>%
  head

   mpg cyl disp  hp drat    wt  qsec vs am gear carb result2 result11 result14
1 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4   FALSE    FALSE    FALSE
2 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4   FALSE    FALSE    FALSE
3 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1   FALSE    FALSE    FALSE
4 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1    TRUE    FALSE    FALSE
5 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2   FALSE    FALSE    FALSE
6 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1   FALSE    FALSE    FALSE

Is it possible to automate this mutate statement? I am working with 10~1000 values in practice. I am also open to other approaches to generate these columns.


Solution

  • Similar to @JilberUrbina's answer, but putting an lapply(values, ..) directly in a mutate:

    library(dplyr)
    values <- c(2,11,14)
    values <- setNames(values, paste0("res", values))
    mtcars |>
      mutate(data.frame(lapply(values, my_formula, disp, hp, carb))) |>
      head()
    #                    mpg cyl disp  hp drat    wt  qsec vs am gear carb  res2 res11 res14
    # Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4 FALSE FALSE FALSE
    # Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4 FALSE FALSE FALSE
    # Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1 FALSE FALSE FALSE
    # Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1  TRUE FALSE FALSE
    # Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2 FALSE FALSE FALSE
    # Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1 FALSE FALSE FALSE
    

    This uses the under-referenced feature of mutate (and summarize) that if the unnamed argument returns a data.frame, then those columns are cbind'ed to the original data.