Solução em R para correlação Pearson entre população e PIB (dados censitários)

Com base nas tabelas fornecidas, o script abaixo realiza: 1. Conexão com o PostgreSQL. 2. Extração do PIB total do ano mais recente disponível na tabela dados_ibge. 3. Extração da população estimada (coluna populacao_estimada da tabela populacao_municipal). 4. Extração da região geográfica (coluna nome_regiao da tabela municipios_sp). 5. Junção das três tabelas pelo codigo_ibge. 6. Cálculo da correlação de Pearson nacional e por região (apenas descritiva, sem p‑valor). 7. Gráficos de dispersão (escala log‑log) para visualizar a relação.

🔌 Conexão com o banco de dados

Ajuste os parâmetros (dbname, host, port, user, password) conforme seu ambiente.

library(DBI)
library(RPostgres)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
library(broom)
library(scales)

con <- dbConnect(
  RPostgres::Postgres(),
  service = "edumaps",
)
## Warning in system("timedatectl", intern = TRUE): running command 'timedatectl'
## had status 1

📥 Carregar os dados

# 1. PIB municipal do ano mais recente
pib <- tbl(con, "dados_ibge") %>%
  filter(ano == 2021) %>%
  select(codigo_ibge, pib_total, ano) %>%
  collect() %>%
  mutate(pib_total = as.numeric(pib_total))  # converte de numeric para double

# 2. População municipal (estimativa)
pop <- tbl(con, "populacao_municipal") %>%
  select(codigo_ibge, populacao_estimada) %>%
  collect() %>%
  mutate(populacao = as.numeric(populacao_estimada))

# 3. Regiões (via tabela municipios_sp)
regioes <- tbl(con, "municipios_sp") %>%
  select(codigo_ibge, nome_regiao, sigla_estado) %>%
  collect() %>%
  # Garantir que nome_regiao não seja NA e padronizar
  filter(!is.na(nome_regiao)) %>%
  distinct(codigo_ibge, .keep_all = TRUE)

# Fechar conexão (opcional)
dbDisconnect(con)

🔗 Juntar tudo e limpar

dados <- pib %>%
  inner_join(pop, by = "codigo_ibge") %>%
  inner_join(regioes, by = "codigo_ibge") %>%
  filter(
    !is.na(pib_total), pib_total > 0,
    !is.na(populacao), populacao > 0
  ) %>%
  mutate(
    log_pib = log10(pib_total),
    log_pop = log10(populacao)
  )

# Ver quantos municípios em cada região
dados %>%
  group_by(nome_regiao) %>%
  summarise(n = n())
## # A tibble: 5 × 2
##   nome_regiao      n
##   <chr>        <int>
## 1 Centro-oeste   467
## 2 Nordeste      1794
## 3 Norte          450
## 4 Sudeste       1668
## 5 Sul           1191

📊 Correlação nacional e por região (descritiva)

# Nacional
cor_nacional <- cor(dados$populacao, dados$pib_total, method = "pearson")
cat("Correlação de Pearson (Brasil): ", round(cor_nacional, 4), "\n")
## Correlação de Pearson (Brasil):  0.955
# Por região
cor_por_regiao <- dados %>%
  group_by(nome_regiao) %>%
  summarise(
    correlacao = cor(populacao, pib_total, use = "complete.obs"),
    n_municipios = n()
  ) %>%
  arrange(desc(correlacao))

print(cor_por_regiao)
## # A tibble: 5 × 3
##   nome_regiao  correlacao n_municipios
##   <chr>             <dbl>        <int>
## 1 Sudeste           0.979         1668
## 2 Sul               0.954         1191
## 3 Nordeste          0.952         1794
## 4 Centro-oeste      0.938          467
## 5 Norte             0.885          450

📈 Gráfico de dispersão (escala log‑log)

ggplot(dados, aes(x = populacao, y = pib_total, color = nome_regiao)) +
  geom_point(alpha = 0.4, size = 0.7) +
  geom_smooth(method = "lm", se = FALSE, color = "black", size = 0.5) +
  scale_x_log10(labels = label_number(scale_cut = cut_short_scale())) +
  scale_y_log10(labels = label_number(scale_cut = cut_short_scale())) +
  facet_wrap(~nome_regiao) +
  labs(
    title = "Relação entre População e PIB Total por Região",
    x = "População (log10)",
    y = "PIB Total (log10)",
    color = "Região"
  ) +
  theme_minimal() +
  theme(legend.position = "bottom")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## `geom_smooth()` using formula = 'y ~ x'

🧠 Interpretação dos resultados (dados censitários)

Como os dados compreendem todos os municípios brasileiros (censo), o coeficiente de Pearson calculado é uma medida descritiva da força da associação linear entre população e PIB total. Não se deve: - Calcular p‑valor (não há inferência para uma população maior). - Falar em “significância estatística” (não há amostragem).

O valor de \(r\) próximo de 1 indica forte correlação linear positiva – municípios mais populosos tendem a ter PIB total maior. Contudo, a transformação log‑log revela que a relação não é perfeitamente linear; a dispersão aumenta para municípios muito pequenos.

Diferenças regionais esperadas: Regiões mais desenvolvidas (Sudeste) podem apresentar correlação mais forte que regiões com alta heterogeneidade (Norte). A tabela cor_por_regiao mostrará esses contrastes.

⚠️ Observações importantes sobre os dados

  • Ano do PIB vs. população: A tabela populacao_municipal não possui coluna ano. Assumimos que se trata da estimativa mais recente. Idealmente deveriam estar alinhados (ex.: PIB 2021 com população 2021). Se houver defasagem, a correlação ainda será alta, mas menos precisa.
  • Municípios sem dados: Alguns municípios podem não ter pib_total (supressão por sigilo) ou populacao_estimada (raro). O inner_join já os exclui.
  • Região: A coluna nome_regiao da tabela municipios_sp já traz a divisão oficial (Norte, Nordeste, etc.). Caso haja valores vazios, remova‑os.

🚀 Execução completa

Salve o script acima em um arquivo .R e execute linha a linha no RStudio ou no terminal R. O resultado final será uma tabela com as correlações regionais e um gráfico de dispersão por região.

Se precisar de ajustes (ex.: escolher um ano específico para o PIB, usar outra coluna de população como soma das faixas etárias), basta modificar a parte de carregamento dos dados. Por exemplo, para usar total_soma_faixas em vez de populacao_estimada: