0Pricing
R Academy · Aula

Aninhando e desaninhando quadros de dados

Use nest() e unnest() para trabalhar com colunas de listas em fluxos organizados.

Aninhando e desaninhando quadros de dados é uma aula grátis de R Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de R Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de R Academy inclui 4 aulas no total.

Colunas de listas e dados aninhados

Uma coluna de listas é uma coluna de um quadro de dados em que cada célula contém um objeto R (um vetor, quadro de dados, modelo ou lista). Isso permite armazenar subdados estruturados junto a outras colunas, possibilitando fluxos de trabalho avançados por grupo.

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() — Criação de quadros de dados aninhados

nest(df, data = c(col1, col2)) agrupa as linhas pelas colunas não aninhadas e reúne as colunas especificadas em uma coluna de listas de quadros de dados. Há uma linha por grupo, cada uma contendo um pequeno quadro de dados.

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() com group_by()

O padrão mais comum é usar group_by() e depois nest() para criar uma linha por grupo, reunindo todas as colunas restantes em uma coluna de listas data. Isso equivale a nest(.by = group_col) nas versões mais recentes do tidyr.

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() com quadros de dados aninhados

Depois de aninhar os dados, use purrr::map() para aplicar uma função a cada pequeno quadro de dados. A função recebe um quadro de dados por vez, e os resultados tornam-se uma nova coluna de listas — frequentemente contendo um modelo ajustado.

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)

Extração de resultados de modelos com map()

Depois de ajustar modelos por grupo, use map() com funções como broom::tidy() ou coef() para extrair os resultados de cada modelo. O resultado é outra coluna de listas que pode ser expandida posteriormente.

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() — Expansão de colunas de listas

unnest(df, cols = data) é o inverso de nest(). Ele expande a coluna de listas novamente em colunas regulares, repetindo as colunas identificadoras conforme necessário. Use cols para especificar qual coluna de listas deve ser expandida.

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() — Expansão de uma lista em linhas

unnest_longer(df, col) expande uma coluna de listas para que cada elemento da lista se torne uma linha. Diferentemente de unnest(), que espera quadros de dados, unnest_longer() funciona com listas de vetores ou valores escalares.

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() — Expansão de uma lista em colunas

unnest_wider(df, col) expande cada elemento da lista em um conjunto de novas colunas. A lista deve ter elementos nomeados — os nomes tornam-se nomes de colunas. Isso é útil para estruturas aninhadas semelhantes a 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)

Padrão completo de fluxo de trabalho aninhado

O fluxo de trabalho completo com quadros de dados aninhados é: group_by() + nest() → aplicar funções com map() → extrair resultados → unnest() para voltar a um quadro de dados plano. Esse padrão permite executar qualquer análise por grupo.

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)

Aninhamento de várias colunas

Você pode selecionar quais colunas irão para o quadro de dados aninhado. Especifique-as explicitamente em nest(data = c(...)). As colunas não especificadas permanecem como colunas regulares no quadro de dados externo, junto à coluna de listas.

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)

Quando usar quadros de dados aninhados

Os quadros de dados aninhados são excelentes quando você precisa ajustar o mesmo modelo em vários grupos, executar simulações por grupo, aplicar transformações complexas a subconjuntos ou trabalhar com dados hierárquicos semelhantes a JSON. Eles mantêm os dados específicos de cada grupo organizados junto aos metadados do grupo.

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)

Verificação rápida

Qual é a forma correta de expandir novamente uma coluna de listas de quadros de dados em um quadro de dados plano?

Recapitulação: aninhamento e expansão

Principais aprendizados sobre fluxos de trabalho com quadros de dados aninhados:

  • nest(data = c(cols)) — reúne colunas em uma coluna de listas de quadros de dados, uma por grupo
  • group_by() + nest() — o padrão usual para aninhar por grupo
  • map(nested$data, fn) — aplica qualquer função a cada quadro de dados aninhado
  • unnest(cols = data) — expande a coluna de listas de quadros de dados de volta ao formato plano
  • unnest_longer(col) — expande uma lista de vetores/valores escalares em linhas
  • unnest_wider(col) — expande uma lista nomeada em colunas
  • Ideal para modelagem por grupo, bootstrap e processamento de dados 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)

Perguntas Frequentes

A aula “Aninhando e desaninhando quadros de dados” é grátis?

Sim — o texto completo de “Aninhando e desaninhando quadros de dados” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de R Academy, atualize para CoddyKit PRO. O curso de R Academy inclui 4 aulas no total.

O que vou aprender em “Aninhando e desaninhando quadros de dados”?

Use nest() e unnest() para trabalhar com colunas de listas em fluxos organizados. Você pratica R Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar R Academy?

Nenhuma experiência prévia é necessária. R Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Aninhando e desaninhando quadros de dados”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de R Academy?

Sim. Cada aula de R Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. De formato amplo para longo com pivot_longer()
  2. De formato longo para amplo com pivot_wider()
  3. separate() e unite() para colunas de strings
  4. Aninhando e desaninhando quadros de dados
← Voltar para R Academy