web-dev-qa-db-ja.com

dplyr if_else()vsベースR ifelse()

私はTidyverseにかなり精通していますが、dplyr ifelse()の代わりに常にif_else()を使用しています。この動作を切り替えて、デフォルトで常にdplyr::if_else()を使用し、コードからifelse()を非推奨にします。

これをしない理由はありますか?これはおそらく私をトラブルに巻き込むでしょうか?詳細は省きますが、最近、データ分析で無意識のうちに文字行列の列を作成したときに、if_else()を使用せずに混乱させました。常にif_else()を使用するように切り替えた場合、将来この問題を回避したいと考えています。

15
stackinator

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
17
James

ifelseよりもif_elseを選択するもう1つの理由は、ifelseDatenumericオブジェクトに変えることです。

Dates <- as.Date(c('2018-10-01', '2018-10-02', '2018-10-03'))
new_Dates <- ifelse(Dates == '2018-10-02', Dates + 1, Dates)
str(new_Dates)

#>  num [1:3] 17805 17807 17807

if_elseifelseよりも高速です

複数の条件をテストする場合、case_whenを使用すると、コードが読みやすくなり、エラーが発生しにくくなることに注意してください。

library(dplyr)

case_when(
  Dates == '2018-10-01' ~ Dates - 1,
  Dates == '2018-10-02' ~ Dates + 1,
  Dates == '2018-10-03' ~ Dates + 2,
  TRUE ~ Dates
)

#> [1] "2018-09-30" "2018-10-03" "2018-10-05"

2018-06-01に reprexパッケージ (v0.2.0)によって作成されました。

10
Tung

また、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
5
Joe