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.
_
代わりにこれら2つのいずれかを行うと、それはなくなります
mutate(n = ifelse(FiscalYear == "FY2018" & Candy == "SNICKERS", n - 3, n))
mutate(n = if_else(FiscalYear == "FY2018" & Candy == "SNICKERS", n - 3L, n))
簡単な再現可能なレクリエーションを作成するのが最も簡単だと思ったので、以下に示すものを実行しましたが、もうエラーを取得することはできません。何が起こっているのでしょうか? なぜifelse
は_if_else
_が機能しないのに、なぜ_if_else
_は3Lに変更すると機能するのですか?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))
_
if_else
from dplyr
は型が安定しているため、「true」条件と「false」条件が同じ型であるかどうかをチェックします。そうでない場合、if_else
はエラーをスローします。 Base Rのifelse
はそれを行いません。
書くとき:
mutate(n = if_else(FiscalYear == "FY2018" & Candy == "SNICKERS", n - 3, n))
n
は元々整数型であったため、「false」は整数型であり、n-3
は3
がdoubleであるため、trueをdoubleに強制します。 「true」と「false」はタイプが異なるため、if_else
はエラーをスローします。
書くとき:
mutate(qty = if_else(name == "Bob" & fruit == "Apple", qty / 2, qty))
qty
はすでに倍精度である可能性が高いため、倍精度を2
(倍精度)で除算しても倍精度が得られます。 「true」と「false」は同じタイプです。したがって、エラーはありません。
とはいえ、これは次のtypeof
sで簡単に確認できます。
> typeof(6)
[1] "double"
> typeof(6L)
[1] "integer"
> typeof(6L-3)
[1] "double"
> typeof(6L-3L)
[1] "integer"
> typeof(6/2)
[1] "double"
Base Rのifelse
は、すべてを同じ型に変換する暗黙の強制を行います。これは、「true」と「false」のタイプが異なる場合にエラーをスローしないことを意味します。暗黙の強制後に予期しない結果が生じる可能性があるため、これはより便利で危険です。
一時的なプログラムやアドホックプログラムにはifelse
を使用し、組み込みの単体テストを利用したい場合にはif_else
を使用することをお勧めします。