まずは蝋の翼から。

学んだことを書きながら確認・整理するためのメモブログ。こういうことなのかな?といったことをふわっと書いたりしていますが、理解が浅いゆえに的はずれなことも多々あると思うのでツッコミ歓迎

ifelse関数が挙動不審なのでdplyr::if_else関数を使う

Rでifelse関数を使ったら思った結果が帰ってこなかった。

yes <- as.Date('2018-01-01')
no <- '2018-12-31'

ifelse(c(TRUE,FALSE), yes, no)
# => [1] "17532"      "2018-12-31"
yes <- as.factor('hoge')
no <- as.POSIXct('2018-01-01')

ifelse(c(TRUE,FALSE), yes, no)

# => [1]          1 1514732400

classやattribute情報が失われるのでDateやfactor型は(内部的な)元の値と違う値になってしまう。

ちなみに、第一引数のベクトル数以上は値が返ってこない、という仕様も内蔵してる模様。

yes <- c('a','b','c')
no <- c('hoge')

ifelse(c(TRUE,FALSE), yes, no)

# => [1] "a"    "hoge"

ifelse()のつらみ アップデート版 - Technically, technophobic.

そのため、予期せぬ挙動をしないためにもdplyr::if_else関数を使いましょう、という話(が上記リンクに書いてた)。

NAを入れたい

yes <- 'hoge'
no <- NA

dplyr::if_else(c(TRUE,FALSE), yes, no)
# =>エラー: `false` must be a character vector, not a logical vector

dplyr::if_else関数は、TRUE, FALSEそれぞれの返り値は同じ型にしないといけない。NAは論理型なのでTRUE, FALSEそれぞれの返り値が異なるのでエラーになる。

そもそもNAは、

本来データが存在しているが、何らかの理由でデータが存在していない状態を示す

【R言語】いい加減NAとNaNとNULL(ついでにInf)の違いをはっきりさせておく - Qiita

とのことなので、「文字型でデータが存在しない」「数値型でデータが存在しない」など、それぞれの文脈の「欠損」で意味合いがある。これを表現したのがNA_characterや、NA_integerとなる。(doubleなどは見当たらないのでそういう場合はas.double(NA))

yes <- 'hoge'
no <- NA_character_

dplyr::if_else(c(TRUE,FALSE), yes, no)

# => "hoge" NA