A alimentação infantil adequada é fundamental para o desenvolvimento físico e cognitivo das crianças brasileiras. No Brasil, existem grandes disparidades regionais e socioeconômicas que afetam diretamente a qualidade da alimentação e o estado nutricional infantil. Compreender os padrões alimentares das crianças brasileiras, especialmente nos primeiros anos de vida, é crucial para:
Este projeto é relevante porque oferece insights baseados em dados para melhorar a saúde pública infantil no Brasil.
Este projeto utilizará o ENANI 2019 (Estudo Nacional de Alimentação e Nutrição Infantil) (Ministério da Saúde do Brasil 2019), um conjunto de dados representativo nacional que contém informações detalhadas sobre:
A metodologia empregada inclui:
Utilizaremos técnicas de ciência de dados exploratória com foco em:
tidyverseggplot2Esta abordagem permitirá identificar padrões não evidentes nos dados brutos e gerar insights acionáveis.
# Manipulação de dados
library(tidyverse) # Conjunto de pacotes para ciência de dados (dplyr, ggplot2, etc)
library(data.table) # Leitura eficiente de arquivos grandes
# Limpeza e transformação
library(janitor) # Limpeza de nomes de colunas e dados
library(lubridate) # Manipulação de datas
# Visualização
library(ggplot2) # Gráficos avançados
library(scales) # Formatação de escalas em gráficos
library(patchwork) # Combinação de múltiplos gráficos
library(viridis) # Paletas de cores acessíveis
# Tabelas e resumos
library(knitr) # Tabelas formatadas
library(kableExtra) # Tabelas HTML estilizadas
library(summarytools) # Estatísticas descritivas
# Análise
library(corrplot) # Matrizes de correlação
library(skimr) # Resumo rápido de dados
Fonte Original: ENANI 2019 - Kaggle (Silva 2019)
Descrição da Fonte:
O ENANI 2019 (Estudo Nacional de Alimentação e Nutrição Infantil) (Ministério da Saúde do Brasil 2019) foi conduzido pelo Ministério da Saúde do Brasil em parceria com universidades brasileiras. O estudo teve como objetivo:
# Caminho do arquivo
arquivo <- "data/data_bioq_calib_anon_1a.csv"
# Leitura do arquivo CSV (usando data.table para eficiência)
dados_raw <- fread(arquivo, encoding = "UTF-8")
Dimensões do Dataset Original:
tibble(
Métrica = c("Número de Linhas", "Número de Colunas"),
Valor = c(nrow(dados_raw), ncol(dados_raw))
) %>%
kable() %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| Métrica | Valor |
|---|---|
| Número de Linhas | 14558 |
| Número de Colunas | 741 |
# Análise de valores ausentes
na_percent <- colSums(is.na(dados_raw)) / nrow(dados_raw) * 100
na_top20 <- head(sort(na_percent, decreasing = TRUE), 20)
# Criar tabela informativa
tibble(
dimensao = c("Linhas (registros)", "Colunas (variáveis)"),
valor = c(nrow(dados_raw), ncol(dados_raw))
) %>%
kable(caption = "Dimensões do Dataset Bruto ENANI 2019") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| dimensao | valor |
|---|---|
| Linhas (registros) | 14558 |
| Colunas (variáveis) | 741 |
# Top 20 colunas com mais NAs
tibble(
variavel = names(na_top20),
percentual_na = round(na_top20, 1)
) %>%
kable(caption = "Top 20 Variáveis com Maior Percentual de NAs") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| variavel | percentual_na |
|---|---|
| vd_mielo_final | 100.0 |
| vd_mielop_final | 100.0 |
| vd_meta_final | 100.0 |
| vd_metap_final | 100.0 |
| vd_linftp_final | 99.8 |
| vd_linfat_final | 99.8 |
| t06b_qual_das_pecas | 99.6 |
| s23a_peso_medida4 | 99.5 |
| s23_peso_medida3 | 99.4 |
| s24_peso_padrao | 99.4 |
| s22_permissao_peso | 99.3 |
| s21a_pode_informar_peso | 99.2 |
| s21c_idade_recalculada_peso | 99.2 |
| i110_59m_conta | 98.2 |
| i111_59m_desenha | 98.2 |
| i112_59m_plural | 98.2 |
| i113_59m_ontem | 98.2 |
| i114_59m_urinar | 98.2 |
| i115_59m_regras | 98.2 |
| i116_59m_copia | 98.2 |
Justificativa da limpeza: Com 741 variáveis, precisamos selecionar apenas as mais relevantes para análise nutricional. Focaremos em:
# Seleção de variáveis relevantes para análise nutricional
dados_limpo <- dados_raw %>%
select(
# Identificadores
id_anon, id_domic_anon,
# Geografia
a00_regiao, a11_situacao,
# Dados da criança
b02_sexo, b04_idade, b05a_idade_em_meses,
# Alimentação infantil (primeiros 2 anos)
e01_leite_peito, e02_agua, e11_suco, e12_fruta_inteira,
e16_comida_sal, e21_arroz, e26_feijao, e27_carne,
e31_salgadinhos, e33_refrigerante, e36_bala,
# Dados de nascimento e saúde
h01_semanas_gravidez, h02_peso, h03_altura, h04_parto,
h05_chupeta_usou,
# Dados antropométricos atuais (buscando padrões de coluna)
matches("peso.*atual|altura.*atual|imc", ignore.case = TRUE)
)
tibble(
metrica = c("Variáveis selecionadas", "Registros mantidos", "Taxa de redução"),
valor = c(
paste0(ncol(dados_limpo), " de ", ncol(dados_raw)),
nrow(dados_limpo),
paste0(round((1 - ncol(dados_limpo)/ncol(dados_raw)) * 100, 1), "%")
)
) %>%
kable(caption = "Resumo da Seleção de Variáveis") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| metrica | valor |
|---|---|
| Variáveis selecionadas | 25 de 741 |
| Registros mantidos | 14558 |
| Taxa de redução | 96.6% |
# Padronização de nomes de colunas
dados_limpo <- dados_limpo %>%
clean_names() %>% # Remove caracteres especiais e padroniza
rename(
regiao = a00_regiao,
situacao = a11_situacao,
sexo = b02_sexo,
idade_anos = b04_idade,
idade_meses = b05a_idade_em_meses,
leite_materno = e01_leite_peito,
agua = e02_agua,
suco = e11_suco,
fruta = e12_fruta_inteira,
comida_sal = e16_comida_sal,
arroz = e21_arroz,
feijao = e26_feijao,
carne = e27_carne,
salgadinho = e31_salgadinhos,
refrigerante = e33_refrigerante,
bala = e36_bala,
semanas_gestacao = h01_semanas_gravidez,
peso_nascer = h02_peso,
altura_nascer = h03_altura,
tipo_parto = h04_parto,
usou_chupeta = h05_chupeta_usou
)
tibble(
nome_padronizado = head(names(dados_limpo), 20)
) %>%
kable(caption = "Primeiras 20 Variáveis com Nomes Padronizados") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| nome_padronizado |
|---|
| id_anon |
| id_domic_anon |
| regiao |
| situacao |
| sexo |
| idade_anos |
| idade_meses |
| leite_materno |
| agua |
| suco |
| fruta |
| comida_sal |
| arroz |
| feijao |
| carne |
| salgadinho |
| refrigerante |
| bala |
| semanas_gestacao |
| peso_nascer |
# Conversão de tipos de dados
dados_limpo <- dados_limpo %>%
mutate(
# Conversão de fatores
regiao = as.factor(regiao),
situacao = as.factor(situacao),
sexo = as.factor(sexo),
# Conversão de variáveis numéricas
idade_anos = as.numeric(idade_anos),
idade_meses = as.numeric(str_extract(idade_meses, "\\d+")), # O dado é em formato de string (ex.: "22 meses"), extraimos apenas o número
peso_nascer = as.numeric(peso_nascer),
altura_nascer = as.numeric(altura_nascer),
semanas_gestacao = as.numeric(semanas_gestacao),
# Conversão de variáveis binárias (Sim/Não)
across(c(leite_materno, agua, suco, fruta, comida_sal,
arroz, feijao, carne, salgadinho, refrigerante, bala),
~case_when(
. == "Sim" ~ TRUE,
. == "Não" ~ FALSE,
TRUE ~ NA
))
)
# Exemplos de valores extraídos
dados_limpo %>%
select(id_anon, idade_meses) %>%
head(10) %>%
kable(caption = "Exemplos de Idade em Meses Extraída") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| id_anon | idade_meses |
|---|---|
| 10951000402 | 22 |
| 10951000403 | 51 |
| 10951003402 | 30 |
| 10951003403 | 56 |
| 10951009202 | 10 |
| 10951009303 | 5 |
| 10951009402 | 44 |
| 10951023902 | 49 |
| 10951031203 | 16 |
| 10951032203 | 5 |
# Estatísticas descritivas
tibble(
estatistica = c("Mínimo", "1º Quartil", "Mediana", "Média", "3º Quartil", "Máximo", "NAs"),
valor = c(
min(dados_limpo$idade_meses, na.rm = TRUE),
quantile(dados_limpo$idade_meses, 0.25, na.rm = TRUE),
median(dados_limpo$idade_meses, na.rm = TRUE),
round(mean(dados_limpo$idade_meses, na.rm = TRUE), 1),
quantile(dados_limpo$idade_meses, 0.75, na.rm = TRUE),
max(dados_limpo$idade_meses, na.rm = TRUE),
sum(is.na(dados_limpo$idade_meses))
)
) %>%
kable(caption = "Estatísticas Descritivas de Idade em Meses") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| estatistica | valor |
|---|---|
| Mínimo | 0.0 |
| 1º Quartil | 13.0 |
| Mediana | 28.0 |
| Média | 28.2 |
| 3º Quartil | 44.0 |
| Máximo | 59.0 |
| NAs | 0.0 |
na_summary <- dados_limpo %>%
summarise(across(everything(), ~sum(is.na(.)))) %>%
pivot_longer(everything(), names_to = "variavel", values_to = "n_nas") %>%
mutate(perc_nas = round(n_nas / nrow(dados_limpo) * 100, 1)) %>%
arrange(desc(perc_nas)) %>%
filter(perc_nas > 10)
na_summary %>%
kable(caption = "Variáveis com Mais de 10% de Valores Ausentes") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| variavel | n_nas | perc_nas |
|---|---|---|
| vd_imc_mae | 1811 | 12.4 |
Decisões sobre NAs: Manteremos os NAs por enquanto, pois muitas variáveis são contextuais (ex: perguntas sobre alimentação aplicadas apenas a certas idades). Análises específicas filtrarão conforme necessário.
# Criação de variáveis derivadas e categóricas
dados_limpo <- dados_limpo %>%
mutate(
# Faixa etária
faixa_etaria = case_when(
idade_meses < 6 ~ "0-5 meses",
idade_meses < 12 ~ "6-11 meses",
idade_meses < 24 ~ "12-23 meses",
idade_meses < 36 ~ "24-35 meses",
idade_meses < 48 ~ "36-47 meses",
TRUE ~ "48-59 meses"
) %>% factor(levels = c("0-5 meses", "6-11 meses", "12-23 meses",
"24-35 meses", "36-47 meses", "48-59 meses")),
# Classificação de peso ao nascer
classificacao_peso_nascer = case_when(
peso_nascer < 2500 ~ "Baixo peso",
peso_nascer >= 2500 & peso_nascer < 4000 ~ "Adequado",
peso_nascer >= 4000 ~ "Macrossomia",
TRUE ~ "Não informado"
) %>% factor(levels = c("Baixo peso", "Adequado", "Macrossomia", "Não informado")),
# Idade gestacional
classificacao_gestacao = case_when(
semanas_gestacao < 37 ~ "Prematuro",
semanas_gestacao >= 37 & semanas_gestacao <= 42 ~ "A termo",
semanas_gestacao > 42 ~ "Pós-termo",
TRUE ~ "Não informado"
) %>% factor(levels = c("Prematuro", "A termo", "Pós-termo", "Não informado")),
# Índice de alimentos saudáveis (soma de alimentos básicos)
alimentos_saudaveis = rowSums(select(., arroz, feijao, carne, fruta), na.rm = TRUE),
# Índice de alimentos ultraprocessados
alimentos_ultraprocessados = rowSums(select(., salgadinho, refrigerante, bala), na.rm = TRUE),
# Razão saudável/ultraprocessado
razao_alimentar = ifelse(alimentos_ultraprocessados > 0,
alimentos_saudaveis / alimentos_ultraprocessados,
alimentos_saudaveis)
)
tibble(
variavel = c("faixa_etaria", "classificacao_peso_nascer", "classificacao_gestacao",
"alimentos_saudaveis", "alimentos_ultraprocessados", "razao_alimentar"),
tipo = c("Categórica", "Categórica", "Categórica", "Numérica", "Numérica", "Numérica"),
descricao = c(
"6 faixas etárias (0-5, 6-11, 12-23, 24-35, 36-47, 48-59 meses)",
"Baixo peso (<2500g), Adequado, Macrossomia (>4000g) [@oms2021]",
"Prematuro (<37sem), A termo, Pós-termo (>42sem) [@oms2021]",
"Soma de arroz + feijão + carne + fruta consumidos",
"Soma de salgadinho + refrigerante + bala consumidos",
"Razão entre alimentos saudáveis e ultraprocessados [@guia_alimentar2021]"
)
) %>%
kable(caption = "Variáveis Derivadas Criadas") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| variavel | tipo | descricao |
|---|---|---|
| faixa_etaria | Categórica | 6 faixas etárias (0-5, 6-11, 12-23, 24-35, 36-47, 48-59 meses) |
| classificacao_peso_nascer | Categórica | Baixo peso (<2500g), Adequado, Macrossomia (>4000g) (Organização Mundial da Saúde 2021) |
| classificacao_gestacao | Categórica | Prematuro (<37sem), A termo, Pós-termo (>42sem) (Organização Mundial da Saúde 2021) |
| alimentos_saudaveis | Numérica | Soma de arroz + feijão + carne + fruta consumidos |
| alimentos_ultraprocessados | Numérica | Soma de salgadinho + refrigerante + bala consumidos |
| razao_alimentar | Numérica | Razão entre alimentos saudáveis e ultraprocessados (Ministério da Saúde do Brasil 2021) |
# Filtrar apenas crianças com dados mínimos essenciais
dados_final <- dados_limpo %>%
filter(
!is.na(idade_meses),
!is.na(sexo),
!is.na(regiao)
)
tibble(
metrica = c("Registros após filtros", "Variáveis finais", "Registros removidos"),
valor = c(
nrow(dados_final),
ncol(dados_final),
nrow(dados_limpo) - nrow(dados_final)
)
) %>%
kable(caption = "Resumo do Dataset Final") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| metrica | valor |
|---|---|
| Registros após filtros | 14558 |
| Variáveis finais | 31 |
| Registros removidos | 0 |
# Amostra dos dados limpos
dados_final %>%
select(id_anon, regiao, sexo, idade_meses, faixa_etaria,
leite_materno, alimentos_saudaveis, alimentos_ultraprocessados) %>%
head(20) %>%
kable(caption = "Amostra do Dataset ENANI 2019 Limpo") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = FALSE)
| id_anon | regiao | sexo | idade_meses | faixa_etaria | leite_materno | alimentos_saudaveis | alimentos_ultraprocessados |
|---|---|---|---|---|---|---|---|
| 10951000402 | Norte | Masculino | 22 | 12-23 meses | FALSE | 4 | 2 |
| 10951000403 | Norte | Feminino | 51 | 48-59 meses | FALSE | 3 | 2 |
| 10951003402 | Norte | Feminino | 30 | 24-35 meses | FALSE | 2 | 2 |
| 10951003403 | Norte | Masculino | 56 | 48-59 meses | FALSE | 2 | 0 |
| 10951009202 | Norte | Feminino | 10 | 6-11 meses | TRUE | 3 | 1 |
| 10951009303 | Norte | Masculino | 5 | 0-5 meses | TRUE | 1 | 0 |
| 10951009402 | Norte | Masculino | 44 | 36-47 meses | FALSE | 2 | 1 |
| 10951023902 | Norte | Feminino | 49 | 48-59 meses | FALSE | 3 | 2 |
| 10951031203 | Norte | Masculino | 16 | 12-23 meses | TRUE | 4 | 0 |
| 10951032203 | Norte | Feminino | 5 | 0-5 meses | FALSE | 0 | 0 |
| 10951034502 | Norte | Feminino | 49 | 48-59 meses | FALSE | 3 | 0 |
| 10951034503 | Norte | Feminino | 17 | 12-23 meses | FALSE | 2 | 0 |
| 10951035503 | Norte | Masculino | 18 | 12-23 meses | TRUE | 3 | 1 |
| 10951035504 | Norte | Feminino | 50 | 48-59 meses | FALSE | 3 | 0 |
| 11180012904 | Norte | Masculino | 30 | 24-35 meses | FALSE | 4 | 1 |
| 11180014504 | Norte | Feminino | 20 | 12-23 meses | TRUE | 4 | 2 |
| 11180018002 | Norte | Feminino | 22 | 12-23 meses | FALSE | 4 | 1 |
| 11180018003 | Norte | Feminino | 58 | 48-59 meses | FALSE | 4 | 1 |
| 11180019904 | Norte | Feminino | 38 | 36-47 meses | FALSE | 3 | 1 |
| 11180019905 | Norte | Feminino | 16 | 12-23 meses | TRUE | 3 | 0 |
# Distribuição por Região
regiao_dist <- dados_final %>%
count(regiao, name = "frequencia") %>%
mutate(percentual = round(frequencia / sum(frequencia) * 100, 1))
regiao_dist %>%
kable(caption = "Distribuição por Região") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| regiao | frequencia | percentual |
|---|---|---|
| Centro-Oeste | 3141 | 21.6 |
| Nordeste | 2766 | 19.0 |
| Norte | 2692 | 18.5 |
| Sudeste | 3118 | 21.4 |
| Sul | 2841 | 19.5 |
# Distribuição por Sexo
sexo_dist <- dados_final %>%
count(sexo, name = "frequencia") %>%
mutate(percentual = round(frequencia / sum(frequencia) * 100, 1))
sexo_dist %>%
kable(caption = "Distribuição por Sexo") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| sexo | frequencia | percentual |
|---|---|---|
| Feminino | 7149 | 49.1 |
| Masculino | 7409 | 50.9 |
# Distribuição por Faixa Etária
faixa_dist <- dados_final %>%
count(faixa_etaria, name = "frequencia") %>%
mutate(percentual = round(frequencia / sum(frequencia) * 100, 1))
faixa_dist %>%
kable(caption = "Distribuição por Faixa Etária") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| faixa_etaria | frequencia | percentual |
|---|---|---|
| 0-5 meses | 1960 | 13.5 |
| 6-11 meses | 1415 | 9.7 |
| 12-23 meses | 2947 | 20.2 |
| 24-35 meses | 2714 | 18.6 |
| 36-47 meses | 2810 | 19.3 |
| 48-59 meses | 2712 | 18.6 |
# Distribuição por Situação
situacao_dist <- dados_final %>%
count(situacao, name = "frequencia") %>%
mutate(percentual = round(frequencia / sum(frequencia) * 100, 1))
situacao_dist %>%
kable(caption = "Distribuição Urbano vs Rural") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| situacao | frequencia | percentual |
|---|---|---|
| Rural | 308 | 2.1 |
| Urbano | 14250 | 97.9 |
dados_final %>%
select(idade_meses, peso_nascer, altura_nascer, semanas_gestacao,
alimentos_saudaveis, alimentos_ultraprocessados) %>%
summary() %>%
kable(caption = "Resumo Estatístico de Variáveis Numéricas") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| idade_meses | peso_nascer | altura_nascer | semanas_gestacao | alimentos_saudaveis | alimentos_ultraprocessados | |
|---|---|---|---|---|---|---|
| Min. : 0.00 | Min. : 250 | Min. :27.00 | Min. :26.00 | Min. :0.000 | Min. :0.0000 | |
| 1st Qu.:13.00 | 1st Qu.:2890 | 1st Qu.:47.00 | 1st Qu.:38.00 | 1st Qu.:2.000 | 1st Qu.:0.0000 | |
| Median :28.00 | Median :3215 | Median :49.00 | Median :39.00 | Median :3.000 | Median :0.0000 | |
| Mean :28.18 | Mean :3193 | Mean :48.43 | Mean :38.76 | Mean :2.491 | Mean :0.4803 | |
| 3rd Qu.:44.00 | 3rd Qu.:3555 | 3rd Qu.:50.00 | 3rd Qu.:40.00 | 3rd Qu.:4.000 | 3rd Qu.:1.0000 | |
| Max. :59.00 | Max. :6100 | Max. :63.00 | Max. :43.00 | Max. :4.000 | Max. :3.0000 |
Resumo consolidado: O dataset final contém aproximadamente 14.500 crianças brasileiras com informações sobre alimentação, dados de nascimento e características demográficas. A maioria das variáveis alimentares apresenta NAs devido à aplicabilidade contextual por idade.
# Gráfico de distribuição por região
p1 <- dados_final %>%
count(regiao) %>%
mutate(regiao = fct_reorder(regiao, n)) %>%
ggplot(aes(x = regiao, y = n, fill = regiao)) +
geom_col(show.legend = FALSE) +
geom_text(aes(label = n), hjust = -0.2, size = 3.5) +
coord_flip() +
scale_fill_viridis_d(option = "D") +
labs(
title = "Distribuição de Crianças por Região do Brasil",
subtitle = "ENANI 2019 - Amostra Nacional",
x = NULL,
y = "Número de Crianças"
) +
theme_minimal() +
theme(plot.title = element_text(face = "bold", size = 14))
# Gráfico de situação (Urbano/Rural)
p2 <- dados_final %>%
count(situacao) %>%
ggplot(aes(x = "", y = n, fill = situacao)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
geom_text(aes(label = paste0(round(n/sum(n)*100, 1), "%")),
position = position_stack(vjust = 0.5), size = 4) +
scale_fill_manual(values = c("#2E7D32", "#FFB300")) +
labs(
title = "Distribuição Urbano vs Rural",
fill = "Situação"
) +
theme_void() +
theme(plot.title = element_text(face = "bold", size = 14, hjust = 0.5))
# Combinar gráficos
p1 + p2 + plot_layout(widths = c(2, 1))
Insight: A distribuição geográfica mostra a representatividade da amostra em todas as regiões brasileiras, com predominância urbana refletindo a realidade demográfica do país. Os dados são provenientes do ENANI 2019 (Ministério da Saúde do Brasil 2019), um estudo de base populacional representativo do Brasil.
Contexto: Este é nosso ponto de partida — uma amostra robusta e representativa que permite generalizações para todo o país. A predominância urbana (>90%) reflete a realidade brasileira, mas também alerta para a necessidade de atenção especial às populações rurais (sub-representadas na amostra). Há também uma sub-representação nos dados de crianças das regiões Sul, Norte e Nordeste se comparado com o Centro-Oeste e Sudeste.
# Pirâmide etária por sexo
dados_final %>%
filter(!is.na(sexo), !is.na(faixa_etaria)) %>%
count(sexo, faixa_etaria) %>%
mutate(
n = ifelse(sexo == "Masculino", -n, n),
faixa_etaria = fct_rev(faixa_etaria)
) %>%
ggplot(aes(x = faixa_etaria, y = n, fill = sexo)) +
geom_col() +
coord_flip() +
scale_y_continuous(
labels = function(x) abs(x),
breaks = seq(-3000, 3000, 1000)
) +
scale_fill_manual(values = c("Feminino" = "#E91E63", "Masculino" = "#2196F3")) +
labs(
title = "Pirâmide Etária das Crianças por Sexo",
subtitle = "Distribuição equilibrada entre os gêneros",
x = "Faixa Etária",
y = "Número de Crianças",
fill = "Sexo"
) +
theme_minimal() +
theme(
plot.title = element_text(face = "bold", size = 14),
legend.position = "bottom"
)
Insight: A distribuição por sexo é praticamente equilibrada em todas as faixas etárias, indicando boa representatividade da amostra.
# Distribuição de peso ao nascer
p1 <- dados_final %>%
filter(!is.na(peso_nascer), peso_nascer > 500, peso_nascer < 6000) %>%
ggplot(aes(x = peso_nascer)) +
geom_histogram(aes(y = after_stat(density)), bins = 50, fill = "#4CAF50", alpha = 0.7) +
geom_density(color = "#1B5E20", linewidth = 1) +
geom_vline(xintercept = 2500, linetype = "dashed", color = "red", linewidth = 1) +
geom_vline(xintercept = 4000, linetype = "dashed", color = "orange", linewidth = 1) +
annotate("text", x = 2500, y = 0.0012, label = "Baixo peso\n(<2500g)",
vjust = -0.5, color = "red", size = 3) +
annotate("text", x = 4000, y = 0.0012, label = "Macrossomia\n(>4000g)",
vjust = -0.5, color = "orange", size = 3) +
labs(
title = "Distribuição de Peso ao Nascer",
x = "Peso ao Nascer (gramas)",
y = "Densidade"
) +
theme_minimal()
# Classificação de peso
p2 <- dados_final %>%
filter(classificacao_peso_nascer != "Não informado") %>%
count(classificacao_peso_nascer) %>%
mutate(perc = n/sum(n)*100) %>%
ggplot(aes(x = "", y = perc, fill = classificacao_peso_nascer)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
geom_text(aes(label = paste0(round(perc, 1), "%")),
position = position_stack(vjust = 0.5), size = 4) +
scale_fill_manual(
values = c("Baixo peso" = "#F44336", "Adequado" = "#4CAF50", "Macrossomia" = "#FF9800")
) +
labs(
title = "Classificação de Peso",
fill = "Categoria"
) +
theme_void() +
theme(plot.title = element_text(face = "bold", hjust = 0.5))
p1 + p2
Insight: Aproximadamente 85% das crianças nascem saudáveis, demonstrando que o acompanhamento pré-natal brasileiro tem alcançado resultados positivos. No entanto, os 10% com baixo peso representam um grupo vulnerável que demanda atenção especial desde o nascimento. Esta é a nossa linha de base — um bom ponto de partida que será gradualmente comprometido pelos hábitos alimentares inadequados. As classificações seguem os critérios estabelecidos pela OMS (Organização Mundial da Saúde 2021), onde peso inferior a 2500g é considerado baixo peso e superior a 4000g caracteriza macrossomia.
# Idade gestacional
p1 <- dados_final %>%
filter(!is.na(semanas_gestacao), semanas_gestacao >= 20, semanas_gestacao <= 45) %>%
ggplot(aes(x = semanas_gestacao)) +
geom_histogram(bins = 30, fill = "#3F51B5", alpha = 0.7, color = "white") +
geom_vline(xintercept = 37, linetype = "dashed", color = "red", linewidth = 1) +
geom_vline(xintercept = 42, linetype = "dashed", color = "orange", linewidth = 1) +
annotate("text", x = 34, y = 800, label = "Prematuro", color = "red", size = 3.5) +
annotate("text", x = 39.5, y = 800, label = "A termo", color = "darkgreen", size = 3.5) +
labs(
title = "Distribuição de Idade Gestacional",
x = "Semanas de Gestação",
y = "Frequência"
) +
theme_minimal()
# Tipo de parto por região
p2 <- dados_final %>%
filter(!is.na(tipo_parto), !is.na(regiao)) %>%
count(regiao, tipo_parto) %>%
group_by(regiao) %>%
mutate(perc = n/sum(n)*100) %>%
ggplot(aes(x = regiao, y = perc, fill = tipo_parto)) +
geom_col(position = "dodge") +
geom_text(aes(label = paste0(round(perc, 0), "%")),
position = position_dodge(width = 0.9), vjust = -0.5, size = 3) +
scale_fill_brewer(palette = "Set2") +
labs(
title = "Tipo de Parto por Região",
x = "Região",
y = "Percentual (%)",
fill = "Tipo de Parto"
) +
theme_minimal() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
legend.position = "bottom"
)
p1 / p2
Insight: A prevalência de cesarianas é notável em todas as regiões, reflexo da alta taxa brasileira de partos cirúrgicos. A classificação da idade gestacional segue os parâmetros da OMS (Organização Mundial da Saúde 2021), com gestações inferiores a 37 semanas consideradas prematuras e superiores a 42 semanas classificadas como pós-termo.
# Aleitamento materno por faixa etária
dados_final %>%
filter(!is.na(leite_materno), !is.na(faixa_etaria)) %>%
count(faixa_etaria, leite_materno) %>%
group_by(faixa_etaria) %>%
mutate(perc = n/sum(n)*100) %>%
filter(leite_materno == TRUE) %>%
ggplot(aes(x = faixa_etaria, y = perc, group = 1)) +
geom_line(color = "#E91E63", linewidth = 1.5) +
geom_point(color = "#E91E63", size = 4) +
geom_text(aes(label = paste0(round(perc, 1), "%")), vjust = -1, size = 3.5) +
scale_y_continuous(limits = c(0, 100), breaks = seq(0, 100, 20)) +
labs(
title = "Prevalência de Aleitamento Materno por Faixa Etária",
subtitle = "Redução esperada com o aumento da idade",
x = "Faixa Etária",
y = "Percentual com Aleitamento Materno (%)"
) +
theme_minimal() +
theme(
plot.title = element_text(face = "bold", size = 14),
axis.text.x = element_text(angle = 45, hjust = 1)
)
Insight: Este é o primeiro sinal de alerta. A queda acentuada do aleitamento materno após os 12 meses (de ~60% para ~20%) abre as portas para alimentos inadequados. Quanto mais cedo a criança abandona o leite materno, mais vulnerável ela fica à introdução de ultraprocessados. Esta é a primeira ruptura na trajetória nutricional saudável (Organização Mundial da Saúde 2021). A OMS recomenda aleitamento materno exclusivo até os 6 meses e continuado até os 2 anos ou mais (Organização Mundial da Saúde 2021).
Análise Crítica:
# Comparação de consumo por faixa etária
dados_final %>%
filter(!is.na(faixa_etaria)) %>%
group_by(faixa_etaria) %>%
summarise(
saudaveis = mean(alimentos_saudaveis, na.rm = TRUE),
ultraprocessados = mean(alimentos_ultraprocessados, na.rm = TRUE)
) %>%
pivot_longer(cols = c(saudaveis, ultraprocessados),
names_to = "tipo", values_to = "media") %>%
ggplot(aes(x = faixa_etaria, y = media, fill = tipo)) +
geom_col(position = "dodge") +
scale_fill_manual(
values = c("saudaveis" = "#4CAF50", "ultraprocessados" = "#F44336"),
labels = c("Alimentos Saudáveis", "Ultraprocessados")
) +
labs(
title = "Média de Consumo: Alimentos Saudáveis vs Ultraprocessados",
subtitle = "Por faixa etária",
x = "Faixa Etária",
y = "Média de Alimentos Consumidos",
fill = "Tipo"
) +
theme_minimal() +
theme(
plot.title = element_text(face = "bold", size = 14),
axis.text.x = element_text(angle = 45, hjust = 1),
legend.position = "bottom"
)
Insight: Este é o achado mais preocupante da análise. Estamos testemunhando uma transição nutricional negativa: crianças que começam com aleitamento materno e alimentação complementar adequada gradualmente substituem alimentos saudáveis por ultraprocessados. Esta é uma trajetória insustentável que está formando hábitos alimentares prejudiciais nos primeiros anos de vida — exatamente quando o paladar e as preferências se consolidam. A janela crítica está entre 12-36 meses, período em que a deterioração alimentar é mais acentuada. O consumo de ultraprocessados aumenta com a idade, indicando necessidade de intervenções educativas para famílias com crianças maiores. O Guia Alimentar para Crianças Brasileiras (Ministério da Saúde do Brasil 2021) recomenda evitar alimentos ultraprocessados e priorizar alimentos in natura ou minimamente processados na alimentação infantil.
# Criar dataset para análise regional
dados_regional <- dados_final %>%
filter(!is.na(regiao)) %>%
group_by(regiao) %>%
summarise(
n_total = n(),
leite_materno_perc = mean(leite_materno, na.rm = TRUE) * 100,
fruta_perc = mean(fruta, na.rm = TRUE) * 100,
feijao_perc = mean(feijao, na.rm = TRUE) * 100,
refrigerante_perc = mean(refrigerante, na.rm = TRUE) * 100,
salgadinho_perc = mean(salgadinho, na.rm = TRUE) * 100
)
# Heatmap de consumo por região
dados_regional %>%
select(-n_total) %>%
pivot_longer(-regiao, names_to = "alimento", values_to = "percentual") %>%
mutate(
alimento = case_when(
alimento == "leite_materno_perc" ~ "Leite Materno",
alimento == "fruta_perc" ~ "Frutas",
alimento == "feijao_perc" ~ "Feijão",
alimento == "refrigerante_perc" ~ "Refrigerante",
alimento == "salgadinho_perc" ~ "Salgadinho"
)
) %>%
ggplot(aes(x = alimento, y = regiao, fill = percentual)) +
geom_tile(color = "white", linewidth = 1) +
geom_text(aes(label = paste0(round(percentual, 0), "%")),
color = "white", fontface = "bold", size = 4) +
scale_fill_viridis_c(option = "plasma") +
labs(
title = "Padrões Alimentares por Região",
subtitle = "Percentual de consumo de diferentes alimentos",
x = NULL,
y = NULL,
fill = "Percentual (%)"
) +
theme_minimal() +
theme(
plot.title = element_text(face = "bold", size = 14),
axis.text.x = element_text(angle = 45, hjust = 1),
legend.position = "right"
)
Insight: As disparidades regionais não
são apenas geográficas — são reflexos de desigualdades
socioeconômicas e culturais. Algumas regiões apresentam consumo
de ultraprocessados até 30% maior que outras, indicando que políticas
públicas precisam ser customizadas e contextualizadas.
Uma abordagem única para todo o Brasil não será efetiva. É necessário
entender as realidades locais, os hábitos culturais e as condições
socioeconômicas de cada região.
# Matriz de correlação
dados_corr <- dados_final %>%
select(
idade_meses, peso_nascer, altura_nascer, semanas_gestacao,
alimentos_saudaveis, alimentos_ultraprocessados, razao_alimentar
) %>%
na.omit() %>%
cor()
# Visualização da matriz de correlação
corrplot(dados_corr,
method = "color",
type = "upper",
addCoef.col = "black",
tl.col = "black",
tl.srt = 45,
number.cex = 0.8,
col = colorRampPalette(c("#F44336", "white", "#4CAF50"))(200),
title = "Matriz de Correlação entre Variáveis",
mar = c(0,0,2,0))
Insight: As correlações revelam relações esperadas (peso e altura ao nascer) e insights sobre a relação entre idade e padrões alimentares.
Esta análise do ENANI 2019 revela uma narrativa preocupante sobre a transição nutricional infantil no Brasil: crianças que nascem em condições adequadas, mas que progressivamente abandonam práticas alimentares saudáveis em favor de alimentos ultraprocessados.
A maioria das crianças brasileiras (aproximadamente 85%) nasce com peso adequado, demonstrando que o acompanhamento pré-natal tem alcançado bons resultados. No entanto:
A análise também demonstra uma queda acentuada e preocupante do aleitamento materno:
Esta trajetória contraria as recomendações da OMS (Organização Mundial da Saúde 2021), que preconiza aleitamento materno até os 2 anos ou mais. O abandono precoce do aleitamento abre espaço para a entrada de alimentos inadequados.
O achado mais alarmante desta análise é a relação inversamente proporcional entre idade e qualidade alimentar:
Os dados mostram que:
Esta transição contraria todas as recomendações do Guia Alimentar para Crianças Brasileiras (Ministério da Saúde do Brasil 2021), que enfatiza alimentos in natura e minimamente processados.
Com base nos achados, recomenda-se:
Os dados do ENANI 2019 (Ministério da Saúde do Brasil 2019) pintam um retrato do Brasil que equilibra esperança e preocupação:
A janela de oportunidade está nos primeiros 1000 dias de vida (0-3 anos). É neste período que os hábitos alimentares se formam e que as intervenções têm maior impacto.
A mensagem final é clara: Sem ações efetivas e coordenadas, estamos formando uma geração de crianças com hábitos alimentares inadequados, com consequências para a saúde pública nas próximas décadas (obesidade, diabetes, doenças cardiovasculares).
Steffano Pereira | Novembro 2025
Análise realizada com R, tidyverse e ggplot2