case_when
要点有两个
- 不匹配的时候会返回 NA,而不是保持不变
- 根据顺序进行条件判断,顺序很重要
下面这段代码,
x <- 1:50
case_when(
x %% 35 == 0 ~ "fizz buzz",
x %% 5 == 0 ~ "fizz",
x %% 7 == 0 ~ "buzz",
TRUE ~ as.character(x)
)
如果不包含TRUE ~ as.character(x),会返回
[1] NA NA NA NA "fizz" NA
[7] "buzz" NA NA "fizz" NA NA
[13] NA "buzz" "fizz" NA NA NA
[19] NA "fizz" "buzz" NA NA NA
[25] "fizz" NA NA "buzz" NA "fizz"
[31] NA NA NA NA "fizz buzz" NA
[37] NA NA NA "fizz" NA "buzz"
[43] NA NA "fizz" NA NA NA
[49] "buzz" "fizz"
如果不包含TRUE ~ as.character(x),不满足前面几个条件的 数字 到了这里会被转成 character,因此不会返回 NA
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"
可以配合verb使用
starwars %>%
select(name:mass, gender, species) %>%
mutate(
type = case_when(
height > 200 | mass > 200 ~ "large",
species == "Droid" ~ "robot",
TRUE ~ "other"
)
)
case_when
可以用在和tidyverse库以外的函数一起使用
case_character_type <- function(height, mass, species) {
case_when(
height > 200 | mass > 200 ~ "large",
species == "Droid" ~ "robot",
TRUE ~ "other"
)
}
case_character_type(150, 250, "Droid")
#> [1] "large"
case_character_type(150, 150, "Droid")
#> [1] "robot"