Home > Mobile >  how substitute ifelse with if...else
how substitute ifelse with if...else

Time:10-12

I want substitute ifelse with if...else because I have exactly the same conditions with a lot of effects. I saw others question like Question14170778 but I can't apply the answear. I know that if statement is not vectorized unlike ifelse

df <- mtcars %>% 
  mutate(Tire = ifelse(mpg>18 & disp>160, "big",NA),
         Bonus = ifelse(mpg>18 & disp>160, -100,NA),
         Maintenance= ifelse(mpg>18 & disp>160, "expensive","cheap"))

and I try something like this but it dosn't work with 1 mutate so with 3....

df1 <- mtcars %>% 
  { if(mtcars$mpg>18 & mtcars$disp>160) mutate(.,Tire = "big") else . }

Is there any other way to avoid writing 10 times the same lines ?

CodePudding user response:

Since you're doing the same logical comparison for several columns, a good alternate approach would be to store your labels in a separate table, then do the comparison once, and join the outcomes:

conditions <- data.frame(
  value = c(TRUE, FALSE),
  Tire = c('big', NA),
  Bonus = c(-100, NA),
  Maintenance = c('expensive', 'cheap')
)

  value Tire Bonus Maintenance
1  TRUE  big  -100   expensive
2 FALSE <NA>    NA       cheap

df <- mtcars %>% 
  mutate(value = mpg > 18 & disp > 160) %>% 
  inner_join(conditions)

   mpg cyl disp  hp drat    wt  qsec vs am gear carb value Tire Bonus Maintenance
1 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4 FALSE <NA>    NA       cheap
2 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4 FALSE <NA>    NA       cheap
3 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1 FALSE <NA>    NA       cheap
4 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1  TRUE  big  -100   expensive
5 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2  TRUE  big  -100   expensive
6 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1  TRUE  big  -100   expensive

CodePudding user response:

If we want to create three columns

library(dplyr)
library(tidyr)
library(stringr)
 mtcars %>%
   mutate(out = case_when(mpg > 18 & disp > 160 ~
    list(tibble(Tire = "big", Bonus = -100, 
      Maintenance = "expensive")),
    TRUE  ~ list(tibble(Tire = NA_character_, Bonus = NA_real_, Maintenance = "cheap")))) %>%
   unnest_wider(out, names_sep = "") %>% 
  rename_with(~ str_remove(.x, "^out"))

-output

# A tibble: 32 × 14
     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb Tire  Bonus Maintenance
   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> <chr>      
 1  21       6  160    110  3.9   2.62  16.5     0     1     4     4 <NA>     NA cheap      
 2  21       6  160    110  3.9   2.88  17.0     0     1     4     4 <NA>     NA cheap      
 3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1 <NA>     NA cheap      
 4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1 big    -100 expensive  
 5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2 big    -100 expensive  
 6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1 big    -100 expensive  
 7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4 <NA>     NA cheap      
 8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2 <NA>     NA cheap      
 9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2 <NA>     NA cheap      
10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4 big    -100 expensive  
  • Related