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 elementnest() — 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 datanest() 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 grupogroup_by() + nest()— o padrão usual para aninhar por grupomap(nested$data, fn)— aplica qualquer função a cada quadro de dados aninhadounnest(cols = data)— expande a coluna de listas de quadros de dados de volta ao formato planounnest_longer(col)— expande uma lista de vetores/valores escalares em linhasunnest_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
- De formato amplo para longo com pivot_longer()
- De formato longo para amplo com pivot_wider()
- separate() e unite() para colunas de strings
- Aninhando e desaninhando quadros de dados