dplyr if_else()vs base R ifelse()

时间:2018-06-01 14:53:49

标签: r if-statement dplyr

我在Tidyverse中相当熟练,但总是使用ifelse()代替dplyr if_else()。我想切换此行为,默认情况下始终使用dplyr::if_else()并弃用代码中的ifelse()

有什么理由不这样做吗?这可能会让我陷入困境吗?我会给你一些细节,但最近,当我在数据分析中不知不觉地创建了一列字符矩阵时,没有使用if_else()搞砸了我。如果我切换到始终使用if_else(),我希望将来避免这个问题。

3 个答案:

答案 0 :(得分:15)

if_else更严格。它检查两个备选方案是否属于同一类型,否则会引发错误,而ifelse将根据需要提升类型。在某些情况下这可能是一个好处,但如果您不检查错误或明确强制进行类型转换,则可能会破坏脚本。例如:

ifelse(c(TRUE,TRUE,FALSE),"a",3)
[1] "a" "a" "3"
if_else(c(TRUE,TRUE,FALSE),"a",3)
Error: `false` must be type character, not double

答案 1 :(得分:3)

我还要补充一点,if_else()NA的情况下可以赋予值,这是添加额外条件的便捷方法。

df <- data_frame(val = c(80, 90, NA, 110))
df %>% mutate(category = if_else(val < 100, 1, 2, missing = 9))

#     val category
#   <dbl>    <dbl>
# 1    80        1
# 2    90        1
# 3    NA        9
# 4   110        2

答案 2 :(得分:0)

首选if_else()而不是ifelse()的另一个重要原因是检查长度的一致性。看到这个危险的陷阱:

> tibble(x = 1:3, y = ifelse(TRUE, x, 4:6))
# A tibble: 3 x 2
      x     y
  <int> <int>
1     1     1
2     2     1
3     3     1

比较
> tibble(x = 1:3, y = if_else(TRUE, x, 4:6))
    Error: `true` must be length 1 (length of `condition`), not 3.

在两种情况下,根据单个(标量)逻辑变量的值,显然y列等于x或等于4:6ifelse()默默地将其输出截断为长度1,然后默默地对其进行回收。 if_else()几乎可以肯定地从源头上捕获了一个错误。