Shinya Uryu

2 minute read

TIL

これまで、purrr::map_df()でリストからデータフレームで値を得たいときはc()を使いながら対象の変数名を与えていたのだけど、それは面倒だなーと思っていたりもした。

こういうやつ。

library(broom)
library(purrr)

lm.res <- mtcars %>%
  split(.$cyl) %>%
  map(~ lm(mpg ~ wt, data = .x)) %>% 
  map(tidy)

lm.res %>% 
  map_df(~ .[c("estimate", "statistic", "p.value")])
##         estimate      statistic             p.value
## 1 39.57119601304  9.10398003528 0.00000777151106938
## 2 -5.64702526124 -3.05225052976 0.01374278198674072
## 3 28.40884451320  6.78927837143 0.00105484419097406
## 4 -2.78010593916 -2.08260537564 0.09175766017203653
## 5 23.86802907600  7.94155114534 0.00000405270541503
## 6 -2.19243792645 -2.96580257564 0.01179280975651219

で、全ての変数を取り出すには、わざわざc()を使う必要はなくてmap_df(~ .[])で良いことに気がついた。さらにいうと[すらも不要でmap_df(~ .)だけで良い。

lm.res %>% 
  map_df(~ .[])
##          term       estimate      std.error      statistic
## 1 (Intercept) 39.57119601304 4.346582028927  9.10398003528
## 2          wt -5.64702526124 1.850118529322 -3.05225052976
## 3 (Intercept) 28.40884451320 4.184368788406  6.78927837143
## 4          wt -2.78010593916 1.334917297184 -2.08260537564
## 5 (Intercept) 23.86802907600 3.005461859929  7.94155114534
## 6          wt -2.19243792645 0.739239335908 -2.96580257564
##               p.value
## 1 0.00000777151106938
## 2 0.01374278198674072
## 3 0.00105484419097406
## 4 0.09175766017203653
## 5 0.00000405270541503
## 6 0.01179280975651219
# これでも良い
lm.res %>% 
  map_df(~ .)

なんでかというと、リストの特定の要素を参照するときは添え字か名前を次のようにする(map_df(~ .[c("hoge")])のパターン)が、全て出力するにはこれらが不要になるのと同じ理由(で良いだろうか)。

lm.res[[2]][c("estimate", "statistic", "p.value")]
##         estimate      statistic          p.value
## 1 28.40884451320  6.78927837143 0.00105484419097
## 2 -2.78010593916 -2.08260537564 0.09175766017204

# [[1]]と[[1]][] は等しい(全ての要素を参照する)
all.equal(lm.res[[1]], lm.res[[1]][])
## [1] TRUE

直接関係しないけど、Jennifer Bryan ( jennybc )のpurrrやリストデータのチュートリアルを読んでいると、なるほどなあと関心するものが多い。これを読んでいると自分は[[[の使い方が理解できていないのかもしれないとも思う。まだまだR力のなさを感じる。…というわけで、purrr、奥が深いぜ

Enjoy!

comments powered by Disqus