0Pricing
R Academy · レッスン

データフレームのネストとアンネスト

nest()とunnest()を使い、tidyなワークフローでリスト列を扱います。

「データフレームのネストとアンネスト」はCoddyKit上の無料R Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはR Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 R Academyコースには全4レッスンが含まれています。

リスト列とネストしたデータ

リスト列とは、各セルにRオブジェクト(ベクトル、データフレーム、モデル、リストなど)が含まれるデータフレームの列です。これにより、構造化されたサブデータを他の列とともに格納でき、強力なグループ単位のワークフローを実現できます。

library(tidyr)
library(dplyr)

# A simple data frame with a list-column
df <- data.frame(
  group = c('A','B','C'),
  n = c(3, 2, 4)
)
df$values <- list(c(1,2,3), c(4,5), c(6,7,8,9))

print(df)
print(df$values[[1]])  # Access the first list element

nest() — ネストしたデータフレームの作成

nest(df, data = c(col1, col2)) は、ネストしない列で行をグループ化し、指定した列をデータフレームのリスト列にまとめます。各グループにつき1行となり、それぞれに小さなデータフレームが含まれます。

library(tidyr)
library(dplyr)

df <- data.frame(
  region = c('East','East','East','West','West'),
  month = c(1,2,3,1,2),
  sales = c(100,120,110,200,190)
)

nested <- df %>%
  nest(data = c(month, sales))

print(nested)
print(nested$data[[1]])  # East region's data

group_by() と nest()

最も一般的なパターンは、group_by() の後に nest() を使い、グループごとに1行を作成して、残りのすべての列を data リスト列にまとめる方法です。新しい tidyr バージョンでは、nest(.by = group_col) と同等です。

library(tidyr)
library(dplyr)

df <- data.frame(
  category = c('A','A','A','B','B','C','C','C','C'),
  x = c(1,2,3,4,5,6,7,8,9),
  y = c(2,4,3,8,7,5,6,9,8)
)

nested <- df %>%
  group_by(category) %>%
  nest()

print(nested)
cat('Rows per category B:', nrow(nested$data[[2]]))

ネストしたデータフレームでの map()

データをネストしたら、purrr::map() を使って各小さなデータフレームに関数を適用します。関数は一度に1つのデータフレームを受け取り、結果は新しいリスト列になります。結果は適合済みモデルになることがよくあります。

library(tidyr)
library(dplyr)
library(purrr)

df <- data.frame(
  group = c('A','A','A','B','B','B'),
  x = c(1,2,3,1,2,3),
  y = c(2.1,4.0,5.9,3.2,5.8,9.1)
)

models <- df %>%
  group_by(group) %>%
  nest() %>%
  mutate(model = map(data, ~lm(y ~ x, data = .x)))

print(models)

map() によるモデル結果の抽出

グループごとにモデルを適合させた後、broom::tidy() や coef() などの関数と map() を組み合わせると、各モデルから結果を抽出できます。出力は別のリスト列となり、後でアンネストできます。

library(tidyr)
library(dplyr)
library(purrr)

df <- data.frame(
  group = c('A','A','A','B','B','B'),
  x = c(1,2,3,1,2,3),
  y = c(2.1,4.0,5.9,3.2,5.8,9.1)
)

df %>%
  group_by(group) %>%
  nest() %>%
  mutate(
    model = map(data, ~lm(y ~ x, data = .x)),
    r_squared = map_dbl(model, ~summary(.x)$r.squared),
    intercept = map_dbl(model, ~coef(.x)[1]),
    slope = map_dbl(model, ~coef(.x)[2])
  ) %>%
  select(group, r_squared, intercept, slope)

unnest() — リスト列の展開

unnest(df, cols = data) は nest() の逆の操作です。リスト列を通常の列に展開し、必要に応じて識別子列を繰り返します。アンネストするリスト列は cols で指定します。

library(tidyr)
library(dplyr)

nested <- data.frame(
  region = c('East','West')
)
nested$data <- list(
  data.frame(month=1:3, sales=c(100,120,110)),
  data.frame(month=1:2, sales=c(200,190))
)

unnested <- unnest(nested, cols = data)
print(unnested)

unnest_longer() — リストを行に展開

unnest_longer(df, col) は、リスト列を展開し、リストの各要素を1行にします。データフレームを想定する unnest() とは異なり、unnest_longer() はベクトルまたはスカラーのリストを処理できます。

library(tidyr)

df <- data.frame(
  person = c('Alice','Bob','Carol')
)
df$skills <- list(
  c('R','Python','SQL'),
  c('Excel','Tableau'),
  c('R','Julia','Stan','BUGS')
)

unnest_longer(df, skills)

unnest_wider() — リストを列に展開

unnest_wider(df, col) は、各リスト要素を複数の新しい列に展開します。リストには名前付き要素が必要で、その名前が列名になります。ネストしたJSONのような構造に便利です。

library(tidyr)

df <- data.frame(id = 1:3)
df$info <- list(
  list(name='Alice', age=30, city='NYC'),
  list(name='Bob', age=25, city='LA'),
  list(name='Carol', age=35, city='Chicago')
)

unnest_wider(df, info)

ネスト処理の完全なワークフローパターン

ネストしたデータフレームを扱う完全なワークフローは、group_by() + nest() → map() で関数を適用 → 結果を抽出 → unnest() でフラットなデータフレームに戻す、という流れです。このパターンにより、グループごとにあらゆる分析を実行できます。

library(tidyr)
library(dplyr)
library(purrr)

df <- data.frame(
  region = c('East','East','East','West','West','West'),
  month = c(1,2,3,1,2,3),
  revenue = c(100,120,115,200,195,210)
)

df %>%
  group_by(region) %>%
  nest() %>%
  mutate(
    mean_rev = map_dbl(data, ~mean(.x$revenue)),
    trend = map_dbl(data, ~coef(lm(revenue~month, data=.x))[2])
  ) %>%
  select(region, mean_rev, trend)

複数列のネスト

ネストしたデータフレームに含める列は、選択して指定できます。nest(data = c(...)) で列を明示的に指定してください。指定しなかった列は、リスト列とともに外側のデータフレームの通常の列として残ります。

library(tidyr)
library(dplyr)

df <- data.frame(
  region = c('East','East','West','West'),
  year = c(2023,2024,2023,2024),
  q1 = c(100,110,200,210),
  q2 = c(105,115,195,215),
  target = c(105,112,198,212)
)

# Only nest quarterly data, keep target as outer column
nested <- df %>%
  group_by(region, year) %>%
  nest(quarters = c(q1, q2))

print(nested)

ネストしたデータフレームを使う場面

ネストしたデータフレームは、グループごとに同じモデルを適合させる場合、グループ単位のシミュレーションを実行する場合、サブセットに複雑な変換を適用する場合、JSONのような階層データを扱う場合に特に適しています。グループ固有のデータを、グループレベルのメタデータとともに整理して保持できます。

library(tidyr)
library(dplyr)
library(purrr)

# Bootstrap confidence interval per group
df <- data.frame(
  group = c('A','A','A','A','B','B','B','B'),
  value = c(10,12,11,13,20,22,19,21)
)

set.seed(42)
df %>%
  group_by(group) %>%
  nest() %>%
  mutate(
    boot_means = map(data, function(d) {
      replicate(100, mean(sample(d$value, replace=TRUE)))
    }),
    ci_low = map_dbl(boot_means, ~quantile(.x, 0.025)),
    ci_high = map_dbl(boot_means, ~quantile(.x, 0.975))
  ) %>%
  select(group, ci_low, ci_high)

確認問題

データフレームのリスト列をフラットなデータフレームに戻す正しい方法は何ですか?

まとめ: ネストとアンネスト

ネストしたデータフレームのワークフローにおける重要なポイント:

  • nest(data = c(cols)) — 列をグループごとのデータフレームのリスト列にまとめます
  • group_by() + nest() — グループ単位でネストする標準的なパターンです
  • map(nested$data, fn) — ネストした各データフレームに任意の関数を適用します
  • unnest(cols = data) — データフレームのリスト列をフラットな形式に戻します
  • unnest_longer(col) — ベクトルまたはスカラーのリストを行に展開します
  • unnest_wider(col) — 名前付きリストを列に展開します
  • グループごとのモデリング、ブートストラップ、JSONデータ処理に適しています
library(tidyr)
library(dplyr)
library(purrr)

data.frame(
  team = c('A','A','B','B'),
  x = c(1,2,1,2),
  y = c(2,4,3,6)
) %>%
  group_by(team) %>%
  nest() %>%
  mutate(
    model = map(data, ~lm(y ~ x, data = .x)),
    slope = map_dbl(model, ~coef(.x)['x'])
  ) %>%
  select(team, slope)

よくある質問

「データフレームのネストとアンネスト」レッスンは無料ですか?

はい。「データフレームのネストとアンネスト」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、R Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 R Academyコースには全4レッスンが含まれています。

「データフレームのネストとアンネスト」で何を学びますか?

nest()とunnest()を使い、tidyなワークフローでリスト列を扱います。 ブラウザで直接実行するハンズオンコードでR Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

R Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのR Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「データフレームのネストとアンネスト」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このR Academyレッスンでコードを書いて実行できますか?

はい。すべてのR Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. pivot_longer()によるワイド形式からロング形式への変換
  2. pivot_wider()によるロング形式からワイド形式への変換
  3. 文字列列のためのseparate()とunite()
  4. データフレームのネストとアンネスト
← R Academyに戻る