1 Introdução

Este trabalho analisa a cobertura de banda larga móvel nos 853 municípios do Estado de Minas Gerais, com base nos dados abertos disponibilizados pela Agência Nacional de Telecomunicações (ANATEL) referentes a junho de 2024.

O objetivo é compreender a distribuição espacial da cobertura de internet móvel e identificar padrões de concentração ou dispersão geográfica, utilizando análise de autocorrelação espacial por meio do Índice de Moran Global e Local (LISA).


2 Pacotes Utilizados

library(plotly)
library(forcats)
library(janitor)
library(tmap)
library(ggspatial)
library(sf)
library(readr)
library(viridis)
library(dplyr)
library(RColorBrewer)
library(htmlwidgets)
library(tidyverse)
library(readxl)
library(ggplot2)
library(kableExtra)
library(spdep)
library(leaflet)
library(geobr)

Nota: Caso algum pacote não esteja instalado, execute install.packages("nome_do_pacote") antes de rodar este documento.


3 Dados

3.1 Leitura e Estrutura

Os dados foram obtidos no painel da ANATEL, filtrando cobertura por município para o Estado de Minas Gerais, referente ao período de junho de 2024.

ANATEL_JUNHO_2024 <- read_excel("C:/Users/Rodrigo/Documentos_SDD/MBA_USP/TCC/Dados/BASE_ANATEL_JUNHO_2024.xlsx")

# Estrutura dos dados brutos
glimpse(ANATEL_JUNHO_2024)
## Rows: 3,054
## Columns: 11
## $ `Código IBGE`           <chr> "3100104", "3100104", "3100104", "3100203", "3…
## $ Município               <chr> "Abadia dos Dourados", "Abadia dos Dourados", …
## $ UF                      <chr> "MG", "MG", "MG", "MG", "MG", "MG", "MG", "MG"…
## $ Operadora               <chr> "Todas", "Todas", "Todas", "Todas", "Todas", "…
## $ Tecnologia              <chr> "4G", "4G", "4G", "4G", "4G", "4G", "4G", "4G"…
## $ `% área coberta`        <dbl> 23.03411, 23.03411, 23.03411, 14.20932, 14.209…
## $ `% moradores cobertos`  <dbl> 71.42292, 71.42292, 71.42292, 88.59294, 88.592…
## $ `% domicílios cobertos` <chr> "72,54", "72,54", "72,54", "88,19", "88,19", "…
## $ `Área km2`              <dbl> 881.0639, 881.0639, 881.0639, 1817.0669, 1817.…
## $ Moradores               <dbl> 6660, 6660, 6660, 22497, 22497, 13131, 13131, …
## $ Domicílios              <dbl> 2314, 2314, 2314, 7704, 7704, 3930, 3930, 1261…

3.2 Limpeza e Seleção de Variáveis

Foram removidas colunas não utilizadas na análise e a variável de percentual de área coberta foi convertida para formato numérico.

# Selecionar colunas relevantes
ANATEL_JUNHO_2024_SELECT <- ANATEL_JUNHO_2024 %>%
  select(-c("% moradores cobertos", "% domicílios cobertos",
            "Área km2", "Moradores", "Domicílios")) %>%
  rename(Código_IBGE = `Código IBGE`) %>%
  mutate_at(vars(`% área coberta`), ~ as.numeric(gsub(",", ".", .)))

glimpse(ANATEL_JUNHO_2024_SELECT)
## Rows: 3,054
## Columns: 6
## $ Código_IBGE      <chr> "3100104", "3100104", "3100104", "3100203", "3100203"…
## $ Município        <chr> "Abadia dos Dourados", "Abadia dos Dourados", "Abadia…
## $ UF               <chr> "MG", "MG", "MG", "MG", "MG", "MG", "MG", "MG", "MG",…
## $ Operadora        <chr> "Todas", "Todas", "Todas", "Todas", "Todas", "Todas",…
## $ Tecnologia       <chr> "4G", "4G", "4G", "4G", "4G", "4G", "4G", "4G", "4G",…
## $ `% área coberta` <dbl> 23.03411, 23.03411, 23.03411, 14.20932, 14.20932, 80.…

3.3 Agregação por Município

Como a base original contém múltiplas linhas por município (uma por operadora e tecnologia), os dados foram agregados calculando a média da área coberta por município.

ANATEL_JUNHO_2024_AGREG <- ANATEL_JUNHO_2024_SELECT %>%
  group_by(Código_IBGE, Município, UF, Operadora, Tecnologia) %>%
  summarise(
    Área_Coberta_Média = mean(`% área coberta`, na.rm = TRUE),
    .groups = 'drop'
  )

head(ANATEL_JUNHO_2024_AGREG) %>%
  kable(caption = "Primeiras linhas após agregação") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Primeiras linhas após agregação
Código_IBGE Município UF Operadora Tecnologia Área_Coberta_Média
3100104 Abadia dos Dourados MG Todas 4G 23.03411
3100203 Abaeté MG Todas 4G 14.20932
3100302 Abre Campo MG Todas 4G 80.16806
3100401 Acaiaca MG Todas 4G 98.63536
3100500 Açucena MG Todas 4G 64.00857
3100609 Água Boa MG Todas 4G 27.26441

4 Análise Descritiva

4.1 Estatísticas Gerais

summary(ANATEL_JUNHO_2024_AGREG$Área_Coberta_Média)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   5.507  45.833  69.754  66.118  89.626 100.000

A cobertura média varia de 5,5% a 100%, com mediana em torno de 69,7%, indicando que metade dos municípios mineiros tem cobertura acima deste valor. Entretanto, há municípios com cobertura muito baixa, apontando para desigualdades regionais.

4.2 Municípios com Menor Cobertura

TAIL_10_MUNS <- ANATEL_JUNHO_2024_AGREG %>%
  arrange(Área_Coberta_Média) %>%
  head(10)

ggplot(TAIL_10_MUNS,
       aes(x = reorder(Município, Área_Coberta_Média),
           y = Área_Coberta_Média,
           fill = Área_Coberta_Média)) +
  geom_bar(stat = "identity", color = "black") +
  geom_text(aes(label = round(Área_Coberta_Média, 1)),
            hjust = -0.3, color = "black", size = 3.5) +
  coord_flip() +
  scale_fill_viridis_c(option = "viridis") +
  labs(x = "Município", y = "Área Coberta Média (%)") +
  theme_minimal()
10 municípios com menor área coberta média

10 municípios com menor área coberta média

4.3 Distribuição por Intervalos de Cobertura

ANATEL_JUNHO_2024_INTERVALO <- ANATEL_JUNHO_2024_AGREG %>%
  mutate(intervalo = cut(Área_Coberta_Média,
                         breaks = seq(0, 100.5, by = 20),
                         include.lowest = TRUE)) %>%
  count(intervalo) %>%
  mutate(perc = n / sum(n) * 100)

ggplot(ANATEL_JUNHO_2024_INTERVALO,
       aes(x = factor(1), y = perc, fill = intervalo)) +
  geom_bar(stat = "identity", color = "black", width = 0.5) +
  geom_text(aes(label = paste0(n, " (", round(perc, 1), "%)")),
            position = position_stack(vjust = 0.5),
            color = "black", size = 5) +
  scale_fill_viridis_d(option = "viridis") +
  labs(x = NULL, y = "Percentual (%)",
       fill = "Intervalo de cobertura (%)") +
  theme_minimal() +
  theme(
    axis.text.y = element_blank(),
    axis.ticks.y = element_blank()
  ) +
  coord_flip() +
  guides(fill = guide_legend(reverse = TRUE))
Distribuição dos municípios por faixas de cobertura

Distribuição dos municípios por faixas de cobertura

Aproximadamente 20% dos municípios de Minas Gerais possuem cobertura abaixo de 40%.


5 Análise Espacial

5.1 Integração com Malha Municipal do IBGE

Os dados da ANATEL foram integrados à malha geográfica dos municípios brasileiros de 2022, disponibilizada pelo pacote geobr.

# Baixar malha de municípios de MG
MUNICIPIOS_BR <- geobr::read_municipality(code_muni = 'all', year = 2022)
MUNICIPIOS_MG <- MUNICIPIOS_BR[MUNICIPIOS_BR$abbrev_state == 'MG', ] %>%
  mutate(code_muni = as.character(code_muni))

# Join com dados ANATEL
ANATEL_JUNHO_2024_JOIN_MUN <- merge(
  ANATEL_JUNHO_2024_AGREG,
  MUNICIPIOS_MG,
  by.x = "Código_IBGE",
  by.y = "code_muni"
)

# Criar objeto espacial
ANATEL_JUNHO_2024_ESPACIAL <- ANATEL_JUNHO_2024_JOIN_MUN %>%
  select(Código_IBGE, Município, UF, Operadora,
         Tecnologia, Área_Coberta_Média, geom) %>%
  st_as_sf()

5.2 Mapa de Cobertura Média

ggplot(data = ANATEL_JUNHO_2024_ESPACIAL) +
  geom_sf(aes(fill = Área_Coberta_Média),
          color = "grey50", lwd = 0.3) +
  scale_fill_viridis_c(option = "viridis",
                       direction = 1,
                       labels = scales::comma) +
  labs(fill = "Área Coberta Média (%)") +
  theme_minimal() +
  theme(legend.title = element_text(face = "plain")) +
  annotation_scale(location = "bl", width_hint = 0.5, style = "ticks") +
  coord_sf(datum = NA)
Cobertura média de internet móvel por município em MG

Cobertura média de internet móvel por município em MG


6 Autocorrelação Espacial

6.1 Construção da Matriz de Vizinhança

A matriz de vizinhança foi construída pelo critério Queen (municípios que compartilham fronteira ou vértice são considerados vizinhos).

# Matriz de vizinhança Queen
ANATEL_JUNHO_2024_VIZINHANCA_QUEEN <- poly2nb(ANATEL_JUNHO_2024_ESPACIAL, queen = TRUE)

# Lista de pesos espaciais
ANATEL_JUNHO_2024_LISTA_PESOS_QUEEN <- nb2listw(ANATEL_JUNHO_2024_VIZINHANCA_QUEEN, style = "W")

6.2 Índice de Moran Global

O Índice de Moran Global mede se há autocorrelação espacial significativa na variável de interesse — ou seja, se municípios próximos tendem a ter coberturas similares.

MORAN_GLOBAL_QUEEN <- moran.test(
  ANATEL_JUNHO_2024_ESPACIAL$Área_Coberta_Média,
  ANATEL_JUNHO_2024_LISTA_PESOS_QUEEN
)
print(MORAN_GLOBAL_QUEEN)
## 
##  Moran I test under randomisation
## 
## data:  ANATEL_JUNHO_2024_ESPACIAL$Área_Coberta_Média  
## weights: ANATEL_JUNHO_2024_LISTA_PESOS_QUEEN    
## 
## Moran I statistic standard deviate = 33.572, p-value < 2.2e-16
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##      0.7148548604     -0.0011737089      0.0004548807

Um valor de Moran positivo e significativo indica autocorrelação espacial positiva: municípios com alta cobertura tendem a se agrupar próximos a outros com alta cobertura, e vice-versa.

6.3 Diagrama de Dispersão de Moran

var_std   <- scale(ANATEL_JUNHO_2024_ESPACIAL$Área_Coberta_Média)
lagged_var <- lag.listw(ANATEL_JUNHO_2024_LISTA_PESOS_QUEEN, var_std)

moran_df <- data.frame(
  var_std    = as.vector(var_std),
  lagged_var = as.vector(lagged_var),
  Município  = ANATEL_JUNHO_2024_ESPACIAL$Município
)

ggplot(moran_df, aes(x = var_std, y = lagged_var)) +
  geom_point(color = "blue", size = 1.5) +
  geom_smooth(method = "lm", color = "red", se = FALSE) +
  labs(x = "Valores padronizados",
       y = "Valores lagged padronizados") +
  theme_minimal()
Diagrama de dispersão de Moran

Diagrama de dispersão de Moran


7 Análise LISA (Local Indicators of Spatial Association)

O Índice de Moran Local (LISA) permite identificar clusters espaciais e outliers para cada município individualmente.

7.1 Cálculo do LISA

local_moran <- localmoran(
  ANATEL_JUNHO_2024_ESPACIAL$Área_Coberta_Média,
  ANATEL_JUNHO_2024_LISTA_PESOS_QUEEN
)

ANATEL_JUNHO_2024_ESPACIAL$localI  <- as.numeric(local_moran[, 1])
ANATEL_JUNHO_2024_ESPACIAL$p.value <- as.numeric(local_moran[, 5])

# Classificação dos quadrantes LISA
media_cobertura <- mean(ANATEL_JUNHO_2024_ESPACIAL$Área_Coberta_Média)

ANATEL_JUNHO_2024_ESPACIAL$LISA_Quadrant <- factor(NA,
  levels = c("Alto-Alto", "Baixo-Baixo", "Alto-Baixo", "Baixo-Alto", "Não Significativo"))

ANATEL_JUNHO_2024_ESPACIAL$LISA_Quadrant[
  ANATEL_JUNHO_2024_ESPACIAL$localI > 0 &
  ANATEL_JUNHO_2024_ESPACIAL$p.value <= 0.05 &
  ANATEL_JUNHO_2024_ESPACIAL$Área_Coberta_Média > media_cobertura] <- "Alto-Alto"

ANATEL_JUNHO_2024_ESPACIAL$LISA_Quadrant[
  ANATEL_JUNHO_2024_ESPACIAL$localI > 0 &
  ANATEL_JUNHO_2024_ESPACIAL$p.value <= 0.05 &
  ANATEL_JUNHO_2024_ESPACIAL$Área_Coberta_Média < media_cobertura] <- "Baixo-Baixo"

ANATEL_JUNHO_2024_ESPACIAL$LISA_Quadrant[
  ANATEL_JUNHO_2024_ESPACIAL$localI < 0 &
  ANATEL_JUNHO_2024_ESPACIAL$p.value <= 0.05 &
  ANATEL_JUNHO_2024_ESPACIAL$Área_Coberta_Média > media_cobertura] <- "Alto-Baixo"

ANATEL_JUNHO_2024_ESPACIAL$LISA_Quadrant[
  ANATEL_JUNHO_2024_ESPACIAL$localI < 0 &
  ANATEL_JUNHO_2024_ESPACIAL$p.value <= 0.05 &
  ANATEL_JUNHO_2024_ESPACIAL$Área_Coberta_Média < media_cobertura] <- "Baixo-Alto"

ANATEL_JUNHO_2024_ESPACIAL$LISA_Quadrant[
  is.na(ANATEL_JUNHO_2024_ESPACIAL$LISA_Quadrant)] <- "Não Significativo"

7.2 Mapa LISA

lisa_colors <- c("red", "blue", "lightblue", "lightcoral", "grey80")

mapa_lisa <- ggplot(data = ANATEL_JUNHO_2024_ESPACIAL) +
  geom_sf(aes(fill = LISA_Quadrant), color = "grey50", lwd = 0.2) +
  scale_fill_manual(
    values = lisa_colors,
    name   = "Clusters LISA",
    labels = c("Alto-Alto", "Baixo-Baixo", "Alto-Baixo",
               "Baixo-Alto", "Não Significativo")
  ) +
  theme_minimal() +
  theme(legend.title = element_text(face = "plain")) +
  annotation_scale(location = "bl", width_hint = 0.5, style = "ticks") +
  coord_sf(datum = NA)

print(mapa_lisa)
Mapa LISA — clusters de cobertura de banda larga móvel em MG

Mapa LISA — clusters de cobertura de banda larga móvel em MG

7.3 Mapa de Significância

sig_colors <- c("red", "orange", "lightgrey")

ANATEL_JUNHO_2024_ESPACIAL$sig <- cut(
  ANATEL_JUNHO_2024_ESPACIAL$p.value,
  breaks = c(0, 0.01, 0.05, 1),
  labels = c("p < 0.01", "p < 0.05", "Não significativo")
)

mapa_significancia <- ggplot(data = ANATEL_JUNHO_2024_ESPACIAL) +
  geom_sf(aes(fill = sig), color = "grey50", lwd = 0.2) +
  scale_fill_manual(
    values = sig_colors,
    name   = "Significância"
  ) +
  theme_minimal() +
  theme(
    legend.title    = element_text(face = "plain"),
    legend.position = "right"
  ) +
  annotation_scale(location = "bl", width_hint = 0.5, style = "ticks") +
  coord_sf(datum = NA)

plot(mapa_significancia)
Mapa de significância do Índice de Moran Local

Mapa de significância do Índice de Moran Local


8 Conclusões

A análise da cobertura de banda larga móvel nos municípios de Minas Gerais revelou:

  • Desigualdade expressiva: a cobertura varia de 5,5% a 100%, com aproximadamente 20% dos municípios abaixo de 40%.
  • Autocorrelação espacial positiva e significativa (Índice de Moran Global > 0, p < 0,05): municípios próximos tendem a ter níveis de cobertura similares.
  • Clusters identificados pelo LISA: municípios com alta cobertura concentram-se em determinadas regiões, enquanto zonas de baixa cobertura formam clusters próprios — evidenciando um padrão de exclusão digital geograficamente estruturado.

9 Referências

  • ANATEL — Agência Nacional de Telecomunicações. Painel de Dados de Cobertura. Disponível em: https://www.anatel.gov.br
  • IBGE — Instituto Brasileiro de Geografia e Estatística. Malha Municipal 2022. Disponível via pacote geobr.
  • ANSELIN, L. (1995). Local Indicators of Spatial Association — LISA. Geographical Analysis, 27(2), 93–115.
  • FÁVERO, L. P.; BELFIORE, P. Manual de Análise de Dados. Elsevier, 2017.

Trabalho de Conclusão de Curso — MBA em Data Science e Analytics, USP/ESALQ.