0Pricing
R Academy · 강의

데이터 프레임 중첩 및 중첩 해제

정돈된 작업 흐름에서 목록 열을 다루기 위해 nest()와 unnest()를 사용합니다.

데이터 프레임 중첩 및 중첩 해제은(는) CoddyKit의 무료 R Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 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))는 중첩되지 않은 열을 기준으로 행을 그룹화하고, 지정한 열을 데이터 프레임 목록 열로 묶습니다. 그룹마다 한 행이 만들어지고, 각 행에는 작은 데이터 프레임이 들어갑니다.

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

nest()와 group_by()

가장 일반적인 패턴은 group_by()를 사용한 다음 nest()를 사용하여 그룹마다 한 행을 만들고, 나머지 모든 열을 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()을 사용하여 각 작은 데이터 프레임에 함수를 적용하십시오. 함수는 한 번에 하나의 데이터 프레임을 받고, 결과는 새 목록 열이 됩니다. 이 결과는 적합된 모델인 경우가 많습니다.

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)는 목록 열을 확장하여 목록의 각 요소가 하나의 행이 되도록 합니다. 데이터 프레임을 기대하는 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/7 AI 튜터), CoddyKit PRO로 업그레이드하면 R Academy 강의 전체를 잠금 해제할 수 있습니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“데이터 프레임 중첩 및 중첩 해제”에서 뭘 배우나요?

정돈된 작업 흐름에서 목록 열을 다루기 위해 nest()와 unnest()를 사용합니다. 브라우저에서 직접 실행하는 실습 코드로 R Academy을(를) 배우며, 24/7 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(으)로 돌아가기