首页 > 解决方案 > if_else() `false` 必须是 double 类型,而不是整数 - 在 R 中

问题描述

一长串 dplyr 管道的末端是

mutate(n = if_else(FiscalYear == "FY2018" & Candy == "SNICKERS", n - 3, n))

这给出了这个错误

Error in mutate_impl(.data, dots) : Evaluation error: `false` must be type double, not integer.

如果我做这两个中的任何一个,它就会消失

mutate(n = ifelse(FiscalYear == "FY2018" & Candy == "SNICKERS", n - 3, n))

mutate(n = if_else(FiscalYear == "FY2018" & Candy == "SNICKERS", n - 3L, n))

我认为制作一个简单的可重现游戏是最简单的,所以我做了你在下面看到的,但我再也找不到错误了。知道发生了什么吗?为什么在不ifelse工作的地方工作,如果我将 3 更改为 3L if_else,为什么工作?if_else我理解L 强制3 是一个整数,对吗?

library(tidyverse)
df <- tribble(
  ~name, ~fruit, ~qty,
  "Bob", "apple", 10,
  "Bill", "apple", 10
)

# THIS WORKS AGAIN AS IT SHOULD
df %>% mutate(qty = ifelse(name == "Bob" & fruit == "apple", qty / 2, qty))

# BUT IF_ELSE DOESN'T FAIL THIS TIME, WEIRD
df %>% mutate(qty = if_else(name == "Bob" & fruit == "apple", qty / 2, qty))

标签: rif-statementdplyr

解决方案


if_elsefromdplyr是类型稳定的,这意味着它检查“真”和“假”条件是否相同。如果不是,则if_else引发错误。ifelse在 Base R 中没有这样做。

写作时:

mutate(n = if_else(FiscalYear == "FY2018" & Candy == "SNICKERS", n - 3, n))

我假设n最初是整数类型,所以“假”将是整数类型,将n-3“真”强制为双精度,因为3是双精度。“true”和“false”属于不同类型,因此if_else会引发错误。

写作时:

mutate(qty = if_else(name == "Bob" & fruit == "apple", qty / 2, qty))

qty可能已经是双精度数,因此将双精度数除以2(双精度数)仍会产生双精度数。“真”和“假”是同一类型。因此没有错误。

话虽如此,这可以很容易地通过以下typeofs进行检查:

> typeof(6)
[1] "double"

> typeof(6L)
[1] "integer"

> typeof(6L-3)
[1] "double"

> typeof(6L-3L)
[1] "integer"

> typeof(6/2)
[1] "double"

ifelse从 Base R 执行隐式强制,将所有内容转换为相同的类型。这意味着当“true”和“false”属于不同类型时,它不会抛出错误。这既方便又危险,因为在隐式强制之后可能会出现意想不到的结果。

我建议将ifelse其用于一次性/临时程序,以及if_else当您想利用内置单元测试时。


推荐阅读