Essa página implementa o algoritmo desenvolvido por Leal e Martins (2025), sobre imputação de exportações ao nível municipal, para imputar as exportações de café nos municípios mineiros em 2023. Usamos também o pacote comexTL desenvolvido por (Alan) Leal para lidar com os dados de comex brasileiro com maior facilidade no R. Os dados de área colhida do café em 2023 foram obtidos na PAM, como distribuídos pelo Base dos Dados.
# Lista de pacotes necessários
pacotes <- c(
"comexTL", # Dados de comércio exterior
"tidyverse", # Manipulação de dados
"sf", # Dados espaciais
"spdep", # Econometria espacial
"ggplot2", # Gráficos
"leaflet", # Mapas interativos
"plotly", # Gráficos interativos
"DT", # Tabelas interativas
"kableExtra", # Formatação de tabelas
"viridis", # Paletas de cores
"geobr" # Geometrias do Brasil
)
# Instalar pacotes que não estão instalados
novos_pacotes <- pacotes[!(pacotes %in% installed.packages()[,"Package"])]
if(length(novos_pacotes)) install.packages(novos_pacotes)
# Carregar todos os pacotes
lapply(pacotes, library, character.only = TRUE)
## [[1]]
## [1] "comexTL" "stats" "graphics" "grDevices" "utils" "datasets"
## [7] "methods" "base"
##
## [[2]]
## [1] "lubridate" "forcats" "stringr" "dplyr" "purrr" "readr"
## [7] "tidyr" "tibble" "ggplot2" "tidyverse" "comexTL" "stats"
## [13] "graphics" "grDevices" "utils" "datasets" "methods" "base"
##
## [[3]]
## [1] "sf" "lubridate" "forcats" "stringr" "dplyr" "purrr"
## [7] "readr" "tidyr" "tibble" "ggplot2" "tidyverse" "comexTL"
## [13] "stats" "graphics" "grDevices" "utils" "datasets" "methods"
## [19] "base"
##
## [[4]]
## [1] "spdep" "spData" "sf" "lubridate" "forcats" "stringr"
## [7] "dplyr" "purrr" "readr" "tidyr" "tibble" "ggplot2"
## [13] "tidyverse" "comexTL" "stats" "graphics" "grDevices" "utils"
## [19] "datasets" "methods" "base"
##
## [[5]]
## [1] "spdep" "spData" "sf" "lubridate" "forcats" "stringr"
## [7] "dplyr" "purrr" "readr" "tidyr" "tibble" "ggplot2"
## [13] "tidyverse" "comexTL" "stats" "graphics" "grDevices" "utils"
## [19] "datasets" "methods" "base"
##
## [[6]]
## [1] "leaflet" "spdep" "spData" "sf" "lubridate" "forcats"
## [7] "stringr" "dplyr" "purrr" "readr" "tidyr" "tibble"
## [13] "ggplot2" "tidyverse" "comexTL" "stats" "graphics" "grDevices"
## [19] "utils" "datasets" "methods" "base"
##
## [[7]]
## [1] "plotly" "leaflet" "spdep" "spData" "sf" "lubridate"
## [7] "forcats" "stringr" "dplyr" "purrr" "readr" "tidyr"
## [13] "tibble" "ggplot2" "tidyverse" "comexTL" "stats" "graphics"
## [19] "grDevices" "utils" "datasets" "methods" "base"
##
## [[8]]
## [1] "DT" "plotly" "leaflet" "spdep" "spData" "sf"
## [7] "lubridate" "forcats" "stringr" "dplyr" "purrr" "readr"
## [13] "tidyr" "tibble" "ggplot2" "tidyverse" "comexTL" "stats"
## [19] "graphics" "grDevices" "utils" "datasets" "methods" "base"
##
## [[9]]
## [1] "kableExtra" "DT" "plotly" "leaflet" "spdep"
## [6] "spData" "sf" "lubridate" "forcats" "stringr"
## [11] "dplyr" "purrr" "readr" "tidyr" "tibble"
## [16] "ggplot2" "tidyverse" "comexTL" "stats" "graphics"
## [21] "grDevices" "utils" "datasets" "methods" "base"
##
## [[10]]
## [1] "viridis" "viridisLite" "kableExtra" "DT" "plotly"
## [6] "leaflet" "spdep" "spData" "sf" "lubridate"
## [11] "forcats" "stringr" "dplyr" "purrr" "readr"
## [16] "tidyr" "tibble" "ggplot2" "tidyverse" "comexTL"
## [21] "stats" "graphics" "grDevices" "utils" "datasets"
## [26] "methods" "base"
##
## [[11]]
## [1] "geobr" "viridis" "viridisLite" "kableExtra" "DT"
## [6] "plotly" "leaflet" "spdep" "spData" "sf"
## [11] "lubridate" "forcats" "stringr" "dplyr" "purrr"
## [16] "readr" "tidyr" "tibble" "ggplot2" "tidyverse"
## [21] "comexTL" "stats" "graphics" "grDevices" "utils"
## [26] "datasets" "methods" "base"
# Função para formatar valores monetários
format_currency <- function(x) {
paste0("US$ ", format(round(x), big.mark = ".", decimal.mark = ","))
}
# Tema personalizado para gráficos
theme_cafe <- function(base_size = 12) {
theme_minimal(base_size = base_size) +
theme(
plot.background = element_rect(fill = "white", color = NA),
panel.background = element_rect(fill = "white", color = NA),
plot.title = element_text(
color = "#d35400",
size = 16,
face = "bold",
hjust = 0.5,
margin = margin(b = 20)
),
plot.subtitle = element_text(
color = "#7f8c8d",
size = 12,
hjust = 0.5,
margin = margin(b = 15)
),
axis.title = element_text(color = "#2c3e50", size = 11, face = "bold"),
axis.text = element_text(color = "#34495e", size = 10),
legend.title = element_text(color = "#d35400", face = "bold"),
legend.text = element_text(color = "#2c3e50"),
panel.grid.major = element_line(color = "#ecf0f1", size = 0.5),
panel.grid.minor = element_blank(),
strip.text = element_text(color = "#d35400", face = "bold")
)
}
## 📊 Carregando dados de área colhida (PAM/IBGE)...
# URL dos dados
data_url <- "https://raw.githubusercontent.com/alanleal-econ/cafe-mg-imputacao/refs/heads/main/cafe_arabica_pam.csv"
# Carregamento dos dados de área colhida (PAM/IBGE)
pam <- readr::read_csv(data_url, show_col_types = FALSE)
# Vetor r: proporção da área colhida por município
area_mg <- pam %>%
filter(sigla_uf == "MG", ano == 2023) %>%
group_by(id_municipio) %>%
summarise(
area = sum(area_colhida, na.rm = TRUE),
.groups = 'drop'
) %>%
mutate(r = area / sum(area, na.rm = TRUE)) %>%
filter(area > 0) # Remove municípios sem produção
cat("✅ Municípios com produção de café:", nrow(area_mg), "\n")
## ✅ Municípios com produção de café: 476
## 📈 Carregando dados de exportação municipal (HS4)...
# Dados de exportação municipal (SH4 = 901: Café)
exp_sh4 <- analise_comex_municipal(
tipo = "exportacao",
anos = 2023,
sh4 = 901,
sg_uf_mun = "MG",
agregar_por = "CO_MUN"
)
## Processando dados MUNICIPAIS de EXPORTACAO de 1 ano(s): 2023
## Arquivos necessários: municipio/exportacao/EXP_2023_MUN.parquet
##
## === Processando exportacao municipal do ano 2023 ===
## Baixando arquivo municipal: municipio/exportacao/EXP_2023_MUN.parquet
## Arquivo baixado com sucesso. Linhas: 1121352
## Arquivo municipal salvo no cache.
##
## === Combinando dados municipais de exportacao de todos os anos ===
## Total de linhas combinadas: 1121352
##
## === Aplicando filtros nos dados municipais ===
## Filtrado por SH4: 901
## Filtrado por UFs das empresas: MG
## Linhas após filtros: 5799
##
## === Agregando dados municipais ===
## Agregando por: SH4, CO_MUN
## Calculando métricas: VL_FOB, KG_LIQUIDO
## Resultado final: 86 linhas
# Preparação do vetor E4 (exportações municipais HS4)
E4 <- exp_sh4 %>%
select(CO_MUN, VL_FOB) %>%
rename(exp_sh4 = VL_FOB)
cat("✅ Municípios exportadores (HS4):", nrow(E4), "\n")
## ✅ Municípios exportadores (HS4): 86
## 🔄 Calculando fator de conversão HS4 → HS6...
# Cálculo do total estadual e fator de conversão
tot_sh4 <- sum(E4$exp_sh4)
exp_sh6_state <- comex_stat_geral_exps(
anos = 2023,
sh6 = 090111, # Café arábica não torrado
sg_uf_ncm = "MG"
)
## Processando 1 ano(s): 2023
## Arquivos necessários: exportacao/EXP_2023.parquet
##
## === Processando ano 2023 ===
## Baixando arquivo: exportacao/EXP_2023.parquet
## Arquivo baixado com sucesso. Linhas: 1563659
## Arquivo salvo no cache.
##
## === Combinando dados de todos os anos ===
## Total de linhas combinadas: 1563659
##
## === Aplicando filtros ===
## Filtrado por SH6: 90111
## Filtrado por UFs: MG
## Linhas após filtros: 1562
##
## === Agregando dados ===
## Agregando por: sh6
## Calculando métricas: VL_FOB, KG_LIQUIDO, QT_ESTAT
## Resultado final: 1 linhas
alpha <- sum(exp_sh6_state$VL_FOB) / tot_sh4
# Estatísticas preliminares
cat("\n📊 ESTATÍSTICAS PRELIMINARES:\n")
##
## 📊 ESTATÍSTICAS PRELIMINARES:
## • Total exportações HS4 (MG): US$ 5.668.807.514
## • Total exportações HS6 (MG): US$ 5.528.856.335
## • Fator de conversão (α): 0.98
## • Municípios com produção: 476
## • Municípios exportadores (HS4): 86
##
## 🗺️ Criando matriz de pesos espaciais...
# Carregamento das geometrias municipais
uf_mun <- geobr::read_municipality(year = 2020) %>%
filter(code_state == 31) %>% # Código de MG
select(code_muni, name_muni, geom)
cat("✅ Geometrias carregadas para", nrow(uf_mun), "municípios\n")
## ✅ Geometrias carregadas para 853 municípios
# Cálculo dos centroides e matriz de distâncias
coords <- sf::st_centroid(uf_mun)
dist_mat <- sf::st_distance(coords)
# Matriz de pesos: inverso da distância
inv_dist <- 1 / as.matrix(dist_mat)
diag(inv_dist) <- 0 # Remove auto-correlação
# Normalização por linha (matriz estocástica)
W <- inv_dist / rowSums(inv_dist)
rownames(W) <- uf_mun$code_muni
colnames(W) <- uf_mun$code_muni
cat("✅ Matriz de pesos espaciais criada (", nrow(W), "x", ncol(W), ")\n")
## ✅ Matriz de pesos espaciais criada ( 853 x 853 )
##
## 🎯 Executando imputação espacial...
# Preparação dos vetores na ordem correta
E4_vec <- E4$exp_sh4[match(uf_mun$code_muni, E4$CO_MUN)]
E4_vec[is.na(E4_vec)] <- 0
r_vec <- area_mg$r[match(uf_mun$code_muni, area_mg$id_municipio)]
r_vec[is.na(r_vec)] <- 0
# Imputação espacial seguindo a metodologia:
# E₆ᵢ = α × Σⱼ wᵢⱼ × E₄ⱼ + rᵢ × (E₆⁻ᴹᴳ - Σᵢ α × Σⱼ wᵢⱼ × E₄ⱼ)
spatial_comp <- alpha * (W %*% E4_vec)
total_spatial <- sum(spatial_comp)
residual <- sum(exp_sh6_state$VL_FOB) - total_spatial
adj_comp <- r_vec * residual
E6_est <- spatial_comp + adj_comp
# Adição dos resultados ao dataframe espacial
uf_mun$E6_imputado <- as.numeric(E6_est)
uf_mun$E4_observado <- E4_vec
uf_mun$componente_espacial <- as.numeric(spatial_comp)
uf_mun$componente_area <- as.numeric(adj_comp)
uf_mun$prop_area <- r_vec
cat("✅ Imputação concluída!\n")
## ✅ Imputação concluída!
## • Total imputado: US$ 5.528.856.335
cat(" • Diferença com oficial:", format_currency(sum(uf_mun$E6_imputado) - sum(exp_sh6_state$VL_FOB)), "\n")
## • Diferença com oficial: US$ 0
##
## 📊 Analisando resultados...
# Estatísticas finais
final_stats <- uf_mun %>%
st_set_geometry(NULL) %>%
summarise(
municipios_total = n(),
municipios_produtores = sum(prop_area > 0, na.rm = TRUE),
municipios_exportadores_hs4 = sum(E4_observado > 0, na.rm = TRUE),
municipios_imputados = sum(E6_imputado > 0, na.rm = TRUE),
total_imputado = sum(E6_imputado, na.rm = TRUE),
media_imputada = mean(E6_imputado[E6_imputado > 0], na.rm = TRUE),
mediana_imputada = median(E6_imputado[E6_imputado > 0], na.rm = TRUE),
max_imputado = max(E6_imputado, na.rm = TRUE),
.groups = 'drop'
)
# Análise dos componentes
component_summary <- uf_mun %>%
st_set_geometry(NULL) %>%
filter(E6_imputado > 0) %>%
summarise(
total_imputado = sum(E6_imputado),
total_espacial = sum(componente_espacial),
total_area = sum(componente_area),
.groups = 'drop'
) %>%
mutate(
perc_espacial = (total_espacial / total_imputado) * 100,
perc_area = (total_area / total_imputado) * 100
)
# Preparação dos dados do ranking
top_exporters <- uf_mun %>%
st_set_geometry(NULL) %>%
filter(E6_imputado > 0) %>%
arrange(desc(E6_imputado)) %>%
slice_head(n = 15) %>%
mutate(
rank = row_number(),
participacao = (E6_imputado / sum(exp_sh6_state$VL_FOB)) * 100,
exp_milhoes = E6_imputado / 1e6
) %>%
select(
rank, name_muni, E6_imputado, participacao,
E4_observado, componente_espacial, componente_area
)
## • Mapa interativo das exportações...
# Paleta de cores
pal <- colorNumeric(
palette = viridis::viridis(100, option = "plasma"),
domain = range(uf_mun$E6_imputado[uf_mun$E6_imputado > 0], na.rm = TRUE),
na.color = "transparent"
)
# Mapa interativo
mapa_exportacoes <- leaflet(uf_mun, options = leafletOptions(zoomControl = TRUE)) %>%
addProviderTiles(
"CartoDB.Positron",
options = providerTileOptions(opacity = 0.8)
) %>%
addPolygons(
weight = 0.8,
color = "#ffffff",
fillColor = ~pal(E6_imputado),
fillOpacity = 0.8,
smoothFactor = 0.2,
popup = ~paste0(
"<div style='font-family: Arial; font-size: 12px;'>",
"<b>", name_muni, "</b><br/>",
"<b>Exportações HS6:</b> ", format_currency(E6_imputado), "<br/>",
"<b>Exportações HS4:</b> ", format_currency(E4_observado), "<br/>",
"<b>% da Área Estadual:</b> ", round(prop_area * 100, 2), "%",
"</div>"
),
popupOptions = popupOptions(maxWidth = 300),
highlightOptions = highlightOptions(
weight = 3,
color = "#d35400",
fillOpacity = 0.9,
bringToFront = TRUE
)
) %>%
addLegend(
pal = pal,
values = ~E6_imputado,
title = "Exportações HS6<br/>(US$ milhares)",
position = "bottomright",
opacity = 0.8,
labFormat = labelFormat(
transform = function(x) x / 1000,
suffix = "k"
)
) %>%
setView(lng = -44.5, lat = -18.5, zoom = 7)
mapa_exportacoes
## • Gráfico do Top 10 exportadores...
top10_data <- top_exporters %>%
slice_head(n = 10) %>%
mutate(
name_muni = str_wrap(name_muni, width = 15),
exp_milhoes = E6_imputado / 1e6
)
grafico_top10 <- ggplot(top10_data, aes(x = reorder(name_muni, exp_milhoes), y = exp_milhoes)) +
geom_col(
fill = "#e67e22",
alpha = 0.8,
width = 0.7
) +
geom_text(
aes(label = paste0("US$ ", round(exp_milhoes, 1), "M")),
hjust = -0.1,
color = "#2c3e50",
size = 3.5,
fontface = "bold"
) +
coord_flip() +
scale_y_continuous(
expand = expansion(mult = c(0, 0.15)),
labels = function(x) paste0("US$ ", x, "M")
) +
labs(
title = "Top 10 Exportadores de Café Arábica",
subtitle = "Minas Gerais - 2023 (Valores Imputados)",
x = NULL,
y = "Exportações (US$ Milhões)",
caption = "Fonte: Elaboração própria com dados SECEX/IBGE"
) +
theme_cafe() +
theme(
axis.text.y = element_text(size = 10),
plot.margin = margin(20, 20, 20, 20)
)
print(grafico_top10)
## • Gráfico de composição dos componentes...
component_data <- data.frame(
Componente = c("Componente Espacial", "Componente por Área"),
Valor = c(component_summary$total_espacial, component_summary$total_area),
Percentual = c(component_summary$perc_espacial, component_summary$perc_area)
)
grafico_componentes <- ggplot(component_data, aes(x = "", y = Percentual, fill = Componente)) +
geom_bar(stat = "identity", width = 1, color = "white", size = 2) +
coord_polar("y", start = 0) +
scale_fill_manual(
values = c("#e67e22", "#3498db"),
labels = paste0(component_data$Componente, "\n(", round(component_data$Percentual, 1), "%)")
) +
labs(
title = "Composição da Imputação Total",
subtitle = paste0("Total Imputado: ", format_currency(component_summary$total_imputado)),
fill = "Componentes"
) +
theme_void() +
theme(
plot.title = element_text(color = "#d35400", size = 16, face = "bold", hjust = 0.5),
plot.subtitle = element_text(color = "#7f8c8d", size = 12, hjust = 0.5),
legend.position = "bottom",
legend.title = element_text(color = "#d35400", face = "bold"),
legend.text = element_text(color = "#2c3e50", size = 10)
)
print(grafico_componentes)
## • Mapa do componente espacial...
uf_mun_filtered <- uf_mun %>%
filter(E6_imputado > 0)
pal_espacial <- colorNumeric("Oranges", domain = uf_mun_filtered$componente_espacial)
mapa_componente_espacial <- leaflet(uf_mun_filtered) %>%
addProviderTiles("CartoDB.Positron") %>%
addPolygons(
weight = 0.5,
color = "white",
fillColor = ~pal_espacial(componente_espacial),
fillOpacity = 0.7,
popup = ~paste0(
"<b>", name_muni, "</b><br/>",
"Componente Espacial: ", format_currency(componente_espacial)
)
) %>%
addLegend(
pal = pal_espacial,
values = ~componente_espacial,
title = "Componente<br/>Espacial (US$)",
position = "bottomright"
) %>%
setView(lng = -44.5, lat = -18.5, zoom = 7)
mapa_componente_espacial
# Tabela do ranking Top 15
tabela_ranking <- top_exporters %>%
mutate(
`Exportações HS6` = format_currency(E6_imputado),
`Participação (%)` = paste0(round(participacao, 2), "%"),
`Exportações HS4` = format_currency(E4_observado),
`Comp. Espacial` = format_currency(componente_espacial),
`Comp. Área` = format_currency(componente_area)
) %>%
select(
`Ranking` = rank,
`Município` = name_muni,
`Exportações HS6`,
`Participação (%)`,
`Exportações HS4`,
`Comp. Espacial`,
`Comp. Área`
)
kable(tabela_ranking,
caption = "Ranking dos Top 15 Exportadores Municipais",
align = c("c", "l", "r", "r", "r", "r", "r")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
full_width = TRUE,
position = "center",
font_size = 12) %>%
row_spec(0, bold = TRUE, color = "white", background = "#e67e22") %>%
column_spec(1, bold = TRUE, color = "#d35400") %>%
column_spec(2, bold = TRUE)
Ranking | Município | Exportações HS6 | Participação (%) | Exportações HS4 | Comp. Espacial | Comp. Área |
---|---|---|---|---|---|---|
1 | Guaranésia | US$ 29.199.710 | 0.53% | US$ 62.274 | US$ 29.550.681 | US$ -350.971 |
2 | Elói Mendes | US$ 24.555.056 | 0.44% | US$ 1.308.623 | US$ 25.532.903 | US$ -977.847 |
3 | Monsenhor Paulo | US$ 23.148.851 | 0.42% | US$ 2.961.614 | US$ 23.480.424 | US$ -331.573 |
4 | Muzambinho | US$ 22.636.321 | 0.41% | US$ 0 | US$ 23.177.665 | US$ -541.344 |
5 | Três Pontas | US$ 22.504.877 | 0.41% | US$ 52.373.049 | US$ 24.183.042 | US$ -1.678.165 |
6 | Juruaia | US$ 22.484.066 | 0.41% | US$ 0 | US$ 22.902.705 | US$ -418.639 |
7 | São Pedro Da União | US$ 21.971.450 | 0.4% | US$ 0 | US$ 22.281.820 | US$ -310.370 |
8 | Fama | US$ 21.118.077 | 0.38% | US$ 0 | US$ 21.229.955 | US$ -111.878 |
9 | Paraguaçu | US$ 19.596.169 | 0.35% | US$ 15.093.615 | US$ 20.493.897 | US$ -897.728 |
10 | Arceburgo | US$ 19.595.811 | 0.35% | US$ 0 | US$ 19.750.996 | US$ -155.185 |
11 | Carmo Da Cachoeira | US$ 18.832.404 | 0.34% | US$ 0 | US$ 19.761.710 | US$ -929.307 |
12 | Serrania | US$ 18.527.678 | 0.34% | US$ 0 | US$ 18.834.439 | US$ -306.761 |
13 | Areado | US$ 18.508.701 | 0.33% | US$ 3.521.678 | US$ 18.771.252 | US$ -262.552 |
14 | Três Corações | US$ 18.079.523 | 0.33% | US$ 54.874.847 | US$ 18.864.471 | US$ -784.948 |
15 | Monte Santo De Minas | US$ 18.077.362 | 0.33% | US$ 1.528.864 | US$ 18.972.834 | US$ -895.473 |
##
## 🎉 ANÁLISE CONCLUÍDA!
##
## 📊 PRINCIPAIS CONCLUSÕES:
## 1. Cobertura Territorial: Imputação para 853 municípios
cat("2. Concentração: Top 10 representa", round(sum(top_exporters$participacao[1:10]), 1), "% do total estadual\n")
## 2. Concentração: Top 10 representa 4.1 % do total estadual
## 3. Validação: Total imputado corresponde ao valor oficial estadual
## 4. Componente Espacial: 102 % da imputação total
##
## 🏆 TOP 5 EXPORTADORES:
for(i in 1:5) {
cat(sprintf("%d. %s: %s\n",
i,
top_exporters$name_muni[i],
format_currency(top_exporters$E6_imputado[i])))
}
## 1. Guaranésia: US$ 29.199.710
## 2. Elói Mendes: US$ 24.555.056
## 3. Monsenhor Paulo: US$ 23.148.851
## 4. Muzambinho: US$ 22.636.321
## 5. Três Pontas: US$ 22.504.877
##
## ✨ Script executado com sucesso!
Nota metodológica: Esta análise implementa uma metodologia de imputação espacial para estimar exportações municipais de café arábica (HS6: 090111) baseada em dados agregados estaduais e informações de área colhida municipal. A imputação combina componentes espaciais (baseados em spillovers de municípios exportadores) e componente por área de produção, garantindo que o total imputado corresponda exatamente ao valor oficial estadual.