library(tidyr)
library(dplyr)
library(purrr)
ネストされたデータフレームとは、1つ(または複数)の列がデータフレームのリストになっているデータフレームのことです。単純なネストされたデータフレームは手で作ることができます。
<- tibble(
df1 g = c(1, 2, 3),
data = list(
tibble(x = 1, y = 2),
tibble(x = 4:5, y = 6:7),
tibble(x = 10)
)
)
df1#> # A tibble: 3 × 2
#> g data
#> <dbl> <list>
#> 1 1 <tibble [1 × 2]>
#> 2 2 <tibble [2 × 2]>
#> 3 3 <tibble [1 × 1]>
ネストされたデータフレームとは、1つ(または複数)の列がデータフレームのリストになっているデータフレームのことです。単純なネストされたデータフレームは手で作ることができます。:
<- tribble(
df2 ~g, ~x, ~y,
1, 1, 2,
2, 4, 6,
2, 5, 7,
3, 10, NA
)%>% nest(data = c(x, y))
df2 #> # A tibble: 3 × 2
#> g data
#> <dbl> <list>
#> 1 1 <tibble [1 × 2]>
#> 2 2 <tibble [2 × 2]>
#> 3 3 <tibble [1 × 2]>
nest()
では、どの変数を内部に入れ子にするかを指定します。もう一つの方法は、どの変数を外部に置いておくかを記述するために、dplyr::group_by()
を使用することです。
%>% group_by(g) %>% nest()
df2 #> # A tibble: 3 × 2
#> # Groups: g [3]
#> g data
#> <dbl> <list>
#> 1 1 <tibble [1 × 2]>
#> 2 2 <tibble [2 × 2]>
#> 3 3 <tibble [1 × 2]>
ネスティングは、グループ化されたデータに関連して理解するのが最も簡単だと思います。つまり、出力の各行が入力の1つの group に対応します。出力の各行は入力の1つの group に対応しています。この方法は、グループごとのオブジェクトがある場合に特に便利であることはすぐに分かるでしょう。
nest()
の反対はunnest()
です。データフレームを含むリスト列の名前を与えると、データフレームを行結合し、外側の列を正しい回数だけ繰り返して並べます。
%>% unnest(data)
df1 #> # A tibble: 4 × 3
#> g x y
#> <dbl> <dbl> <dbl>
#> 1 1 1 2
#> 2 2 4 6
#> 3 2 5 7
#> 4 3 10 NA
入れ子になったデータは、各グループに 何か が1つずつあるような問題に適しています。このような問題がよく起こるのは、複数のモデルをフィッティングする場合です。
<- mtcars %>%
mtcars_nested group_by(cyl) %>%
nest()
mtcars_nested#> # A tibble: 3 × 2
#> # Groups: cyl [3]
#> cyl data
#> <dbl> <list>
#> 1 6 <tibble [7 × 10]>
#> 2 4 <tibble [11 × 10]>
#> 3 8 <tibble [14 × 10]>
データフレームのリストがあれば、モデルのリストを作るのはとても自然なことです。
<- mtcars_nested %>%
mtcars_nested mutate(model = map(data, function(df) lm(mpg ~ wt, data = df)))
mtcars_nested#> # A tibble: 3 × 3
#> # Groups: cyl [3]
#> cyl data model
#> <dbl> <list> <list>
#> 1 6 <tibble [7 × 10]> <lm>
#> 2 4 <tibble [11 × 10]> <lm>
#> 3 8 <tibble [14 × 10]> <lm>
そして、予測のリストを作成することもできます。
<- mtcars_nested %>%
mtcars_nested mutate(model = map(model, predict))
mtcars_nested #> # A tibble: 3 × 3
#> # Groups: cyl [3]
#> cyl data model
#> <dbl> <list> <list>
#> 1 6 <tibble [7 × 10]> <dbl [7]>
#> 2 4 <tibble [11 × 10]> <dbl [11]>
#> 3 8 <tibble [14 × 10]> <dbl [14]>
このワークフローは、broomと組み合わせて使うと、モデルを整然としたデータフレームに変換し、それを unnest()
してフラットなデータフレームに戻すことが簡単にできます。broom と dplyr の vignetteでは、より大きな例を見ることができます。