Rで文字列→数値に変換する際、NAs introduced by coercionが出て困った時のtips
次のような変換を考えます。
- "1名" → 1
- "2名" → 2
- "なし" → 0
- "調査中" → NA
これをdplyrのパイプの中でmutate( case_when(...) )
を駆使して実行していたのですが、エラーとなってしまいました。
データフレーム(見栄えのためtibble)
mydf <- tibble( 同居家族 = c("1名","2名","なし","調査中") )
ダメな例
mydf %>% mutate( 同居家族数 = case_when( 同居家族 == "なし" ~ 0 , 同居家族 == "調査中" ~ NA_integer_ , str_detect(同居家族,"名") ~ as.numeric( str_remove(同居家族,"名") ) ) )
上を実行すると次のようなErrorが出ます。
Error: Problem with `mutate()` input `同居家族数`. x must be an integer vector, not a double vector. ℹ Input `同居家族数` is `case_when(...)`. Run `rlang::last_error()` to see where the error occurred. In addition: Warning message: In eval_tidy(pair$rhs, env = default_env) : NAs introduced by coercion
ググってみると、なんとなく似たようなissueが上がっておりました。
頑張って読んでみると、case_when
で分岐してもas.numeric( str_remove(同居家族,"名") )
が実行されるのはstr_detect(同居家族,"名")
の時のみではないっぽいことがわかりました。ということで結局、as.numeric()
するときに数値に変換できない文字列が入っていたためエラーになっていた、というわけです。
改善策
改善策としては、面倒臭がらず列を数字に変換できる文字列に一旦変換したのちに、改めてas.numeric()
してあげれば良いわけです。
mydf %>% mutate( 同居家族数 = case_when( 同居家族 == "なし" ~ "0" , 同居家族 == "調査中" ~ NA_character_ , str_detect(同居家族,"名") ~ str_remove(同居家族, "名") ), 同居家族数 = as.numeric(同居家族数) )
実行結果