Home > Back-end >  How can I conditionally "mutate" a variable inside a dplyr pipe
How can I conditionally "mutate" a variable inside a dplyr pipe

Time:08-05

Just as the title says, I'm trying to conditionally add a mutate step to my dplyr pipe. But I'm getting errors. Is there a tidy solution? Here's a simple example...

max.mpg <- 50
mtcars %>%
  {
    if(!!max.mpg > 10) mutate(foo = 1) else . 
  } 

But the above generates the following error:

  no applicable method for 'mutate' applied to an object of class "c('double', 'numeric')"

What I'm trying to do is add a new variable to the mtcars data frame--but only upon a given condition. If the condition is FALSE, then I just want the original data frame returned.

Interestingly, if I change the above condition to evaluate as FALSE (such as by writing, if(!!max.mpg > 60)), then the script runs fine. So, the problem indeed appears to reside in the mutate verb.

Finally, and in case it greatly affects the solution, I've got the above embedded inside a custom function. But I think if I can get the simple script correct in the above, I can work the rest out.

Any suggestions?

CodePudding user response:

You don't need tidyeval

library(dplyr)

max.mpg <- 50

mtcars %>% {if(max.mpg > 10) mutate(., foo=1) else .}

#>                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb foo
#> Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4   1
#> Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4   1
#> Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1   1
#> Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1   1
#> Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2   1
...

mtcars %>% {if(max.mpg > 60) mutate(., foo=1) else .}  

#>                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#> Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#> Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
#> Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
#> Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
...

CodePudding user response:

It seems like what you are trying to evaluate doesn't have anything to do with the data set as you are defining max.mpg and then comparing that to a constant. I assume what you are trying to do is is flag when mpg is greater than max.mpg, in that case this should work

library (dplyr)
max.mpg <- 50

mtcars %>% mutate(foo=if_else(mpg>max.mpg, true = 1, false = 0))

With a value of 50 all the rows evaluate the same, if that is changed to something within the mpg range can see that it evaluates conditionally.

max.mpg <- 20

mtcars %>% mutate(foo=if_else(mpg>max.mpg, true = 1, false = 0))
  • Related