データフレームのネストとアンネスト
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 elementnest() — ネストしたデータフレームの作成
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 datagroup_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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- pivot_longer()によるワイド形式からロング形式への変換
- pivot_wider()によるロング形式からワイド形式への変換
- 文字列列のためのseparate()とunite()
- データフレームのネストとアンネスト