Using case_when() over multiple columns

Hey there, @bragks! Thankfully, you don't need to use case_when() separately for each column, and you don't need to use purrr to iterate over the columns. Instead, as you suspected, you can use the scoped variants of mutate: mutate_if() and mutate_at() :smile:

  • mutate_if() lets you mutate all columns that return TRUE for a predicate function that you supply;
  • mutate_at() lets you specify the columns you want to mutate using helpers like starts_with() or one_of(); and
  • mutate_all() lets you mutate... all columns :stuck_out_tongue:

When you use these scoped variants, you wrap the mutation function inside funs(), and then you have access to . to specify the original column. For example:

Df %>% 
  mutate_at(
    vars(one_of('ab', 'de')),
    funs(case_when(
    . == "1+1" | . == "1+2" ~ 1,
    . == "1+3" | . == "1+4" ~ 2,
    . == "1+5" | . == "1+6" ~ 3)))
#> # A tibble: 10 x 6
#>       ab ba    cd    dc       de ed   
#>    <dbl> <chr> <chr> <chr> <dbl> <chr>
#>  1     1 1+2   1+6   1+3       3 1+3  
#>  2     2 1+2   1+2   1+4       2 1+6  
#>  3     2 1+5   1+4   1+3       3 1+3  
#>  4     3 1+3   1+1   1+2       2 1+2  
#>  5     1 1+5   1+2   1+5       2 1+1  
#>  6     3 1+3   1+3   1+5       3 1+1  
#>  7     3 1+5   1+1   1+5       1 1+2  
#>  8     2 1+6   1+3   1+1       2 1+4  
#>  9     2 1+3   1+6   1+5       3 1+4  
#> 10     1 1+5   1+3   1+3       3 1+3  

Df %>% 
  mutate_all(
    funs(case_when(
    . == "1+1" | . == "1+2" ~ 1,
    . == "1+3" | . == "1+4" ~ 2,
    . == "1+5" | . == "1+6" ~ 3)))
#> # A tibble: 10 x 6
#>       ab    ba    cd    dc    de    ed
#>    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#>  1     1     1     3     2     3     2
#>  2     2     1     1     2     2     3
#>  3     2     3     2     2     3     2
#>  4     3     2     1     1     2     1
#>  5     1     3     1     3     2     1
#>  6     3     2     2     3     3     1
#>  7     3     3     1     3     1     1
#>  8     2     3     2     1     2     2
#>  9     2     2     3     3     3     2
#> 10     1     3     2     2     3     2

I hope that helps!

8 Likes