此函數允許您對多個if_else()
語句進行向量化。按順序評估每種情況,每個元素的第一個匹配確定輸出向量中的相應值。如果沒有匹配的情況,則 .default
將用作最終的 "else" 語句。
case_when()
是 SQL "searched" CASE WHEN
語句的 R 等效項。
參數
- ...
-
<
dynamic-dots
> 一係列雙邊公式。左側 (LHS) 確定哪些值與此情況匹配。右側 (RHS) 提供重置值。LHS 輸入必須計算為邏輯向量。
RHS 輸入將被強製為其通用類型。
所有輸入將被回收到其常見大小。也就是說,我們鼓勵所有 LHS 輸入的大小相同。回收主要對 RHS 輸入有用,您可以提供大小為 1 的輸入,該輸入將被回收到 LHS 輸入的大小。
NULL
輸入被忽略。 - .default
-
當所有 LHS 輸入返回
FALSE
或NA
時使用的值。.default
的大小必須為 1 或與從...
計算出的通用大小相同。.default
參與具有 RHS 輸入的公共類型的計算。LHS 條件中的
NA
值的處理方式與FALSE
類似,這意味著這些位置的結果將被分配為.default
值。要以不同方式處理條件中的缺失值,您必須在它們落入.default
之前使用另一個條件顯式捕獲它們。這通常涉及is.na(x) ~ value
的一些變體,適合您對case_when()
的使用。如果是
NULL
(默認值),則將使用缺失值。 - .ptype
-
聲明所需輸出類型的可選原型。如果提供,它將覆蓋 RHS 輸入的通用類型。
- .size
-
聲明所需輸出大小的可選大小。如果提供,這將覆蓋從
...
計算出的通用大小。
例子
x <- 1:70
case_when(
x %% 35 == 0 ~ "fizz buzz",
x %% 5 == 0 ~ "fizz",
x %% 7 == 0 ~ "buzz",
.default = as.character(x)
)
#> [1] "1" "2" "3" "4" "fizz"
#> [6] "6" "buzz" "8" "9" "fizz"
#> [11] "11" "12" "13" "buzz" "fizz"
#> [16] "16" "17" "18" "19" "fizz"
#> [21] "buzz" "22" "23" "24" "fizz"
#> [26] "26" "27" "buzz" "29" "fizz"
#> [31] "31" "32" "33" "34" "fizz buzz"
#> [36] "36" "37" "38" "39" "fizz"
#> [41] "41" "buzz" "43" "44" "fizz"
#> [46] "46" "47" "48" "buzz" "fizz"
#> [51] "51" "52" "53" "54" "fizz"
#> [56] "buzz" "57" "58" "59" "fizz"
#> [61] "61" "62" "buzz" "64" "fizz"
#> [66] "66" "67" "68" "69" "fizz buzz"
# 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(
x %% 5 == 0 ~ "fizz",
x %% 7 == 0 ~ "buzz",
x %% 35 == 0 ~ "fizz buzz",
.default = as.character(x)
)
#> [1] "1" "2" "3" "4" "fizz" "6" "buzz" "8" "9" "fizz"
#> [11] "11" "12" "13" "buzz" "fizz" "16" "17" "18" "19" "fizz"
#> [21] "buzz" "22" "23" "24" "fizz" "26" "27" "buzz" "29" "fizz"
#> [31] "31" "32" "33" "34" "fizz" "36" "37" "38" "39" "fizz"
#> [41] "41" "buzz" "43" "44" "fizz" "46" "47" "48" "buzz" "fizz"
#> [51] "51" "52" "53" "54" "fizz" "buzz" "57" "58" "59" "fizz"
#> [61] "61" "62" "buzz" "64" "fizz" "66" "67" "68" "69" "fizz"
# If none of the cases match and no `.default` is supplied, NA is used:
case_when(
x %% 35 == 0 ~ "fizz buzz",
x %% 5 == 0 ~ "fizz",
x %% 7 == 0 ~ "buzz",
)
#> [1] NA NA NA NA "fizz"
#> [6] NA "buzz" NA NA "fizz"
#> [11] NA NA NA "buzz" "fizz"
#> [16] NA NA NA NA "fizz"
#> [21] "buzz" NA NA NA "fizz"
#> [26] NA NA "buzz" NA "fizz"
#> [31] NA NA NA NA "fizz buzz"
#> [36] NA NA NA NA "fizz"
#> [41] NA "buzz" NA NA "fizz"
#> [46] NA NA NA "buzz" "fizz"
#> [51] NA NA NA NA "fizz"
#> [56] "buzz" NA NA NA "fizz"
#> [61] NA NA "buzz" NA "fizz"
#> [66] NA NA NA NA "fizz buzz"
# Note that `NA` values on the LHS are treated like `FALSE` and will be
# assigned the `.default` value. You must handle them explicitly if you
# want to use a different value. The exact way to handle missing values is
# dependent on the set of LHS conditions you use.
x[2:4] <- NA_real_
case_when(
x %% 35 == 0 ~ "fizz buzz",
x %% 5 == 0 ~ "fizz",
x %% 7 == 0 ~ "buzz",
is.na(x) ~ "nope",
.default = as.character(x)
)
#> [1] "1" "nope" "nope" "nope" "fizz"
#> [6] "6" "buzz" "8" "9" "fizz"
#> [11] "11" "12" "13" "buzz" "fizz"
#> [16] "16" "17" "18" "19" "fizz"
#> [21] "buzz" "22" "23" "24" "fizz"
#> [26] "26" "27" "buzz" "29" "fizz"
#> [31] "31" "32" "33" "34" "fizz buzz"
#> [36] "36" "37" "38" "39" "fizz"
#> [41] "41" "buzz" "43" "44" "fizz"
#> [46] "46" "47" "48" "buzz" "fizz"
#> [51] "51" "52" "53" "54" "fizz"
#> [56] "buzz" "57" "58" "59" "fizz"
#> [61] "61" "62" "buzz" "64" "fizz"
#> [66] "66" "67" "68" "69" "fizz buzz"
# `case_when()` evaluates all RHS expressions, and then constructs its
# result by extracting the selected (via the LHS expressions) parts.
# In particular `NaN`s are produced in this case:
y <- seq(-2, 2, by = .5)
case_when(
y >= 0 ~ sqrt(y),
.default = y
)
#> Warning: NaNs produced
#> [1] -2.0000000 -1.5000000 -1.0000000 -0.5000000 0.0000000 0.7071068
#> [7] 1.0000000 1.2247449 1.4142136
# `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",
.default = "other"
)
)
#> # A tibble: 87 × 6
#> name height mass gender species type
#> <chr> <int> <dbl> <chr> <chr> <chr>
#> 1 Luke Skywalker 172 77 masculine Human other
#> 2 C-3PO 167 75 masculine Droid robot
#> 3 R2-D2 96 32 masculine Droid robot
#> 4 Darth Vader 202 136 masculine Human large
#> 5 Leia Organa 150 49 feminine Human other
#> 6 Owen Lars 178 120 masculine Human other
#> 7 Beru Whitesun lars 165 75 feminine Human other
#> 8 R5-D4 97 32 masculine Droid robot
#> 9 Biggs Darklighter 183 84 masculine Human other
#> 10 Obi-Wan Kenobi 182 77 masculine Human other
#> # ℹ 77 more rows
# `case_when()` is not a tidy eval function. If you'd like to reuse
# the same patterns, extract the `case_when()` call in a normal
# function:
case_character_type <- function(height, mass, species) {
case_when(
height > 200 | mass > 200 ~ "large",
species == "Droid" ~ "robot",
.default = "other"
)
}
case_character_type(150, 250, "Droid")
#> [1] "large"
case_character_type(150, 150, "Droid")
#> [1] "robot"
# Such functions can be used inside `mutate()` as well:
starwars %>%
mutate(type = case_character_type(height, mass, species)) %>%
pull(type)
#> [1] "other" "robot" "robot" "large" "other" "other" "other" "robot"
#> [9] "other" "other" "other" "other" "large" "other" "other" "large"
#> [17] "other" "other" "other" "other" "other" "robot" "other" "other"
#> [25] "other" "other" "other" "other" "other" "other" "other" "other"
#> [33] "other" "other" "large" "large" "other" "other" "other" "other"
#> [41] "other" "other" "other" "other" "other" "other" "other" "other"
#> [49] "other" "other" "other" "other" "other" "large" "other" "other"
#> [57] "other" "other" "other" "other" "other" "other" "other" "other"
#> [65] "other" "other" "other" "other" "large" "large" "other" "other"
#> [73] "robot" "other" "other" "other" "large" "large" "other" "other"
#> [81] "large" "other" "other" "other" "robot" "other" "other"
# `case_when()` ignores `NULL` inputs. This is useful when you'd
# like to use a pattern only under certain conditions. Here we'll
# take advantage of the fact that `if` returns `NULL` when there is
# no `else` clause:
case_character_type <- function(height, mass, species, robots = TRUE) {
case_when(
height > 200 | mass > 200 ~ "large",
if (robots) species == "Droid" ~ "robot",
.default = "other"
)
}
starwars %>%
mutate(type = case_character_type(height, mass, species, robots = FALSE)) %>%
pull(type)
#> [1] "other" "other" "other" "large" "other" "other" "other" "other"
#> [9] "other" "other" "other" "other" "large" "other" "other" "large"
#> [17] "other" "other" "other" "other" "other" "other" "other" "other"
#> [25] "other" "other" "other" "other" "other" "other" "other" "other"
#> [33] "other" "other" "large" "large" "other" "other" "other" "other"
#> [41] "other" "other" "other" "other" "other" "other" "other" "other"
#> [49] "other" "other" "other" "other" "other" "large" "other" "other"
#> [57] "other" "other" "other" "other" "other" "other" "other" "other"
#> [65] "other" "other" "other" "other" "large" "large" "other" "other"
#> [73] "other" "other" "other" "other" "large" "large" "other" "other"
#> [81] "large" "other" "other" "other" "other" "other" "other"
相關用法
- R dplyr case_match 通用向量化 switch()
- R dplyr copy_to 將本地數據幀複製到遠程src
- R dplyr consecutive_id 為連續組合生成唯一標識符
- R dplyr coalesce 找到第一個非缺失元素
- R dplyr context 有關“當前”組或變量的信息
- R dplyr cumall 任何、全部和平均值的累積版本
- R dplyr compute 強製計算數據庫查詢
- R dplyr c_across 合並多列的值
- R dplyr cross_join 交叉連接
- R dplyr count 計算每組中的觀察結果
- R dplyr group_trim 修剪分組結構
- R dplyr slice 使用行的位置對行進行子集化
- R dplyr sample_n 從表中采樣 n 行
- R dplyr row_number 整數排名函數
- R dplyr band_members 樂隊成員
- R dplyr mutate-joins 變異連接
- R dplyr nth 從向量中提取第一個、最後一個或第 n 個值
- R dplyr group_split 按組分割 DataFrame
- R dplyr mutate 創建、修改和刪除列
- R dplyr order_by 用於排序窗口函數輸出的輔助函數
- R dplyr percent_rank 比例排名函數
- R dplyr recode 重新編碼值
- R dplyr starwars 星球大戰人物
- R dplyr desc 降序
- R dplyr between 檢測值落在指定範圍內的位置
注:本文由純淨天空篩選整理自Hadley Wickham等大神的英文原創作品 A general vectorised if-else。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。