【小ネタ】リストにNULLがある場合のpurrr::map系関数の挙動
タイトルが適切かわからないが、小ネタ。次のようなリストオブジェクトがあるとする。リストに含まれる要素はname, age, genderの値をもっているが、2番目の要素はgenderがない、というようなもの。
library(purrr) x <- list(list(name = "A", age = 23L, gender = "Male"), list(name = "B", age = 18L), list(name = "C", age = 24L, gender = "Male"))
これをpurrrを使って処理する。全ての要素に含まれるname, ageはmap
系の関数で参照できる。一方でgenderについては、要素の数が合わないためにエラーになる。
x %>% map("name")
## [[1]]
## [1] "A"
##
## [[2]]
## [1] "B"
##
## [[3]]
## [1] "C"
x %>% map_int("age")
## [1] 23 18 24
x %>% map_chr("gender") # Error: Result 2 is not a length 1 # atomic vector
このような場合の処置として、map
関数では.nullという引数を用意していて、NA_integer_
を指定すると足りない値を欠損値として扱ってくれる。
x %>% map_chr("gender", .null = NA_integer_)
## [1] "Male" NA "Male"
ニュースを見ると、どうやら0.2.1からの仕様らしい。それに関する議論もある。
また返り値をデータフレーム化するmap_df()
では、要素数が一致しなくても、.nullを指定しなくても、欠損値として処理される。AIEEEEEE!!??
x %>% map_df(~.)
## # A tibble: 3 x 3
## name age gender
## <chr> <int> <chr>
## 1 A 23 Male
## 2 B 18 <NA>
## 3 C 24 Male
map
を利用する別の関数でも.nullが指定可能である。
x %>% at_depth(1, "gender", .null = NA_integer_) %>% flatten_chr()
## [1] "Male" NA "Male"