This function allows you to vectorise multiple if and else if statements. It is an R equivalent of the SQL CASE WHEN statement.

case_when(...)

Arguments

...

A sequence of two-sided formulas. The left hand side (LHS) determines which values match this case. The right hand side (RHS) provides the replacement value.

The LHS must evaluate to a logical vector. Each logical vector can either have length 1 or a common length. All RHSs must evaluate to the same type of vector.

These dots are evaluated with explicit splicing.

Value

A vector as long as the longest LHS, with the type (and attributes) of the first RHS. Inconsistent lengths or types will generate an error.

Examples

x <- 1:50 case_when( x %% 35 == 0 ~ "fizz buzz", x %% 5 == 0 ~ "fizz", x %% 7 == 0 ~ "buzz", TRUE ~ as.character(x) )
#> [1] "1" "2" "3" "4" "fizz" "6" #> [7] "buzz" "8" "9" "fizz" "11" "12" #> [13] "13" "buzz" "fizz" "16" "17" "18" #> [19] "19" "fizz" "buzz" "22" "23" "24" #> [25] "fizz" "26" "27" "buzz" "29" "fizz" #> [31] "31" "32" "33" "34" "fizz buzz" "36" #> [37] "37" "38" "39" "fizz" "41" "buzz" #> [43] "43" "44" "fizz" "46" "47" "48" #> [49] "buzz" "fizz"
# Like an if statement, the arguments are evaluated in order, so you must # proceed from the most specific to the most general. This won't work: case_when( TRUE ~ as.character(x), x %% 5 == 0 ~ "fizz", x %% 7 == 0 ~ "buzz", x %% 35 == 0 ~ "fizz buzz" )
#> [1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" #> [16] "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30" #> [31] "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" "45" #> [46] "46" "47" "48" "49" "50"
# case_when is particularly useful inside mutate when you want to # create a new variable that relies on a complex combination of existing # variables starwars %>% select(name:mass, gender, species) %>% mutate( type = case_when( height > 200 | mass > 200 ~ "large", species == "Droid" ~ "robot", TRUE ~ "other" ) )
#> # A tibble: 87 x 6 #> name height mass gender species type #> <chr> <int> <dbl> <chr> <chr> <chr> #> 1 Luke Skywalker 172 77 male Human other #> 2 C-3PO 167 75 <NA> Droid robot #> 3 R2-D2 96 32 <NA> Droid robot #> 4 Darth Vader 202 136 male Human large #> 5 Leia Organa 150 49 female Human other #> 6 Owen Lars 178 120 male Human other #> 7 Beru Whitesun lars 165 75 female Human other #> 8 R5-D4 97 32 <NA> Droid robot #> 9 Biggs Darklighter 183 84 male Human other #> 10 Obi-Wan Kenobi 182 77 male Human other #> # ... with 77 more rows
# Dots support splicing: patterns <- list( TRUE ~ as.character(x), x %% 5 == 0 ~ "fizz", x %% 7 == 0 ~ "buzz", x %% 35 == 0 ~ "fizz buzz" ) case_when(!!! patterns)
#> [1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" #> [16] "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30" #> [31] "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" "45" #> [46] "46" "47" "48" "49" "50"