# Defina quais serão as versões dos pacotes utilizadas (mesmas versões do presente documento)
renv::restore()
# Defina os pacotes que serão utilizados
pckgs <- c("archive", "arrow", "fs", "geocodebr", "gt", "httr2", "here", "janitor", "knitr", "readxl", "quarto", "scales", "sf", "tidyverse", "zip")
# Ative-os
lapply(pckgs, library, character.only = TRUE)
# Remova o objeto que armazenou o nome dos pacotes
rm(pckgs)Procedimento para checagem e atualização da base geoespacial das escolas (2022 e 2025)
Visão geral
O presente documento disponibiliza o procedimento para a definição, a manutenção e a atualização dos dados geoespaciais das escolas brasileiras presentes na plataforma GeoReDUS. O objetivo é obter uma base geoespacial única das escolas ao longo do tempo. Para isso, propõe-se um procedimento de compatibilização espaço-temporal dos dados.
A proposta, como pode ser vista neste documento e no sumário localizado no canto superior direito da página, está estruturada em “grandes etapas”. São elas: i) preparação do ambiente local para armazenamento dos dados originais (microdados do censo escolar e catálogo de escolas; ii) acesso, importação e definição das operações relacionadas à limpeza e à organização da base compatibilizada dos microdados escolares; iii) breve exploração e análise dos dados; iv) geocodificação das escolas que não apresentam coordenadas geográficas e v) exportação dos resultados gerados[^1].
[^1] Caso você esteja usando o Positron como IDE, a estrutura do documento pode ser acompanhada por meio do campo OUTLINE, no canto inferior esquerdo da IDE.
Preparação e configurações iniciais
O primeiro passo para a geração dos dados geoespaciais das escolas consiste na preparação e estruturação do R e do ambiente local onde os dados serão armazenados. Dessa forma, o procedimento poderá ser reproduzido por qualquer pessoa em qualquer local, obtendo-se os mesmos resultados.
Carregando os pacotes necessários
De modo a facilitar algumas operações, e tomando como guia os princípios FAIR e do Tidyverse, alguns pacotes serão habilitados. Note: graças ao uso do Renv, as mesmas versões dos pacotes utilizadas no momento de geração dos dados serão replicadas em seu ambiente local.
Definindo algumas variáveis para fins de reprodutibilidade/atualizações
Para facilitar possíveis alterações, atualizações, usos recorrentes e/ou novas consultas, algumas variáveis já serão definidas neste momento. Por ora, elas compreendem o total dos censos escolares analisados (censo_esc_tot) e os seus respectivos anos (censo_esc_anos).
# Defina o número de bases analisadas (neste momento, quatro: 2022, 2023, 2024 e 2025)
censo_esc_anos <- c(2022, 2023, 2024, 2025)
censo_esc_tot <- length(censo_esc_anos)Obtenção, transformação e organização dos dados
A partir deste momento, serão realizadas algumas operações voltadas à obtenção, ao tratamento e à organização dos dados que serão utilizados para gerar a base geoespacial das escolas brasileiras ao longo do tempo.
Criando a estrutura de armazenamento do ambiente local
Para armazenar os dados, três pastas serão criadas:
01_logs: local destinado ao armazenamento dos registros de operações e modificações realizadas;02_originais: local destinado ao armazenamento dos dados originais, e,03_processados: local destinado ao armazenamento dos dados gerados por meio do atual procedimento.
# Crie os caminhos das pastas que armazenarão os dados
pastas <- c(
here("dados", str_c("01", "_logs")),
here("dados", str_c("02", "_originais")),
here("dados", str_c("03", "_processados"))
)
# Crie as pastas, caso não existam
walk(pastas, ~ if(!dir_exists(.x)) dir_create(.x, recurse = TRUE))
# Armazene o caminho de algumas pastas em objetos para facilitar as chamadas ao longo do código
pasta_logs <- pastas[1]
pasta_dados_originais <- pastas[2]
pasta_dados_processados <- pastas[3] Criando o procedimento para a obtenção, o tratamento e a organização dos dados
A obtenção, o tratamento e a organização dos microdados dos censos escolares ao longo do tempo pode ser realizada de diferentes formas. No presente caso, optou-se por criar uma função que reúne as etapas necessárias para essas ações.
Por meio dela, os dados originais serão:
- Acessados via internet, baixados para o ambiente o local (computador) e importados para o R;
- Realizadas operações de tratamento (exclusão e geração de variáveis; transformação de classes, (re)organização dos dados, etc.)
- Geração de uma base única compatibilizada entre os anos analisados - base, essa, que servirá de insumo para a etapa de geocodificação, mais adiante.
# Definição da função para processar os dados de cada ano
processar_censo_ano <- function(ano, max_tentativas = 3) {
# Preparação dos registros das ações e alterações (logs)
## Especifique o caminho onde o arquivo de log será armazenado
arquivo_log <- file.path(pasta_logs, str_glue("processamento_{ano}_{Sys.Date()}.log"))
## Crie uma função para gerar as mensagens de log
log_msg <- function(msg, tipo = "INFO") {
timestamp <- format(Sys.time(), "%Y-%m-%d %H:%M:%S")
mensagem <- str_glue("[{timestamp}] [{tipo}] Ano {ano}: {msg}")
write_lines(mensagem, arquivo_log, append = TRUE)
message(mensagem)
}
# Acesso aos dados
## Gere uma mensagem indicando o início do processamento
log_msg("Início do processamento")
## Defina o endereço para baixar o dado
base_url <- "https://download.inep.gov.br"
## Defina o nome do arquivo a ser baixado
arq_orig <- str_c("microdados_censo_escolar_", ano, if_else(ano == 2025, "_", ""), ".zip") # O if_else é usado para contemplar a grafia diferente dos microdados de 2025 (um traço antes do ".zip")
## Baixe os dados
for (tentativa in 1:max_tentativas) {
# Gere uma mensagem sobre o início do processo
log_msg(str_glue("Tentativa de download/importação {tentativa}/{max_tentativas}"))
resultado <- tryCatch({
# Baixe o dado da fonte e salve-o localmente, caso ele ainda não exista
if (!file.exists(file.path(pasta_dados_originais, arq_orig))) {
request(base_url) |>
req_url_path_append("dados_abertos") |>
req_url_path_append(arq_orig) |>
req_perform(path = file.path(pasta_dados_originais, arq_orig))
}
## Renomeie a pasta original do dado de 2025, assumindo o mesmo padrão dos anos anteriores
if (str_detect(arq_orig, "_\\.zip$")) {
novo_nome <- str_replace(arq_orig, "_\\.zip$", ".zip")
caminho_novo <- path(pasta_dados_originais, novo_nome)
fs::file_move(file.path(pasta_dados_originais, arq_orig), caminho_novo)
}
## Descompacte os dados
### Defina o caminho do arquivo compactado (.zip)
arq_zip <- dir_ls(pasta_dados_originais, type = "file", regexp = glue::glue("microdados_censo_escolar_{ano}\\.zip$"))
### Extraia os dados dos arquivos compactados e salve-os na pasta de dados originais
zip::unzip(
zipfile = arq_zip,
exdir = pasta_dados_originais,
overwrite = TRUE)
## Importe os dados para o ambiente do R
### Localize os microdados (dados descompactados)
#### Trate o caso de 2022, que apresenta especificidades
if (ano == 2022) {
# Liste o nome do diretòrio desconsiderando os caracteres especiais
pasta_2022 <- dir_ls(
path = pasta_dados_originais,
type = "directory",
regexp = str_glue("Censo.*Escolar.*{ano}"),
ignore.case = TRUE
)
# Altere o nome da pasta para o ano de 2022
if (length(pasta_2022) == 1) {
pasta_destino <- file.path(pasta_dados_originais, str_c("microdados_censo_escolar_", ano))
if (!dir_exists(pasta_destino)) {
file_move(pasta_2022, pasta_destino)
}
}
}
if (ano != 2025) {
micro_base <- dir_ls(
path = file.path(pasta_dados_originais, str_c("microdados_censo_escolar_", ano)),
recurse = TRUE,
type = "file",
# Garante que, excluído o caso de 2025, apenas os microdados serão registrados
regexp = str_glue("microdados_ed_basica_{ano}\\.csv$")
)
} else {
micro_base <- dir_ls(
path = file.path(pasta_dados_originais, str_c("microdados_censo_escolar_", ano)),
recurse = TRUE,
type = "file",
glob = "*.csv"
) |>
str_subset(
pattern = "Curso_Tecnico_2025",
negate = TRUE)
}
### Crie uma mensagem indicando a ausência do arquivo, caso ele não seja encontrado
if (length(micro_base) == 0) stop("Arquivo CSV de microdados não encontrado")
### Leia os dados brutos (microdados)
if (ano != 2025) {
micro_orig <- read_delim(
micro_base,
delim = ";",
locale = locale(
decimal_mark = ",",
grouping_mark = ".",
encoding = "latin1"),
col_types = cols(.default = col_character())) |>
clean_names() |>
arrange(co_entidade)
} else {
micro_orig <- micro_base |>
# Leia os dados de cada arquivo
map(
~ read_csv2(.x,
show_col_types = FALSE,
locale = locale(encoding = "latin1"), # ISO-8859-1
col_types = cols(.default = col_character()))
) |>
# Junte todos os arquivos em uma base única
reduce(full_join, by = c("CO_ENTIDADE", "NU_ANO_CENSO")
) |>
# Padronize a nomenclatura das variáveis
janitor::clean_names() |>
# Organize a base a partir do código das escolas
arrange(co_entidade)
}
### Crie uma mensagem indicando o número de linhas e colunas do dado bruto carregado (microdado)
log_msg(str_glue("Dados brutos carregados: {nrow(micro_orig)} linhas, {ncol(micro_orig)} colunas"))
# Transformação e organização dos dados
microdados_esc_ativ <- micro_orig |>
# Selecione as variáveis de interesse
select(nu_ano_censo, sg_uf, no_municipio, co_municipio, co_cep, ds_endereco, nu_endereco, no_bairro, no_entidade, co_entidade, tp_dependencia, tp_situacao_funcionamento, qt_mat_bas
) |>
# Filtre apenas as escolas ativas (em funcionamento e com ao menos 1 matrícula)
filter(
tp_situacao_funcionamento == 1 &
if_any(starts_with("qt_mat"), ~ . > 0)) |>
select(!tp_situacao_funcionamento) |>
# Mude a classe de algumas variáveis
mutate(
# Substitua os valores 88888 por NA nas variáveis numéricas
across(where(is.numeric), ~ na_if(., 88888)),
# Recodifique a variável de tipo de dependência administrativa
tp_dependencia = recode(tp_dependencia,
"1" = "Pública - Federal",
"2" = "Pública - Estadual",
"3" = "Pública - Municipal",
"4" = "Privada")
) |>
# Renomeie as variáveis para o padrão utilizado na plataforma GeoReDUS
rename(
ano_cn_escolar = nu_ano_censo,
nm_mun = no_municipio,
cod_mun = co_municipio,
cep = co_cep,
endereco = ds_endereco,
num_endereco = nu_endereco,
nm_bairro = no_bairro,
nm_escola = no_entidade,
cod_escola = co_entidade,
tp_adm = tp_dependencia
)
## Crie uma mensagem indicando o número de linhas e colunas do dado final gerado (microdados das escolas ativas)
log_msg(str_glue("Base final gerada: {nrow(microdados_esc_ativ)} escolas ativas, {ncol(microdados_esc_ativ)} variáveis"))
## Crie uma mensagem explicitando os possíveis erros
return(list(status = "sucesso", dados = microdados_esc_ativ))
}, error = function(e) {
log_msg(str_glue("Erro: {e$message}"), "ERRO")
if (tentativa < max_tentativas) {
espera <- 2^tentativa
log_msg(str_glue("Aguardando {espera}s antes da próxima tentativa"), "NOVA TENTATIVA")
Sys.sleep(espera)
}
return(list(status = "erro", mensagem = e$message))
})
if (resultado$status == "sucesso") return(resultado$dados)
}
## Crie uma mensagem sobre eventuais falhas definitivas
log_msg("Falha após todas as tentativas", "FALHA")
return(NULL)
}Implementando a função para o acesso e tratamento dos dados
Criada a função, basta aplicá-la ao conjunto de dados de interesse. O resultado esperado, neste caso, é a geração dos microdados das escolas ativas para cada um dos anos analisados.
Escolas ativas são aquelas que, de acordo com os dados do censo escolar, estão em funcionamento e apresentam ao menos uma matrícula ativa.
# Implementação da leitura, tratamento e organização dos dados para cada censo
## Mensagem indicando o início do processamento dos dados de todos os anos
message(strrep("=", 50))
message("🚀 Processamento dos Censos Escolares")
message(strrep("=", 50))
## Aplique a função de processamento para cada ano e armazene os resultados em uma lista
resultados <- censo_esc_anos |>
set_names(str_c("microdados_esc_ativ_", censo_esc_anos)) |>
map(processar_censo_ano)
## Salve os casos em que o processamento foi bem-sucedido e os casos em que houve falha
result_posit <- compact(resultados)
## Salve os casos em que houve falha
sel_falha <- map_lgl(resultados, is.null)
result_negat <- resultados[sel_falha]
## Crie uma base única com os dados dos censos
base_unic_cens_edu_orig <- result_posit |>
map("dados") |>
keep(is.data.frame) |>
list_rbind()
## Gere um resumo sobre todo o procedimento ("Relatório final")
message("\n", strrep("=", 50))
message("📊 RESUMO:")
message(str_glue("✅ Sucesso: {length(result_posit)} anos"))
if (length(result_posit) > 0) {
iwalk(result_posit, ~ message(str_glue(" ├─ {.y}: {nrow(.x)} escolas, {ncol(.x)} variáveis")))
}
if (length(result_negat) > 0) {
message(str_glue("❌ Falha: {length(result_negat)} anos"))
iwalk(result_negat, ~ message(str_glue(" └─ {.y} (verifique os logs)")))
}
message(strrep("=", 50))Explorando os dados dos Censos Escolares (2022, 2023, 2024, 2025)
Mapeando as escolas ao longo dos anos
A partir da base única criada (base_unic_cens_edu_orig), torna-se possível identificar a presença de cada escola ao longo do tempo. Tomando como exemplo o caso hipotético de uma escola presente em três anos distintos, o seu registro na base (associado as suas características) ocuparia três linhas, uma para cada ano.
Para facilitar a visualização desse quadro e sintetizar essas informações, três variáveis serão geradas:
no_censo_pres: quantifica o número de vezes que a escola aparece durante o período analisado (por ex., o número 3 indica que a escola está presente em três levantamentos);ano_censos_pres: registra o ano dos censos em que a escola está presente (usando o mesmo exemplo anterior, o registro seria igual a “2023, 2024 e 2025”), e,tipo_censos_pres: expressa, por meio de classes, o número de vezes que a escola aparece na base.
# Mapeie os casos exclusivos e os compartilhados, mantendo todos os registros originais em uma mesma base
base_unica_map_com_rep <- base_unic_cens_edu_orig |>
# Agrupe os dados em função dos código das escolas
group_by(cod_escola) |>
mutate(
# Conte o número de escolas por código único (lembre-se que dados de anos distintos foram integrados, possibilitando a repetição do cód. únic.)
no_censos_pres = n(),
# Registre o(s) ano(s) de origem associados ao cômputo dos cód. únic.
ano_censos_pres = str_c(sort(unique(ano_cn_escolar)), collapse = ", "),
# Crie uma variável para nomear as classes relacionadas ao cômputo feito
tipo_censos_pres = case_when(
no_censos_pres == 1 ~ "1_base",
no_censos_pres == 2 ~ "2_bases",
no_censos_pres == 3 ~ "3_bases",
no_censos_pres == 4 ~ "4_bases")
) |>
# Desfaça os grupos criados
ungroup()
glimpse(base_unica_map_com_rep)Rows: 714,874
Columns: 15
$ ano_cn_escolar <chr> "2022", "2022", "2022", "2022", "2022", "2022", "2022…
$ sg_uf <chr> "RO", "RO", "RO", "RO", "RO", "RO", "RO", "RO", "RO",…
$ nm_mun <chr> "Porto Velho", "Porto Velho", "Porto Velho", "Porto V…
$ cod_mun <chr> "1100205", "1100205", "1100205", "1100205", "1100205"…
$ cep <chr> "76824556", "76808108", "76801123", "76804214", "7682…
$ endereco <chr> "AVENIDA AMAZONAS", "RUA CAETANO", "AVENIDA CARLOS GO…
$ num_endereco <chr> "6492", "3256", "1135", "1483", "1056", "605", "4767"…
$ nm_bairro <chr> "TIRADENTES", "CALADINHO", "CENTRO", "SANTA BARBARA",…
$ nm_escola <chr> "EEEE ABNAEL MACHADO DE LIMA - CENE", "EMEIEF PEQUENO…
$ cod_escola <chr> "11000023", "11000040", "11000058", "11000082", "1100…
$ tp_adm <chr> "Pública - Estadual", "Pública - Municipal", "Privada…
$ qt_mat_bas <chr> "72", "244", "1289", "80", "750", "175", "976", "300"…
$ no_censos_pres <int> 4, 4, 4, 3, 4, 1, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4,…
$ ano_censos_pres <chr> "2022, 2023, 2024, 2025", "2022, 2023, 2024, 2025", "…
$ tipo_censos_pres <chr> "4_bases", "4_bases", "4_bases", "3_bases", "4_bases"…
A seguir, busca-se evidenciar quais são as escolas presentes em mais de um censo educacional. Para isso, o cômputo considera todos os anos do censo analisados (essa definição foi feita no objeto censo_esc_anos).
| Presença em mais de um censo escolar | Anos | Total de escolas |
|---|---|---|
| 2_bases | 2022, 2023 | 2585 |
| 2_bases | 2022, 2024 | 193 |
| 2_bases | 2022, 2025 | 111 |
| 3_bases | 2022, 2023, 2024 | 4013 |
| 3_bases | 2022, 2023, 2025 | 355 |
| 3_bases | 2022, 2024, 2025 | 490 |
| 4_bases | 2022, 2023, 2024, 2025 | 167499 |
| Presença em mais de um censo escolar | Anos | Total de escolas |
|---|---|---|
| 2_bases | 2022, 2023 | 2585 |
| 2_bases | 2023, 2024 | 320 |
| 2_bases | 2023, 2025 | 65 |
| 3_bases | 2022, 2023, 2024 | 4013 |
| 3_bases | 2022, 2023, 2025 | 355 |
| 3_bases | 2023, 2024, 2025 | 3367 |
| 4_bases | 2022, 2023, 2024, 2025 | 167499 |
| Presença em mais de um censo escolar | Anos | Total de escolas |
|---|---|---|
| 2_bases | 2022, 2024 | 193 |
| 2_bases | 2023, 2024 | 320 |
| 2_bases | 2024, 2025 | 3108 |
| 3_bases | 2022, 2023, 2024 | 4013 |
| 3_bases | 2022, 2024, 2025 | 490 |
| 3_bases | 2023, 2024, 2025 | 3367 |
| 4_bases | 2022, 2023, 2024, 2025 | 167499 |
| Presença em mais de um censo escolar | Anos | Total de escolas |
|---|---|---|
| 2_bases | 2022, 2025 | 111 |
| 2_bases | 2023, 2025 | 65 |
| 2_bases | 2024, 2025 | 3108 |
| 3_bases | 2022, 2023, 2025 | 355 |
| 3_bases | 2022, 2024, 2025 | 490 |
| 3_bases | 2023, 2024, 2025 | 3367 |
| 4_bases | 2022, 2023, 2024, 2025 | 167499 |
Considerando os dados expostos, que tratam das escolas presentes em mais de um censo escolar, duas constatações podem ser feitas:
- A depender do ano de referência da base, os números variam para os casos em que uma escola está presente em dois censos ou três anos;
- Independentemente do ano de referência, o número de escolas presentes em todos os levantamentos é o mesmo (167499).
Criando uma base única sem repetição de escolas
Considerando o objetivo final do presente procedimento (disponibilizar o dado geoespacial mais qualificado e atualizado possível das escolas), passa-se à criação da primeira base sintética referente ao período abrangido. Diferentemente do que ocorre com a base geral produzida anteriormente (base_unica_map_com_rep), neste caso o conjunto de escolas presentes em todos os anos analisados não contará com repetições.
Nesse sentido, é importante destacar a necessidade de se assumir um ano de referência para a geração dessa base. Afinal, a base única anterior abrange múltiplos anos e os dados da nova base proposta devem estar, em última instância, atrelados a um ano específico.
Do ponto de vista teórico, a fonte ideal seria a base mais atual. Isso porque, com o tempo as instituições produtoras de dados podem corrigir eventuais falhas, omissões e/ou prestar novos esclarecimentos sobre as possibilidade e as limitações de seus dados. Contudo, a análise empírica entre os anos dos censos escolares mostram que o dado sobre o logradouro (variável endereco) das escolas de 2025 muitas vezes encontra-se sem a denominação de seu tipo (“rua”, “avenida”, etc.). Esse fato, que é um fator limitante, atrelado à busca pelo dado mais atualizado, levou à escolha de 2024 como o ano de referência mais adequado para esta etapa.
Definida a referência temporal, a seguir cria-se a base com todas as escolas presentes durante o período analisado, incluindo-se os casos presentes em apenas um ano.
# Crie uma base sem as repetições dos registros originais por anos (REF.: 2024).
base_unica_map <- base_unica_map_com_rep |>
mutate(ano_cn_escolar = factor(ano_cn_escolar, levels = c(2025, 2022, 2023, 2024))) |> # Para ordernar em função dos anos mais recentes, substitua o parâmetro "levels = c(...)" por "ordered = TRUE"
arrange(cod_escola, desc(no_censos_pres), desc(ano_cn_escolar)) |>
distinct(cod_escola, .keep_all = T)
glimpse(base_unica_map)Rows: 189,545
Columns: 15
$ ano_cn_escolar <fct> 2024, 2024, 2024, 2024, 2024, 2022, 2024, 2024, 2024,…
$ sg_uf <chr> "RO", "RO", "RO", "RO", "RO", "RO", "RO", "RO", "RO",…
$ nm_mun <chr> "Porto Velho", "Porto Velho", "Porto Velho", "Porto V…
$ cod_mun <chr> "1100205", "1100205", "1100205", "1100205", "1100205"…
$ cep <chr> "76824556", "76808108", "76801123", "76804214", "7682…
$ endereco <chr> "AVENIDA AMAZONAS", "RUA CAETANO", "AVENIDA CARLOS GO…
$ num_endereco <chr> "6492", "3256", "1135", "1483", "1056", "605", "4767"…
$ nm_bairro <chr> "TIRADENTES", "CALADINHO", "CENTRO", "SANTA BARBARA",…
$ nm_escola <chr> "EEEE ABNAEL MACHADO DE LIMA - CENE", "EMEIEF PEQUENO…
$ cod_escola <chr> "11000023", "11000040", "11000058", "11000082", "1100…
$ tp_adm <chr> "Pública - Estadual", "Pública - Municipal", "Privada…
$ qt_mat_bas <chr> "71", "207", "1135", "58", "556", "175", "1046", "285…
$ no_censos_pres <int> 4, 4, 4, 3, 4, 1, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4,…
$ ano_censos_pres <chr> "2022, 2023, 2024, 2025", "2022, 2023, 2024, 2025", "…
$ tipo_censos_pres <chr> "4_bases", "4_bases", "4_bases", "3_bases", "4_bases"…
A partir do exposto, é possível notar que a nova base conta com 189545 escolas.
De forma a visualizar melhor os dados, a seguir são apresentados um gráfico e duas tabelas ilustrando a presença das escolas ao longo do tempo. Enquanto a primeira tabela indica a origem (ano) dos dados que foram selecionados para compor a base, a segunda evidencia a presença/permanência das escolas ao longo do tempo.
# Verifique a procedência dos dados (ano)
base_unica_map_cnt_ano_orig <- base_unica_map |>
count(ano_cn_escolar, sort = T, name = "tot_escolas") |>
mutate(prop = scales::percent(tot_escolas/sum(tot_escolas), accuracy = 0.1))
# Compare a presença das escolas ao longo dos anos - ano mais atual (2024), após análise empírica
base_unica_map_cnt_anos <- base_unica_map |>
mutate(tipo_censos_pres = factor(tipo_censos_pres)) |>
# group_by(sg_uf) |> # Ative para ver o comportamento por estados. Caso queira realizar a leitura por município, acrescente a variável "nm_mun"
count(tipo_censos_pres , ano_censos_pres, name = "tot_escolas") |>
mutate(prop = scales::percent(tot_escolas/sum(tot_escolas), accuracy = 0.1)) |>
arrange(desc(tipo_censos_pres), ano_censos_pres)
# Plote as duas tabelas
## Origem do dado
base_unica_map_cnt_ano_orig |>
janitor::adorn_totals() |>
knitr::kable(col.names = c("Ano de origem do censo escolar", "Total de escolas", "Proporção"), caption = "Origem dos dados escolares (ano)", align = 'ccc')| Ano de origem do censo escolar | Total de escolas | Proporção |
|---|---|---|
| 2024 | 179286 | 94.6% |
| 2025 | 3771 | 2.0% |
| 2023 | 3277 | 1.7% |
| 2022 | 3211 | 1.7% |
| Total | 189545 | - |
## Presença ao longo dos anos
base_unica_map_cnt_anos |>
janitor::adorn_totals() |>
knitr::kable(col.names = c("Presença das escolas", "Anos", "Total de escolas", "Proporção (%)"), caption = "Presença das escolas ao longo dos censos escolares (contagem por ano)", align = "llcc")| Presença das escolas | Anos | Total de escolas | Proporção (%) |
|---|---|---|---|
| 4_bases | 2022, 2023, 2024, 2025 | 167499 | 88.4% |
| 3_bases | 2022, 2023, 2024 | 4013 | 2.1% |
| 3_bases | 2022, 2023, 2025 | 355 | 0.2% |
| 3_bases | 2022, 2024, 2025 | 490 | 0.3% |
| 3_bases | 2023, 2024, 2025 | 3367 | 1.8% |
| 2_bases | 2022, 2023 | 2585 | 1.4% |
| 2_bases | 2022, 2024 | 193 | 0.1% |
| 2_bases | 2022, 2025 | 111 | 0.1% |
| 2_bases | 2023, 2024 | 320 | 0.2% |
| 2_bases | 2023, 2025 | 65 | 0.0% |
| 2_bases | 2024, 2025 | 3108 | 1.6% |
| 1_base | 2022 | 3100 | 1.6% |
| 1_base | 2023 | 272 | 0.1% |
| 1_base | 2024 | 296 | 0.2% |
| 1_base | 2025 | 3771 | 2.0% |
| Total | - | 189545 | - |
Como esperado, a maioria dos dados que compõem a base são de 2024, ano de referência adotado anteriormente. Por sua vez, a segunda tabela reforça alguns dados conhecidos, como a permanência de grande parte das escolas ao longo do período analisado (base_unica_map_cnt_anos[1, "prop"] |> pull()), e revela os que estão presentes em apenas em um ano do período. Esse mesmo quadro é exposto no gráfico a seguir.
base_unica_map_cnt_ano_orig |>
mutate(
label_val_abs_rel = str_c(tot_escolas, "\n(", prop, ")"),
label_pos = tot_escolas + max(tot_escolas) * 0.025) |>
ggplot(aes(x = fct_infreq(ano_cn_escolar), y = tot_escolas)) +
geom_col(fill = "#4C6CB3") +
geom_text(aes(y = label_pos, label = label_val_abs_rel),
hjust = -0.05,
size = 4,
fontface = "bold") +
labs(
title = "Mapeamento das escolas nos censos escolares",
subtitle = ("Base de origem do dado (Brasil)"),
x = NULL,
y = NULL
) +
coord_flip() +
theme_classic() +
theme(
plot.title = element_text(size = 20),
plot.subtitle = element_text(size = 15),
axis.line.x = element_blank(),
axis.ticks.x = element_blank(),
axis.text.x = element_blank(),
axis.title.x = element_blank(),
axis.text.y = element_text(size = 12.5)
)# Gere um gráfico para representar a presença das escolas ao longo dos anos (Brasil)
base_unica_map_cnt_anos|>
mutate(
ano_censos_pres = fct_rev(fct_infreq(ano_censos_pres)),
label_val_abs_rel = str_c(tot_escolas, "\n(", prop, ")"),
label_pos = tot_escolas + max(tot_escolas) * 0.025) |>
ggplot(aes(x = fct_reorder(ano_censos_pres, tot_escolas), y = tot_escolas)) +
geom_col(fill = "#4C6CB3") +
geom_text(aes(y = label_pos, label = label_val_abs_rel),
hjust = -0.05,
size = 3.5,
fontface = "bold") +
labs(
title = "Mapeamento das escolas nos censos escolares",
subtitle = c("Contagem da presença de cada unidade ao longo dos anos (Brasil)"),
x = NULL) +
coord_flip() +
theme_classic() +
theme(
plot.title = element_text(size = 20),
plot.title.position = "plot",
plot.subtitle = element_text(size = 15),
axis.line.x = element_blank(),
axis.ticks.x = element_blank(),
axis.text.x = element_blank(),
axis.title.x = element_blank(),
axis.text.y = element_text(size = 12.5)
)A partir das tabelas, verifica-se que após a seleção de 2024 como ano referência, 94.6% (179286) dos dados das escolas são provenientes dessa base. Por sua vez, ao analisarmos a presença das escolas ao longo do tempo, nota-se que 88.4% (167499) estão presentes ao longo do período analisado, indicando uma estabilidade para o Brasil, como um todo.
Os dados por estado, por sua vez, podem ser vistos a seguir.
# Crie uma tabela para representar a presença das escolas ao longo dos anos por ESTADOS
base_unica_map_cnt_anos_uf <- base_unica_map |>
mutate(
# tipo_censos_pres = factor(tipo_censos_pres , labels = c("Comum (3 bases)", "Compartilhado (2 bases)", "Exclusivo (1 base)")),
ano_censos_pres =
fct_relevel(ano_censos_pres, "2022, 2023, 2024, 2025", "2022, 2023, 2024", "2022, 2023, 2025", "2022, 2024, 2025", "2023, 2024, 2025", "2022, 2023", "2022, 2024", "2022, 2025", "2023, 2024", "2023, 2025", "2024, 2025", "2022", "2023", "2024", "2025" )) |>
group_by(sg_uf, .drop = FALSE) |> # Caso queira realizar a leitura por município, acrescente a variável "nm_mun"
count(ano_censos_pres, name = "tot_escolas") |>
mutate(prop = scales::percent(tot_escolas/sum(tot_escolas), accuracy = 0.1))
base_unica_map_cnt_anos_uf |>
janitor::adorn_totals() |>
kable(col.names = c("Estado", "Ano do censo", "Total de escolas", "Proporção (%)"), align = 'clcc') # Caso o município tenha sido incluído no objeto anterior, ele tb deverá ser adicionado no parâmetro "col.names", entre as etiquetas "Estado" e "Ano do censo".| Estado | Ano do censo | Total de escolas | Proporção (%) |
|---|---|---|---|
| AC | 2022, 2023, 2024, 2025 | 1428 | 89.0% |
| AC | 2022, 2023, 2024 | 32 | 2.0% |
| AC | 2022, 2023, 2025 | 8 | 0.5% |
| AC | 2022, 2024, 2025 | 4 | 0.2% |
| AC | 2023, 2024, 2025 | 25 | 1.6% |
| AC | 2022, 2023 | 19 | 1.2% |
| AC | 2022, 2024 | 0 | 0.0% |
| AC | 2022, 2025 | 4 | 0.2% |
| AC | 2023, 2024 | 2 | 0.1% |
| AC | 2023, 2025 | 2 | 0.1% |
| AC | 2024, 2025 | 22 | 1.4% |
| AC | 2022 | 28 | 1.7% |
| AC | 2023 | 0 | 0.0% |
| AC | 2024 | 3 | 0.2% |
| AC | 2025 | 28 | 1.7% |
| AL | 2022, 2023, 2024, 2025 | 2590 | 82.7% |
| AL | 2022, 2023, 2024 | 101 | 3.2% |
| AL | 2022, 2023, 2025 | 8 | 0.3% |
| AL | 2022, 2024, 2025 | 17 | 0.5% |
| AL | 2023, 2024, 2025 | 89 | 2.8% |
| AL | 2022, 2023 | 59 | 1.9% |
| AL | 2022, 2024 | 6 | 0.2% |
| AL | 2022, 2025 | 3 | 0.1% |
| AL | 2023, 2024 | 10 | 0.3% |
| AL | 2023, 2025 | 1 | 0.0% |
| AL | 2024, 2025 | 77 | 2.5% |
| AL | 2022 | 81 | 2.6% |
| AL | 2023 | 7 | 0.2% |
| AL | 2024 | 17 | 0.5% |
| AL | 2025 | 66 | 2.1% |
| AM | 2022, 2023, 2024, 2025 | 5164 | 89.7% |
| AM | 2022, 2023, 2024 | 74 | 1.3% |
| AM | 2022, 2023, 2025 | 12 | 0.2% |
| AM | 2022, 2024, 2025 | 19 | 0.3% |
| AM | 2023, 2024, 2025 | 118 | 2.0% |
| AM | 2022, 2023 | 55 | 1.0% |
| AM | 2022, 2024 | 2 | 0.0% |
| AM | 2022, 2025 | 4 | 0.1% |
| AM | 2023, 2024 | 5 | 0.1% |
| AM | 2023, 2025 | 2 | 0.0% |
| AM | 2024, 2025 | 125 | 2.2% |
| AM | 2022 | 72 | 1.3% |
| AM | 2023 | 1 | 0.0% |
| AM | 2024 | 12 | 0.2% |
| AM | 2025 | 92 | 1.6% |
| AP | 2022, 2023, 2024, 2025 | 820 | 90.4% |
| AP | 2022, 2023, 2024 | 15 | 1.7% |
| AP | 2022, 2023, 2025 | 0 | 0.0% |
| AP | 2022, 2024, 2025 | 2 | 0.2% |
| AP | 2023, 2024, 2025 | 19 | 2.1% |
| AP | 2022, 2023 | 14 | 1.5% |
| AP | 2022, 2024 | 0 | 0.0% |
| AP | 2022, 2025 | 0 | 0.0% |
| AP | 2023, 2024 | 0 | 0.0% |
| AP | 2023, 2025 | 0 | 0.0% |
| AP | 2024, 2025 | 9 | 1.0% |
| AP | 2022 | 11 | 1.2% |
| AP | 2023 | 2 | 0.2% |
| AP | 2024 | 1 | 0.1% |
| AP | 2025 | 14 | 1.5% |
| BA | 2022, 2023, 2024, 2025 | 14540 | 84.0% |
| BA | 2022, 2023, 2024 | 597 | 3.5% |
| BA | 2022, 2023, 2025 | 37 | 0.2% |
| BA | 2022, 2024, 2025 | 75 | 0.4% |
| BA | 2023, 2024, 2025 | 266 | 1.5% |
| BA | 2022, 2023 | 263 | 1.5% |
| BA | 2022, 2024 | 38 | 0.2% |
| BA | 2022, 2025 | 19 | 0.1% |
| BA | 2023, 2024 | 60 | 0.3% |
| BA | 2023, 2025 | 8 | 0.0% |
| BA | 2024, 2025 | 240 | 1.4% |
| BA | 2022 | 376 | 2.2% |
| BA | 2023 | 60 | 0.3% |
| BA | 2024 | 54 | 0.3% |
| BA | 2025 | 669 | 3.9% |
| CE | 2022, 2023, 2024, 2025 | 6989 | 86.9% |
| CE | 2022, 2023, 2024 | 160 | 2.0% |
| CE | 2022, 2023, 2025 | 9 | 0.1% |
| CE | 2022, 2024, 2025 | 22 | 0.3% |
| CE | 2023, 2024, 2025 | 261 | 3.2% |
| CE | 2022, 2023 | 91 | 1.1% |
| CE | 2022, 2024 | 10 | 0.1% |
| CE | 2022, 2025 | 4 | 0.0% |
| CE | 2023, 2024 | 14 | 0.2% |
| CE | 2023, 2025 | 7 | 0.1% |
| CE | 2024, 2025 | 158 | 2.0% |
| CE | 2022 | 114 | 1.4% |
| CE | 2023 | 22 | 0.3% |
| CE | 2024 | 8 | 0.1% |
| CE | 2025 | 178 | 2.2% |
| DF | 2022, 2023, 2024, 2025 | 1157 | 83.1% |
| DF | 2022, 2023, 2024 | 34 | 2.4% |
| DF | 2022, 2023, 2025 | 10 | 0.7% |
| DF | 2022, 2024, 2025 | 7 | 0.5% |
| DF | 2023, 2024, 2025 | 27 | 1.9% |
| DF | 2022, 2023 | 26 | 1.9% |
| DF | 2022, 2024 | 4 | 0.3% |
| DF | 2022, 2025 | 2 | 0.1% |
| DF | 2023, 2024 | 6 | 0.4% |
| DF | 2023, 2025 | 0 | 0.0% |
| DF | 2024, 2025 | 44 | 3.2% |
| DF | 2022 | 22 | 1.6% |
| DF | 2023 | 4 | 0.3% |
| DF | 2024 | 5 | 0.4% |
| DF | 2025 | 44 | 3.2% |
| ES | 2022, 2023, 2024, 2025 | 2883 | 92.0% |
| ES | 2022, 2023, 2024 | 49 | 1.6% |
| ES | 2022, 2023, 2025 | 1 | 0.0% |
| ES | 2022, 2024, 2025 | 3 | 0.1% |
| ES | 2023, 2024, 2025 | 29 | 0.9% |
| ES | 2022, 2023 | 55 | 1.8% |
| ES | 2022, 2024 | 0 | 0.0% |
| ES | 2022, 2025 | 0 | 0.0% |
| ES | 2023, 2024 | 1 | 0.0% |
| ES | 2023, 2025 | 0 | 0.0% |
| ES | 2024, 2025 | 39 | 1.2% |
| ES | 2022 | 41 | 1.3% |
| ES | 2023 | 1 | 0.0% |
| ES | 2024 | 2 | 0.1% |
| ES | 2025 | 31 | 1.0% |
| GO | 2022, 2023, 2024, 2025 | 4358 | 87.5% |
| GO | 2022, 2023, 2024 | 106 | 2.1% |
| GO | 2022, 2023, 2025 | 11 | 0.2% |
| GO | 2022, 2024, 2025 | 19 | 0.4% |
| GO | 2023, 2024, 2025 | 93 | 1.9% |
| GO | 2022, 2023 | 58 | 1.2% |
| GO | 2022, 2024 | 13 | 0.3% |
| GO | 2022, 2025 | 2 | 0.0% |
| GO | 2023, 2024 | 12 | 0.2% |
| GO | 2023, 2025 | 1 | 0.0% |
| GO | 2024, 2025 | 108 | 2.2% |
| GO | 2022 | 48 | 1.0% |
| GO | 2023 | 10 | 0.2% |
| GO | 2024 | 9 | 0.2% |
| GO | 2025 | 130 | 2.6% |
| MA | 2022, 2023, 2024, 2025 | 10682 | 89.9% |
| MA | 2022, 2023, 2024 | 283 | 2.4% |
| MA | 2022, 2023, 2025 | 30 | 0.3% |
| MA | 2022, 2024, 2025 | 20 | 0.2% |
| MA | 2023, 2024, 2025 | 130 | 1.1% |
| MA | 2022, 2023 | 199 | 1.7% |
| MA | 2022, 2024 | 4 | 0.0% |
| MA | 2022, 2025 | 8 | 0.1% |
| MA | 2023, 2024 | 13 | 0.1% |
| MA | 2023, 2025 | 3 | 0.0% |
| MA | 2024, 2025 | 125 | 1.1% |
| MA | 2022 | 229 | 1.9% |
| MA | 2023 | 17 | 0.1% |
| MA | 2024 | 14 | 0.1% |
| MA | 2025 | 125 | 1.1% |
| MG | 2022, 2023, 2024, 2025 | 14806 | 88.5% |
| MG | 2022, 2023, 2024 | 318 | 1.9% |
| MG | 2022, 2023, 2025 | 14 | 0.1% |
| MG | 2022, 2024, 2025 | 32 | 0.2% |
| MG | 2023, 2024, 2025 | 302 | 1.8% |
| MG | 2022, 2023 | 198 | 1.2% |
| MG | 2022, 2024 | 5 | 0.0% |
| MG | 2022, 2025 | 8 | 0.0% |
| MG | 2023, 2024 | 29 | 0.2% |
| MG | 2023, 2025 | 3 | 0.0% |
| MG | 2024, 2025 | 260 | 1.6% |
| MG | 2022 | 282 | 1.7% |
| MG | 2023 | 15 | 0.1% |
| MG | 2024 | 27 | 0.2% |
| MG | 2025 | 424 | 2.5% |
| MS | 2022, 2023, 2024, 2025 | 1726 | 92.0% |
| MS | 2022, 2023, 2024 | 15 | 0.8% |
| MS | 2022, 2023, 2025 | 0 | 0.0% |
| MS | 2022, 2024, 2025 | 2 | 0.1% |
| MS | 2023, 2024, 2025 | 29 | 1.5% |
| MS | 2022, 2023 | 18 | 1.0% |
| MS | 2022, 2024 | 0 | 0.0% |
| MS | 2022, 2025 | 0 | 0.0% |
| MS | 2023, 2024 | 1 | 0.1% |
| MS | 2023, 2025 | 0 | 0.0% |
| MS | 2024, 2025 | 33 | 1.8% |
| MS | 2022 | 12 | 0.6% |
| MS | 2023 | 0 | 0.0% |
| MS | 2024 | 1 | 0.1% |
| MS | 2025 | 39 | 2.1% |
| MT | 2022, 2023, 2024, 2025 | 2467 | 84.0% |
| MT | 2022, 2023, 2024 | 69 | 2.4% |
| MT | 2022, 2023, 2025 | 7 | 0.2% |
| MT | 2022, 2024, 2025 | 10 | 0.3% |
| MT | 2023, 2024, 2025 | 77 | 2.6% |
| MT | 2022, 2023 | 83 | 2.8% |
| MT | 2022, 2024 | 2 | 0.1% |
| MT | 2022, 2025 | 2 | 0.1% |
| MT | 2023, 2024 | 12 | 0.4% |
| MT | 2023, 2025 | 1 | 0.0% |
| MT | 2024, 2025 | 57 | 1.9% |
| MT | 2022 | 60 | 2.0% |
| MT | 2023 | 3 | 0.1% |
| MT | 2024 | 6 | 0.2% |
| MT | 2025 | 80 | 2.7% |
| PA | 2022, 2023, 2024, 2025 | 9873 | 88.6% |
| PA | 2022, 2023, 2024 | 238 | 2.1% |
| PA | 2022, 2023, 2025 | 36 | 0.3% |
| PA | 2022, 2024, 2025 | 24 | 0.2% |
| PA | 2023, 2024, 2025 | 232 | 2.1% |
| PA | 2022, 2023 | 171 | 1.5% |
| PA | 2022, 2024 | 7 | 0.1% |
| PA | 2022, 2025 | 8 | 0.1% |
| PA | 2023, 2024 | 28 | 0.3% |
| PA | 2023, 2025 | 3 | 0.0% |
| PA | 2024, 2025 | 115 | 1.0% |
| PA | 2022 | 213 | 1.9% |
| PA | 2023 | 9 | 0.1% |
| PA | 2024 | 11 | 0.1% |
| PA | 2025 | 180 | 1.6% |
| PB | 2022, 2023, 2024, 2025 | 4358 | 87.6% |
| PB | 2022, 2023, 2024 | 111 | 2.2% |
| PB | 2022, 2023, 2025 | 14 | 0.3% |
| PB | 2022, 2024, 2025 | 13 | 0.3% |
| PB | 2023, 2024, 2025 | 85 | 1.7% |
| PB | 2022, 2023 | 81 | 1.6% |
| PB | 2022, 2024 | 6 | 0.1% |
| PB | 2022, 2025 | 3 | 0.1% |
| PB | 2023, 2024 | 6 | 0.1% |
| PB | 2023, 2025 | 0 | 0.0% |
| PB | 2024, 2025 | 53 | 1.1% |
| PB | 2022 | 137 | 2.8% |
| PB | 2023 | 5 | 0.1% |
| PB | 2024 | 3 | 0.1% |
| PB | 2025 | 98 | 2.0% |
| PE | 2022, 2023, 2024, 2025 | 7559 | 89.3% |
| PE | 2022, 2023, 2024 | 163 | 1.9% |
| PE | 2022, 2023, 2025 | 1 | 0.0% |
| PE | 2022, 2024, 2025 | 6 | 0.1% |
| PE | 2023, 2024, 2025 | 115 | 1.4% |
| PE | 2022, 2023 | 150 | 1.8% |
| PE | 2022, 2024 | 0 | 0.0% |
| PE | 2022, 2025 | 3 | 0.0% |
| PE | 2023, 2024 | 4 | 0.0% |
| PE | 2023, 2025 | 0 | 0.0% |
| PE | 2024, 2025 | 142 | 1.7% |
| PE | 2022 | 176 | 2.1% |
| PE | 2023 | 3 | 0.0% |
| PE | 2024 | 4 | 0.0% |
| PE | 2025 | 142 | 1.7% |
| PI | 2022, 2023, 2024, 2025 | 3803 | 86.6% |
| PI | 2022, 2023, 2024 | 223 | 5.1% |
| PI | 2022, 2023, 2025 | 8 | 0.2% |
| PI | 2022, 2024, 2025 | 4 | 0.1% |
| PI | 2023, 2024, 2025 | 48 | 1.1% |
| PI | 2022, 2023 | 64 | 1.5% |
| PI | 2022, 2024 | 4 | 0.1% |
| PI | 2022, 2025 | 5 | 0.1% |
| PI | 2023, 2024 | 4 | 0.1% |
| PI | 2023, 2025 | 1 | 0.0% |
| PI | 2024, 2025 | 54 | 1.2% |
| PI | 2022 | 113 | 2.6% |
| PI | 2023 | 3 | 0.1% |
| PI | 2024 | 3 | 0.1% |
| PI | 2025 | 53 | 1.2% |
| PR | 2022, 2023, 2024, 2025 | 9186 | 93.8% |
| PR | 2022, 2023, 2024 | 98 | 1.0% |
| PR | 2022, 2023, 2025 | 7 | 0.1% |
| PR | 2022, 2024, 2025 | 8 | 0.1% |
| PR | 2023, 2024, 2025 | 104 | 1.1% |
| PR | 2022, 2023 | 81 | 0.8% |
| PR | 2022, 2024 | 1 | 0.0% |
| PR | 2022, 2025 | 3 | 0.0% |
| PR | 2023, 2024 | 6 | 0.1% |
| PR | 2023, 2025 | 2 | 0.0% |
| PR | 2024, 2025 | 116 | 1.2% |
| PR | 2022 | 69 | 0.7% |
| PR | 2023 | 1 | 0.0% |
| PR | 2024 | 6 | 0.1% |
| PR | 2025 | 102 | 1.0% |
| RJ | 2022, 2023, 2024, 2025 | 10446 | 83.5% |
| RJ | 2022, 2023, 2024 | 357 | 2.9% |
| RJ | 2022, 2023, 2025 | 59 | 0.5% |
| RJ | 2022, 2024, 2025 | 103 | 0.8% |
| RJ | 2023, 2024, 2025 | 296 | 2.4% |
| RJ | 2022, 2023 | 181 | 1.4% |
| RJ | 2022, 2024 | 58 | 0.5% |
| RJ | 2022, 2025 | 7 | 0.1% |
| RJ | 2023, 2024 | 46 | 0.4% |
| RJ | 2023, 2025 | 12 | 0.1% |
| RJ | 2024, 2025 | 318 | 2.5% |
| RJ | 2022 | 227 | 1.8% |
| RJ | 2023 | 42 | 0.3% |
| RJ | 2024 | 40 | 0.3% |
| RJ | 2025 | 316 | 2.5% |
| RN | 2022, 2023, 2024, 2025 | 3202 | 89.7% |
| RN | 2022, 2023, 2024 | 81 | 2.3% |
| RN | 2022, 2023, 2025 | 11 | 0.3% |
| RN | 2022, 2024, 2025 | 9 | 0.3% |
| RN | 2023, 2024, 2025 | 46 | 1.3% |
| RN | 2022, 2023 | 36 | 1.0% |
| RN | 2022, 2024 | 0 | 0.0% |
| RN | 2022, 2025 | 5 | 0.1% |
| RN | 2023, 2024 | 8 | 0.2% |
| RN | 2023, 2025 | 2 | 0.1% |
| RN | 2024, 2025 | 56 | 1.6% |
| RN | 2022 | 54 | 1.5% |
| RN | 2023 | 9 | 0.3% |
| RN | 2024 | 12 | 0.3% |
| RN | 2025 | 37 | 1.0% |
| RO | 2022, 2023, 2024, 2025 | 1138 | 90.2% |
| RO | 2022, 2023, 2024 | 36 | 2.9% |
| RO | 2022, 2023, 2025 | 1 | 0.1% |
| RO | 2022, 2024, 2025 | 0 | 0.0% |
| RO | 2023, 2024, 2025 | 13 | 1.0% |
| RO | 2022, 2023 | 15 | 1.2% |
| RO | 2022, 2024 | 0 | 0.0% |
| RO | 2022, 2025 | 0 | 0.0% |
| RO | 2023, 2024 | 2 | 0.2% |
| RO | 2023, 2025 | 0 | 0.0% |
| RO | 2024, 2025 | 22 | 1.7% |
| RO | 2022 | 21 | 1.7% |
| RO | 2023 | 1 | 0.1% |
| RO | 2024 | 0 | 0.0% |
| RO | 2025 | 12 | 1.0% |
| RR | 2022, 2023, 2024, 2025 | 854 | 92.5% |
| RR | 2022, 2023, 2024 | 9 | 1.0% |
| RR | 2022, 2023, 2025 | 0 | 0.0% |
| RR | 2022, 2024, 2025 | 1 | 0.1% |
| RR | 2023, 2024, 2025 | 18 | 2.0% |
| RR | 2022, 2023 | 4 | 0.4% |
| RR | 2022, 2024 | 0 | 0.0% |
| RR | 2022, 2025 | 0 | 0.0% |
| RR | 2023, 2024 | 0 | 0.0% |
| RR | 2023, 2025 | 0 | 0.0% |
| RR | 2024, 2025 | 22 | 2.4% |
| RR | 2022 | 2 | 0.2% |
| RR | 2023 | 0 | 0.0% |
| RR | 2024 | 0 | 0.0% |
| RR | 2025 | 13 | 1.4% |
| RS | 2022, 2023, 2024, 2025 | 9342 | 90.0% |
| RS | 2022, 2023, 2024 | 200 | 1.9% |
| RS | 2022, 2023, 2025 | 18 | 0.2% |
| RS | 2022, 2024, 2025 | 20 | 0.2% |
| RS | 2023, 2024, 2025 | 180 | 1.7% |
| RS | 2022, 2023 | 124 | 1.2% |
| RS | 2022, 2024 | 10 | 0.1% |
| RS | 2022, 2025 | 4 | 0.0% |
| RS | 2023, 2024 | 12 | 0.1% |
| RS | 2023, 2025 | 5 | 0.0% |
| RS | 2024, 2025 | 140 | 1.3% |
| RS | 2022 | 134 | 1.3% |
| RS | 2023 | 15 | 0.1% |
| RS | 2024 | 16 | 0.2% |
| RS | 2025 | 165 | 1.6% |
| SC | 2022, 2023, 2024, 2025 | 6095 | 90.0% |
| SC | 2022, 2023, 2024 | 73 | 1.1% |
| SC | 2022, 2023, 2025 | 6 | 0.1% |
| SC | 2022, 2024, 2025 | 10 | 0.1% |
| SC | 2023, 2024, 2025 | 144 | 2.1% |
| SC | 2022, 2023 | 63 | 0.9% |
| SC | 2022, 2024 | 4 | 0.1% |
| SC | 2022, 2025 | 4 | 0.1% |
| SC | 2023, 2024 | 3 | 0.0% |
| SC | 2023, 2025 | 0 | 0.0% |
| SC | 2024, 2025 | 130 | 1.9% |
| SC | 2022 | 85 | 1.3% |
| SC | 2023 | 6 | 0.1% |
| SC | 2024 | 3 | 0.0% |
| SC | 2025 | 149 | 2.2% |
| SE | 2022, 2023, 2024, 2025 | 1908 | 88.0% |
| SE | 2022, 2023, 2024 | 63 | 2.9% |
| SE | 2022, 2023, 2025 | 0 | 0.0% |
| SE | 2022, 2024, 2025 | 0 | 0.0% |
| SE | 2023, 2024, 2025 | 25 | 1.2% |
| SE | 2022, 2023 | 39 | 1.8% |
| SE | 2022, 2024 | 2 | 0.1% |
| SE | 2022, 2025 | 2 | 0.1% |
| SE | 2023, 2024 | 2 | 0.1% |
| SE | 2023, 2025 | 0 | 0.0% |
| SE | 2024, 2025 | 34 | 1.6% |
| SE | 2022 | 55 | 2.5% |
| SE | 2023 | 3 | 0.1% |
| SE | 2024 | 5 | 0.2% |
| SE | 2025 | 30 | 1.4% |
| SP | 2022, 2023, 2024, 2025 | 28624 | 89.9% |
| SP | 2022, 2023, 2024 | 473 | 1.5% |
| SP | 2022, 2023, 2025 | 47 | 0.1% |
| SP | 2022, 2024, 2025 | 60 | 0.2% |
| SP | 2023, 2024, 2025 | 574 | 1.8% |
| SP | 2022, 2023 | 416 | 1.3% |
| SP | 2022, 2024 | 17 | 0.1% |
| SP | 2022, 2025 | 11 | 0.0% |
| SP | 2023, 2024 | 34 | 0.1% |
| SP | 2023, 2025 | 12 | 0.0% |
| SP | 2024, 2025 | 585 | 1.8% |
| SP | 2022 | 408 | 1.3% |
| SP | 2023 | 33 | 0.1% |
| SP | 2024 | 34 | 0.1% |
| SP | 2025 | 526 | 1.7% |
| TO | 2022, 2023, 2024, 2025 | 1501 | 90.3% |
| TO | 2022, 2023, 2024 | 35 | 2.1% |
| TO | 2022, 2023, 2025 | 0 | 0.0% |
| TO | 2022, 2024, 2025 | 0 | 0.0% |
| TO | 2023, 2024, 2025 | 22 | 1.3% |
| TO | 2022, 2023 | 22 | 1.3% |
| TO | 2022, 2024 | 0 | 0.0% |
| TO | 2022, 2025 | 0 | 0.0% |
| TO | 2023, 2024 | 0 | 0.0% |
| TO | 2023, 2025 | 0 | 0.0% |
| TO | 2024, 2025 | 24 | 1.4% |
| TO | 2022 | 30 | 1.8% |
| TO | 2023 | 0 | 0.0% |
| TO | 2024 | 0 | 0.0% |
| TO | 2025 | 28 | 1.7% |
| Total | - | 189545 | - |
# Gere um gráfico para representar a presença das escolas ao longo dos anos por ESTADOS
base_unica_map_cnt_anos_uf |>
mutate(
lab_val_abs_rel = str_c(tot_escolas, " (", prop,")")
) |>
ggplot(aes(x = fct_relevel(
ano_censos_pres,
c(
str_c("2023", "2024", "2025", sep = ", "),
str_c("2023", "2024", sep = ", "),
str_c("2023", "2025", sep = ", "),
str_c("2024", "2025", sep = ", "),
"2023", "2024", "2025")), y = tot_escolas)) +
geom_col(fill = "#4C6CB3") +
geom_text(aes(label = lab_val_abs_rel),
hjust = -0.1,
size = 2.25,
fontface = "bold") +
labs(
title = "Mapeamento das escolas nos censos escolares",
subtitle = glue::glue("Contagem da presença de cada unidade escolar ao longo dos anos por unidade federativa ({paste(censo_esc_anos, collapse = ', ')})"),
x = NULL) +
coord_flip() +
theme_classic() +
theme(axis.line.x = element_blank(),
axis.ticks.x = element_blank(),
axis.text.x = element_blank(),
axis.title.x = element_blank(),
axis.text.y = element_text(size = 7),
) +
facet_wrap(vars(sg_uf)) +
scale_y_continuous(expand = expansion(mult = c(0.00, 0.2)))Finalizada essa breve incursão exploratória, bem como a geração da base que será utilizada para a próxima etapa, a seguir passar-se-á à geocodificação.
Geocodificação
Acessando os dados do Catálogo de Escolas
Até o momento, os dados que permitem uma maior precisão para a localização das escolas referem-se às variáveis de logradouro e seus respectivos números. Contudo, nem sempre esses dados serão suficientes ou adequados, uma vez que para algumas escolas ou eles não existem ou indicam a localização de forma mais genérica (Estrada X, Terra Índigena, Área rural, etc.).
Para lidar com essa situação, uma nova base será explorada, o Catálogo de Escolas.
Baixe o dado original (“Catálogo de Escolas”) com a localização das escolas
De forma complementar aos dados presentes nos microdados do Censo Escolar, outra fonte que será utilizada para o processo de geocodificação, como recém mencionado, é o Catálogo de Escolas. Com os dados podendo ser acessados pelo site do Inep Data, essa base permite acessar um par de coordenadas geográficas associado a cada uma das escolas.
Essa etapa não é feita de forma automática
Para baixar os dados, acesse a url do Catálogo de Escolas. Na página, NÃO selecione nenhuma variável e clique em “Aplicar”.
O site gerará um relatório detalhado, apresentando o seguinte texto (19/02/26):
” Foram selecionadas 212.386 escolas. São apresentadas 25 escolas por página do relatório.
Quando selecionada a opção exportar, o resultado detalhado com todas as entidades retornadas na busca constarão do arquivo eletrônico.”
Em seguida, pressione o botão “Exportar” para baixar o arquivo em csv:
Análise - Tabela da lista das escolas - Detalhado.csv
Salve-o com o nome “catalogo_escolas” na pasta de dados originais criada no começo desse projeto.
Importe os dados originais do Catálogo de Escolas
A base do Catálogo de Escolas é formada por um conjunto de variáveis. Nem todas, porém, fornecem insumos para a geocodificação. Tendo isso em vista, o processo de importação a seguir seleciona apenas as variáveis que atendem a esse propósito.
# Importe os dados do catálogo de escolas
catalogo_escolas <- read_csv(file.path(pasta_dados_originais,
"catalogo_escolas.csv"),
locale = locale(
# decimal_mark = ",",
# grouping_mark = ".",
encoding = "UTF-8"),
col_select = all_of(c("Escola", "Código INEP", "Latitude", "Longitude")),
col_types = cols(
.default = col_character())) |>
clean_names()A partir da importação, é possível notar que o Catálogo de Escolas possui 212386 escolas cadastradas.
Renomeie, recodifique e selecione as variáveis de interesse (colunas)
Para facilitar a identificação e antecipar fontes eventuais de erros, a seguir as variáveis serão renomeadas e eventuais espaços na descrição das coordenadas geográficas eliminados.
# Renomeie as variáveis e elimine os eventuais espaços do campo das coordenadas geográficas
catalogo_escolas_geo <- catalogo_escolas |>
rename(
# Renomeie as variáveis
cod_escola = codigo_inep,
lat_inep = latitude,
long_inep = longitude
) |>
mutate(
# Remova os eventuais espaços extras das coord. geo.
lat_inep = trimws(lat_inep),
long_inep = trimws(long_inep)
) |>
select(cod_escola, lat_inep, long_inep)
glimpse(catalogo_escolas_geo)Rows: 212,386
Columns: 3
$ cod_escola <chr> "11000023", "11000040", "11000058", "11000082", "11000104",…
$ lat_inep <chr> "-8.758459", "-8.79373016", "-8.7607343", "-8.765205", "-8.…
$ long_inep <chr> "-63.8540109", "-63.88391863", "-63.9019859", "-63.8961767"…
Integrando as coordenadas geográficas (Catálogo de Escolas) à base única gerada anteriormente (microdados do Censo Escolar)
Com o acesso às coordenadas geográficas presentes no Catálogo de Escolas devidamente formatadas, a seguir será realizada a junção dessa base com a dos microdados gerada anteriormente (base_unica_map). Note, também, que uma nova coluna é criada (fonte_coord_geo). O objetivo é registrar a fonte original do dado.
# Crie uma base única a partir dos microdados e Catálogo de Escolas
escolas_geo <- base_unica_map |>
left_join(catalogo_escolas_geo, join_by("cod_escola")) |>
mutate(fonte_coord_geo = case_when(
!is.na(lat_inep) & !is.na(long_inep) ~ "catalogo_inep",
TRUE ~ NA))
# Verifique a fonte dos dados presentes na base
escolas_geo |>
count(fonte_coord_geo, name = "tot_escolas") |>
knitr::kable(col.names = c("Fonte do dado", "Total de escolas"), align = 'lc')| Fonte do dado | Total de escolas |
|---|---|
| catalogo_inep | 150374 |
| NA | 39171 |
Realizada a integração entre as bases (“microdados” e “catalogo_escolas”), verifica-se que boa parte das escolas possuem coordenadas geográficas (79.33). Ainda restam, contudo, 20.67% das escolas sem esse dado.
Prepare a base para a geocodificação (escolas sem coordenadas geográficas)
Para lidar com a ausência de dados mais precisos sobre a dimensão espacial de algumas escolas, as coordenadas faltantes serão obtidas por meio do geocodebr, pacote dispobilizado pelo IPEA.
Dois objetos serão, então, criados: escolas_com_coord_geo e escolas_sem_coord_geo. Enquanto o primeiro registra os casos que já possuem coordenadas geográficas, o segundo armazenará as escolas que não possuem esses dados.
As coordenadas geradas via geocodebr são estimativas obtidas a partir das informações textuais de endereço. Nesse sentido, é importante frisar que a precisão espacial obtida está diretamente relacionada ao nível de detalhamento e qualidade dessa informação (logradouro, número, CEP, etc.). A depender do caso, ela pode variar da localização aproximada do imóvel ao centróide de áreas mais amplas, como as abrangidas pelo CEP ou município. Portanto, as coordenadas geográficas assim estimadas devem ser utilizadas com cautela, especialmente em análises espaciais de grande detalhamento.
# Selecione as escolas com coordenadas geográficas
escolas_com_coord_geo <- escolas_geo |>
filter(!is.na(lat_inep) & !is.na(long_inep))
# Selecione as escolas sem coordenadas geográficas
escolas_sem_coord_geo <- escolas_geo |>
filter(is.na(lat_inep) | is.na(long_inep)) |>
select(!c(lat_inep, long_inep))Geocodifique com o Geocodebr
Identificado o conjunto de escolas sem coordenadas geográficas, a seguir o procedimento de geocodificação será realizado. É importante lembrar, porém, que a base gerada até o momento contém dados de diferentes anos. Tal escolha, longe de ser fortuita, está relacionada à busca pela melhor localização possível das escolas.
Tendo esse objetivo em vista, propõe-se um procedimento de compatibilização entre os anos. A ideia consiste, basicamente, em geocodificar os endereços de todos os anos, compará-los e selecionar aqueles que apresentam os melhores resultados.
Nesse sentido, inicialmente criam-se objetos com i) os códigos das escolas sem coordenadas geográficas e ii) as variáveis que auxiliarão o algoritmo de geocodificação.
# Selecione as variáveis que serão utilizadas na geocodificação
sel_var_geocod <- c("ano_cn_escolar", "cod_escola", "sg_uf", "nm_mun", "endereco", "num_endereco", "cep", "nm_bairro", "ano_censos_pres")
# Obtenha o código das escolas que não possuem coordenadas geográficas
sel_esc_sem_coordgeo <- escolas_sem_coord_geo |>
pull(var = cod_escola)
# Veja o número de escolas selecionadas
length(sel_esc_sem_coordgeo)[1] 39171
O próximo passo diz respeito à geração, de fato, das coordenadas geográficas para o conjunto de escolas que ainda não possui esses dados. Baseando-se no endereço registrado na base, um procedimento geral é proposto para implementar a geocodificação por ano (usa-se um for loop para isso).
O primeiro passo diz respeito à geração de uma lista vazia (resultados_geocod). Funcionando como insumo para as próximas etapas, o objetivo dessa lista é armazenar os resultados que serão produzidos pela geocodificação para cada um dos anos.
Em seguida, passa-se à estruturação da base. Mais especificamente, serão selecionadas as escolas e as variáveis de interesse (salvos no objeto base_esc_geocod_orig).
Com a base estruturada, o algoritimo de geocodificação pode ser implementado. Para isso, inicialmente serão definidos os parâmetros requeridos pelo algoritmo (campos). Vencido esse passo, executa-se a função geocode() do pacote Geocodebr. Note: de forma a explicitar uma exigência do algoritmo, o código a seguir inicia assegurando que todas as variáveis estão codificadas como character.
Finalizada a geocodificação, um novo conjunto de variáveis é gerado e acrescentado à base de entrada utilizada (escolas_geocod). De forma resumida, essas novas variáveis podem ser subdivididas em dois grupos: i) informações descritivas sobre a localização e ii) qualidade dos dados obtidos. Para o procedimento proposto, apenas algumas dessas variáveis serão retidas.
Por fim, o procedimento renomeia algumas variáveis (indicando o seu ano de origem) e salva os resultados na lista (inicialmente) vazia.
# Lista vazia para armazenar os resultados de cada ano
resultados_geocod <- list()
for(ano in censo_esc_anos) {
# Crie a base anual a ser geocodificada
base_esc_geocod_orig <- base_unica_map_com_rep |>
filter(cod_escola %in% sel_esc_sem_coordgeo & ano_cn_escolar == ano) |>
select(all_of(sel_var_geocod))
# Defina os campos que serão utilizados para a geocodificação
campos <- definir_campos(
estado = "sg_uf",
municipio = "nm_mun",
logradouro = "endereco",
numero = "num_endereco",
cep = "cep",
localidade = "nm_bairro")
# Transforme a classe das variáveis (exigência do algoritmo)
base_esc_geocod <- base_esc_geocod_orig |>
mutate(across(everything(), as.character))
# Realize a geocodificação
escolas_geocod <- geocode(
enderecos = base_esc_geocod,
campos_endereco = campos,
resultado_completo = TRUE,
resultado_sf = FALSE,
verboso = TRUE,
cache = TRUE)
# Selecione apenas as variáveis de interesse
escolas_geocod <- escolas_geocod |>
select(sg_uf, nm_mun, cod_escola, lat, lon, precisao, desvio_metros, tipo_resultado, ano_censos_pres)
# Renomeie as colunas (exceto as variáveis que permanecerão as mesmas), acrescentando o ano
## Crie objetos auxiliares para identificar quais variáveis serão alteradas
var_perm <- c("sg_uf", "nm_mun", "cod_escola")
outras_var <- setdiff(names(escolas_geocod), var_perm)
novos_nomes_var <- str_c(outras_var, "_", ano)
## Atribua os novos nomes as variáveis
escolas_geocod <- escolas_geocod |>
rename_with(
~ novos_nomes_var[which(outras_var == .x)],
.cols = all_of(outras_var))
# Guarde o resultado em uma lista
resultados_geocod[[str_c("esc_geocod_", as.character(ano))]] <- escolas_geocod
}ℹ Padronizando endereços de entrada
ℹ Utilizando dados do CNEFE armazenados localmente
ℹ Geolocalizando endereços
Casos processados: 0/29,162 ■ 0% - dn01
Casos processados: 3,416/29,162 ■■■■■ 12% - da01
Casos processados: 5,895/29,162 ■■■■■■■ 20% - pn01
Casos processados: 6,304/29,162 ■■■■■■■ 22% - pa01
Casos processados: 6,799/29,162 ■■■■■■■■ 23% - dn02
Casos processados: 7,830/29,162 ■■■■■■■■■ 27% - da02
Casos processados: 8,640/29,162 ■■■■■■■■■■ 30% - pn02
Casos processados: 8,753/29,162 ■■■■■■■■■■ 30% - pa02
Casos processados: 8,897/29,162 ■■■■■■■■■■ 31% - dn03
Casos processados: 9,152/29,162 ■■■■■■■■■■ 31% - da03
Casos processados: 9,349/29,162 ■■■■■■■■■■■ 32% - pn03
Casos processados: 9,400/29,162 ■■■■■■■■■■■ 32% - pa03
Casos processados: 9,444/29,162 ■■■■■■■■■■■ 32% - dn04
Casos processados: 9,565/29,162 ■■■■■■■■■■■ 33% - da04
Casos processados: 9,731/29,162 ■■■■■■■■■■■ 33% - dl01
Casos processados: 11,338/29,162 ■■■■■■■■■■■■■ 39% - pl01
Casos processados: 11,791/29,162 ■■■■■■■■■■■■■ 40% - dl02
Casos processados: 14,479/29,162 ■■■■■■■■■■■■■■■■ 50% - pl02
Casos processados: 15,421/29,162 ■■■■■■■■■■■■■■■■■ 53% - dl03
Casos processados: 15,549/29,162 ■■■■■■■■■■■■■■■■■ 53% - pl03
Casos processados: 15,587/29,162 ■■■■■■■■■■■■■■■■■ 53% - dl04
Casos processados: 15,797/29,162 ■■■■■■■■■■■■■■■■■ 54% - dc01
Casos processados: 19,510/29,162 ■■■■■■■■■■■■■■■■■■■■■ 67% - dc02
Casos processados: 28,730/29,162 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 99% - db01
Casos processados: 29,032/29,162 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 100% - dm01
Casos processados: 29,162/29,162 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 100% - Fim!
ℹ Preparando resultados
Foram encontrados e resolvidos 2071 casos de empate.
Warning message:
In enderecobr::padronizar_enderecos(enderecos = enderecos, campos_do_endereco = enderecobr::correspondencia_campos(logradouro = campos_endereco[["logradouro"]], :
Alguns números não puderam ser convertidos para integer, introduzindo NAs no
resultado.
ℹ Padronizando endereços de entrada
ℹ Utilizando dados do CNEFE armazenados localmente
ℹ Geolocalizando endereços
Casos processados: 0/30,386 ■ 0% - dn01
Casos processados: 3,797/30,386 ■■■■■ 12% - da01
Casos processados: 6,592/30,386 ■■■■■■■■ 22% - pn01
Casos processados: 7,017/30,386 ■■■■■■■■ 23% - pa01
Casos processados: 7,546/30,386 ■■■■■■■■ 25% - dn02
Casos processados: 8,706/30,386 ■■■■■■■■■■ 29% - da02
Casos processados: 9,598/30,386 ■■■■■■■■■■ 32% - pn02
Casos processados: 9,719/30,386 ■■■■■■■■■■■ 32% - pa02
Casos processados: 9,875/30,386 ■■■■■■■■■■■ 32% - dn03
Casos processados: 10,140/30,386 ■■■■■■■■■■■ 33% - da03
Casos processados: 10,351/30,386 ■■■■■■■■■■■ 34% - pn03
Casos processados: 10,401/30,386 ■■■■■■■■■■■ 34% - pa03
Casos processados: 10,458/30,386 ■■■■■■■■■■■ 34% - dn04
Casos processados: 10,586/30,386 ■■■■■■■■■■■ 35% - da04
Casos processados: 10,747/30,386 ■■■■■■■■■■■■ 35% - dl01
Casos processados: 12,437/30,386 ■■■■■■■■■■■■■ 41% - pl01
Casos processados: 12,898/30,386 ■■■■■■■■■■■■■■ 42% - dl02
Casos processados: 15,575/30,386 ■■■■■■■■■■■■■■■■ 51% - pl02
Casos processados: 16,525/30,386 ■■■■■■■■■■■■■■■■■ 54% - dl03
Casos processados: 16,649/30,386 ■■■■■■■■■■■■■■■■■ 55% - pl03
Casos processados: 16,684/30,386 ■■■■■■■■■■■■■■■■■ 55% - dl04
Casos processados: 16,908/30,386 ■■■■■■■■■■■■■■■■■■ 56% - dc01
Casos processados: 20,709/30,386 ■■■■■■■■■■■■■■■■■■■■■ 68% - dc02
Casos processados: 29,918/30,386 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 98% - db01
Casos processados: 30,259/30,386 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 100% - dm01
Casos processados: 30,386/30,386 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 100% - Fim!
ℹ Preparando resultados
Foram encontrados e resolvidos 2119 casos de empate.
Warning message:
In enderecobr::padronizar_enderecos(enderecos = enderecos, campos_do_endereco = enderecobr::correspondencia_campos(logradouro = campos_endereco[["logradouro"]], :
Alguns números não puderam ser convertidos para integer, introduzindo NAs no
resultado.
ℹ Padronizando endereços de entrada
ℹ Utilizando dados do CNEFE armazenados localmente
ℹ Geolocalizando endereços
Casos processados: 0/32,105 ■ 0% - dn01
Casos processados: 3,777/32,105 ■■■■■ 12% - da01
Casos processados: 6,648/32,105 ■■■■■■■ 21% - pn01
Casos processados: 7,127/32,105 ■■■■■■■■ 22% - pa01
Casos processados: 7,674/32,105 ■■■■■■■■ 24% - dn02
Casos processados: 8,780/32,105 ■■■■■■■■■ 27% - da02
Casos processados: 9,711/32,105 ■■■■■■■■■■ 30% - pn02
Casos processados: 9,835/32,105 ■■■■■■■■■■ 31% - pa02
Casos processados: 9,980/32,105 ■■■■■■■■■■ 31% - dn03
Casos processados: 10,253/32,105 ■■■■■■■■■■■ 32% - da03
Casos processados: 10,494/32,105 ■■■■■■■■■■■ 33% - pn03
Casos processados: 10,540/32,105 ■■■■■■■■■■■ 33% - pa03
Casos processados: 10,600/32,105 ■■■■■■■■■■■ 33% - dn04
Casos processados: 10,726/32,105 ■■■■■■■■■■■ 33% - da04
Casos processados: 10,907/32,105 ■■■■■■■■■■■ 34% - dl01
Casos processados: 12,685/32,105 ■■■■■■■■■■■■■ 40% - pl01
Casos processados: 13,177/32,105 ■■■■■■■■■■■■■ 41% - dl02
Casos processados: 15,853/32,105 ■■■■■■■■■■■■■■■■ 49% - pl02
Casos processados: 16,806/32,105 ■■■■■■■■■■■■■■■■■ 52% - dl03
Casos processados: 16,961/32,105 ■■■■■■■■■■■■■■■■■ 53% - pl03
Casos processados: 17,004/32,105 ■■■■■■■■■■■■■■■■■ 53% - dl04
Casos processados: 17,252/32,105 ■■■■■■■■■■■■■■■■■ 54% - dc01
Casos processados: 21,884/32,105 ■■■■■■■■■■■■■■■■■■■■■ 68% - dc02
Casos processados: 31,464/32,105 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 98% - db01
Casos processados: 31,878/32,105 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 99% - dm01
Casos processados: 32,085/32,105 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 100% - Fim!
ℹ Preparando resultados
Foram encontrados e resolvidos 2128 casos de empate.
Casos processados: 32,105/32,105 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 100% - Fim!
Warning messages:
1: In enderecobr::padronizar_enderecos(enderecos = enderecos, campos_do_endereco = enderecobr::correspondencia_campos(logradouro = campos_endereco[["logradouro"]], :
Alguns números não puderam ser convertidos para integer, introduzindo NAs no
resultado.
2: In enderecobr::padronizar_enderecos(enderecos = enderecos, campos_do_endereco = enderecobr::correspondencia_campos(logradouro = campos_endereco[["logradouro"]], :
Alguns números não puderam ser convertidos para integer, introduzindo NAs no
resultado.
ℹ Padronizando endereços de entrada
ℹ Utilizando dados do CNEFE armazenados localmente
ℹ Geolocalizando endereços
Casos processados: 0/34,289 ■ 0% - dn01
Casos processados: 914/34,289 ■■ 3% - da01
Casos processados: 1,729/34,289 ■■■ 5% - pn01
Casos processados: 2,092/34,289 ■■■ 6% - pa01
Casos processados: 2,438/34,289 ■■■ 7% - dn02
Casos processados: 3,621/34,289 ■■■■ 11% - da02
Casos processados: 4,818/34,289 ■■■■■ 14% - pn02
Casos processados: 5,008/34,289 ■■■■■ 15% - pa02
Casos processados: 5,248/34,289 ■■■■■■ 15% - dn03
Casos processados: 5,346/34,289 ■■■■■■ 16% - da03
Casos processados: 5,450/34,289 ■■■■■■ 16% - pn03
Casos processados: 5,482/34,289 ■■■■■■ 16% - pa03
Casos processados: 5,532/34,289 ■■■■■■ 16% - dn04
Casos processados: 5,612/34,289 ■■■■■■ 16% - da04
Casos processados: 5,739/34,289 ■■■■■■ 17% - dl01
Casos processados: 6,310/34,289 ■■■■■■■ 18% - pl01
Casos processados: 6,564/34,289 ■■■■■■■ 19% - dl02
Casos processados: 9,594/34,289 ■■■■■■■■■ 28% - pl02
Casos processados: 10,613/34,289 ■■■■■■■■■■ 31% - dl03
Casos processados: 10,683/34,289 ■■■■■■■■■■ 31% - pl03
Casos processados: 10,736/34,289 ■■■■■■■■■■ 31% - dl04
Casos processados: 10,967/34,289 ■■■■■■■■■■■ 32% - dc01
Casos processados: 19,976/34,289 ■■■■■■■■■■■■■■■■■■ 58% - dc02
Casos processados: 32,473/34,289 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 95% - db01
Casos processados: 33,601/34,289 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 98% - dm01
Casos processados: 34,283/34,289 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 100% - Fim!
ℹ Preparando resultados
Foram encontrados e resolvidos 2450 casos de empate.
Casos processados: 34,289/34,289 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 100% - Fim!
Warning messages:
1: In enderecobr::padronizar_enderecos(enderecos = enderecos, campos_do_endereco = enderecobr::correspondencia_campos(logradouro = campos_endereco[["logradouro"]], :
Alguns números não puderam ser convertidos para integer, introduzindo NAs no
resultado.
2: In enderecobr::padronizar_enderecos(enderecos = enderecos, campos_do_endereco = enderecobr::correspondencia_campos(logradouro = campos_endereco[["logradouro"]], :
Alguns números não puderam ser convertidos para integer, introduzindo NAs no
resultado.
# Veja os resultados
summary(resultados_geocod) Length Class Mode
esc_geocod_2022 9 data.frame list
esc_geocod_2023 9 data.frame list
esc_geocod_2024 9 data.frame list
esc_geocod_2025 9 data.frame list
str(resultados_geocod)List of 4
$ esc_geocod_2022:'data.frame': 29162 obs. of 9 variables:
..$ sg_uf : chr [1:29162] "RO" "RO" "RO" "RO" ...
..$ nm_mun : chr [1:29162] "Porto Velho" "Porto Velho" "Porto Velho" "Porto Velho" ...
..$ cod_escola : chr [1:29162] "11000325" "11000546" "11000562" "11000635" ...
..$ lat_2022 : num [1:29162] -8.79 -9.78 -9.69 -8.78 -9.32 ...
..$ lon_2022 : num [1:29162] -63.9 -66.6 -65.5 -63.8 -64.3 ...
..$ precisao_2022 : chr [1:29162] "numero_aproximado" "cep" "cep" "logradouro" ...
..$ desvio_metros_2022 : int [1:29162] 6 14393 49470 210 83271 17466 120198 6 120198 158686 ...
..$ tipo_resultado_2022 : chr [1:29162] "da03" "dc02" "dc02" "dl03" ...
..$ ano_censos_pres_2022: chr [1:29162] "2022, 2023" "2022" "2022, 2023, 2024, 2025" "2022, 2023, 2024, 2025" ...
$ esc_geocod_2023:'data.frame': 30386 obs. of 9 variables:
..$ sg_uf : chr [1:30386] "RO" "RO" "RO" "RO" ...
..$ nm_mun : chr [1:30386] "Porto Velho" "Porto Velho" "Porto Velho" "Porto Velho" ...
..$ cod_escola : chr [1:30386] "11000325" "11000562" "11000635" "11001011" ...
..$ lat_2023 : num [1:30386] -8.79 -9.73 -9.11 -9.32 -8.42 ...
..$ lon_2023 : num [1:30386] -63.9 -65.5 -63.9 -64.3 -63.5 ...
..$ precisao_2023 : chr [1:30386] "numero_aproximado" "cep" "cep" "cep" ...
..$ desvio_metros_2023 : int [1:30386] 6 29046 120198 83271 17466 120198 6 120198 158686 689 ...
..$ tipo_resultado_2023 : chr [1:30386] "da03" "dc01" "dc02" "dc02" ...
..$ ano_censos_pres_2023: chr [1:30386] "2022, 2023" "2022, 2023, 2024, 2025" "2022, 2023, 2024, 2025" "2022, 2023, 2024, 2025" ...
$ esc_geocod_2024:'data.frame': 32105 obs. of 9 variables:
..$ sg_uf : chr [1:32105] "RO" "RO" "RO" "RO" ...
..$ nm_mun : chr [1:32105] "Porto Velho" "Porto Velho" "Porto Velho" "Porto Velho" ...
..$ cod_escola : chr [1:32105] "11000562" "11000635" "11001011" "11001070" ...
..$ lat_2024 : num [1:32105] -9.73 -9.11 -9.11 -8.42 -9.11 ...
..$ lon_2024 : num [1:32105] -65.5 -63.9 -63.9 -63.5 -63.9 ...
..$ precisao_2024 : chr [1:32105] "cep" "cep" "cep" "cep" ...
..$ desvio_metros_2024 : int [1:32105] 29046 120198 120198 17466 120198 6 120198 158686 689 35351 ...
..$ tipo_resultado_2024 : chr [1:32105] "dc01" "dc02" "dc02" "dc02" ...
..$ ano_censos_pres_2024: chr [1:32105] "2022, 2023, 2024, 2025" "2022, 2023, 2024, 2025" "2022, 2023, 2024, 2025" "2022, 2023, 2024, 2025" ...
$ esc_geocod_2025:'data.frame': 34289 obs. of 9 variables:
..$ sg_uf : chr [1:34289] "RO" "RO" "RO" "RO" ...
..$ nm_mun : chr [1:34289] "Porto Velho" "Porto Velho" "Porto Velho" "Porto Velho" ...
..$ cod_escola : chr [1:34289] "11000562" "11000635" "11001011" "11001070" ...
..$ lat_2025 : num [1:34289] -9.69 -9.11 -9.11 -8.42 -9.11 ...
..$ lon_2025 : num [1:34289] -65.5 -63.9 -63.9 -63.5 -63.9 ...
..$ precisao_2025 : chr [1:34289] "cep" "cep" "cep" "cep" ...
..$ desvio_metros_2025 : int [1:34289] 49470 120198 120198 17466 120198 120198 120198 158686 1002 35351 ...
..$ tipo_resultado_2025 : chr [1:34289] "dc02" "dc02" "dc02" "dc02" ...
..$ ano_censos_pres_2025: chr [1:34289] "2022, 2023, 2024, 2025" "2022, 2023, 2024, 2025" "2022, 2023, 2024, 2025" "2022, 2023, 2024, 2025" ...
Antes dos comentários sobre a geocodificação, mencione-se que as mensagens de atenção (warning messages) geradas estão apenas alertando para a impossibilidade de converter alguns números para o formato integer, padrão de representação utilizado pelo algoritmo. Sempre que isso ocorre, o algoritmo substitui esse valor por um valor faltante (NA).
Isso posto, observa-se que a lista criada (resultados_geocod) apresenta os dados geocodificados para cada um dos 4 anos analisados. Essa forma de visualização, porém, é de difícil compreensão.
Diante deste fato e do resultado que se quer obter, a seguir a lista será transformada em uma única estrutura tabular (escolas_geocod_tds_anos). A partir dos sufixos das variáveis, que indicam o ano de origem do dado para cada uma das escolas, comparações serão mais facilmente realizáveis.
# Transforme a lista com os resultados da geocoficação em uma única base tabular
escolas_geocod_tds_anos <- resultados_geocod |>
reduce(full_join, by = c("sg_uf", "nm_mun", "cod_escola"))
# Veja os dados para as primeiras escolas da base única
escolas_geocod_tds_anos |>
head() |>
knitr::kable()| sg_uf | nm_mun | cod_escola | lat_2022 | lon_2022 | precisao_2022 | desvio_metros_2022 | tipo_resultado_2022 | ano_censos_pres_2022 | lat_2023 | lon_2023 | precisao_2023 | desvio_metros_2023 | tipo_resultado_2023 | ano_censos_pres_2023 | lat_2024 | lon_2024 | precisao_2024 | desvio_metros_2024 | tipo_resultado_2024 | ano_censos_pres_2024 | lat_2025 | lon_2025 | precisao_2025 | desvio_metros_2025 | tipo_resultado_2025 | ano_censos_pres_2025 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| RO | Porto Velho | 11000325 | -8.794654 | -63.88509 | numero_aproximado | 6 | da03 | 2022, 2023 | -8.794654 | -63.88509 | numero_aproximado | 6 | da03 | 2022, 2023 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| RO | Porto Velho | 11000546 | -9.775360 | -66.59998 | cep | 14393 | dc02 | 2022 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| RO | Porto Velho | 11000562 | -9.685638 | -65.46000 | cep | 49470 | dc02 | 2022, 2023, 2024, 2025 | -9.731319 | -65.53329 | cep | 29046 | dc01 | 2022, 2023, 2024, 2025 | -9.731319 | -65.53329 | cep | 29046 | dc01 | 2022, 2023, 2024, 2025 | -9.685638 | -65.46000 | cep | 49470 | dc02 | 2022, 2023, 2024, 2025 |
| RO | Porto Velho | 11000635 | -8.776310 | -63.79908 | logradouro | 210 | dl03 | 2022, 2023, 2024, 2025 | -9.111448 | -63.91765 | cep | 120198 | dc02 | 2022, 2023, 2024, 2025 | -9.111448 | -63.91765 | cep | 120198 | dc02 | 2022, 2023, 2024, 2025 | -9.111448 | -63.91765 | cep | 120198 | dc02 | 2022, 2023, 2024, 2025 |
| RO | Porto Velho | 11001011 | -9.318474 | -64.28872 | cep | 83271 | dc02 | 2022, 2023, 2024, 2025 | -9.318474 | -64.28872 | cep | 83271 | dc02 | 2022, 2023, 2024, 2025 | -9.111448 | -63.91765 | cep | 120198 | dc02 | 2022, 2023, 2024, 2025 | -9.111448 | -63.91765 | cep | 120198 | dc02 | 2022, 2023, 2024, 2025 |
| RO | Porto Velho | 11001070 | -8.418862 | -63.49341 | cep | 17466 | dc02 | 2022, 2023, 2024, 2025 | -8.418862 | -63.49341 | cep | 17466 | dc02 | 2022, 2023, 2024, 2025 | -8.418862 | -63.49341 | cep | 17466 | dc02 | 2022, 2023, 2024, 2025 | -8.418862 | -63.49341 | cep | 17466 | dc02 | 2022, 2023, 2024, 2025 |
A partir da geocodificação e da criação de uma base única para armazenar esses dados, é possível verificar que o procedimento gerou dados para 39254 escolas. Esse número, contudo, é ligeiramente maior do que a base de entrada (escolas_sem_coord_geo), que possui 39171 escolas. Isso ocorre, pois no processo de geocodificação ocorreu a duplicação de algumas escolas, expostas a seguir.
# Crie um vetor para selecionar os casos duplicados
sel_esc_geocod_dupli <- duplicated(escolas_geocod_tds_anos$cod_escola)
# Quantique os casos duplicados
sum(sel_esc_geocod_dupli)[1] 83
# Selecione e apresente os 10 casos aleatórios de escolas duplicadas
escolas_geocod_tds_anos |>
filter(sel_esc_geocod_dupli) |>
slice_sample(n = 10) |>
kable()| sg_uf | nm_mun | cod_escola | lat_2022 | lon_2022 | precisao_2022 | desvio_metros_2022 | tipo_resultado_2022 | ano_censos_pres_2022 | lat_2023 | lon_2023 | precisao_2023 | desvio_metros_2023 | tipo_resultado_2023 | ano_censos_pres_2023 | lat_2024 | lon_2024 | precisao_2024 | desvio_metros_2024 | tipo_resultado_2024 | ano_censos_pres_2024 | lat_2025 | lon_2025 | precisao_2025 | desvio_metros_2025 | tipo_resultado_2025 | ano_censos_pres_2025 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| MT | Santo Antônio de Leverger | 51042045 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | -15.942145 | -55.85528 | cep | 121370 | dc02 | 2022, 2023, 2024 | NA | NA | NA | NA | NA | NA |
| MA | Fortuna | 21132046 | NA | NA | NA | NA | NA | NA | -5.706096 | -44.10157 | cep | 34040 | dc02 | 2022, 2023, 2024, 2025 | -5.706096 | -44.10157 | cep | 34040 | dc02 | 2022, 2023, 2024, 2025 | -5.706096 | -44.10157 | cep | 34040 | dc02 | 2022, 2023, 2024, 2025 |
| MT | Santo Antônio de Leverger | 51042053 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | -15.948544 | -55.56117 | cep | 1127 | dc01 | 2022, 2023, 2024 | NA | NA | NA | NA | NA | NA |
| AM | Anori | 13015656 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | -3.795525 | -61.67254 | cep | 83658 | dc02 | 2022, 2023, 2024, 2025 | NA | NA | NA | NA | NA | NA |
| MT | Santo Antônio de Leverger | 51041626 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | -16.592987 | -55.21377 | logradouro | 6 | dl02 | 2022, 2023, 2024, 2025 | -16.592987 | -55.21377 | logradouro | 6 | dl02 | 2022, 2023, 2024, 2025 |
| MT | Tangará da Serra | 51090457 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | -14.622953 | -57.49594 | municipio | 36911 | dm01 | 2022, 2023, 2024, 2025 | -14.622953 | -57.49594 | municipio | 36911 | dm01 | 2022, 2023, 2024, 2025 |
| AC | Rio Branco | 12015172 | NA | NA | NA | NA | NA | NA | -10.039042 | -67.78903 | cep | 2416 | dc02 | 2022, 2023, 2024, 2025 | -10.039042 | -67.78903 | cep | 2416 | dc02 | 2022, 2023, 2024, 2025 | -10.039042 | -67.78903 | cep | 2416 | dc02 | 2022, 2023, 2024, 2025 |
| MT | Santo Antônio de Leverger | 51041774 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | -15.942145 | -55.85528 | cep | 121370 | dc02 | 2022, 2023, 2024 | NA | NA | NA | NA | NA | NA |
| MA | Graça Aranha | 21203849 | NA | NA | NA | NA | NA | NA | -5.407171 | -44.33240 | cep | 889 | dc01 | 2022, 2023, 2024, 2025 | -5.407171 | -44.33240 | cep | 889 | dc01 | 2022, 2023, 2024, 2025 | -5.407163 | -44.33809 | cep | 9303 | dc02 | 2022, 2023, 2024, 2025 |
| MT | Santo Antônio de Leverger | 51056550 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | -15.942145 | -55.85528 | cep | 121370 | dc02 | 2022, 2023, 2024, 2025 | -15.942145 | -55.85528 | cep | 121370 | dc02 | 2022, 2023, 2024, 2025 |
Uma vez que não deve haver duplicação na base das escolas geocodificadas, o próximo trecho eliminará esses casos. Em linhas gerais, a estratégia adotada consiste em:
- Agrupar as escolas a partir dos seus códigos de identificação - dessa forma, a duplicação será reconhecida;
- Identificar, para cada grupo de escolas, o menor desvio produzido no momento da geocodificação (o valor será salvo em uma variável auxiliar);
- Preencher as variáveis com valores faltantes a partir da comparação dos casos, e,
- Selecionar as escolas a partir dos menores valores de desvios existentes.
escolas_geocod_tds_anos <- escolas_geocod_tds_anos |>
# Agrupe os casos por código de escola
group_by(cod_escola) %>%
# Identifique, em cada grupo, o menor desvio gerado pela geocodificação
mutate(menor_desvio_da_linha = pmin(desvio_metros_2022,desvio_metros_2023, desvio_metros_2024, desvio_metros_2025, na.rm = TRUE)) %>%
# Compare, identifique os evetuais valores ausentes (NA) das variáveis da base e replique os valores para cima e para baixo dentro do mesmo código de escola
fill(everything(), .direction = "downup") %>%
# Rearrange a base considerando o menor valor do desvio por código de escola
arrange(menor_desvio_da_linha) %>%
# Remova a coluna auxiliar utilizada para identificar o menor desvio da geocodif.
select(-menor_desvio_da_linha) %>%
# Selecione apenas a escola com o menor desvio global do mesmo código
distinct(cod_escola, .keep_all = TRUE) %>%
# Desfaça os grupos criados
ungroup()Eliminada a duplicação de escolas da base geocodificada, a seguir apresentam-se: i) a estrutura da atual base e ii) a presença das escolas geocodificadas ao longo do tempo.
# Veja a estrutura da base apenas com as escolas geocodificadas sem duplicação
glimpse(escolas_geocod_tds_anos)Rows: 39,171
Columns: 27
$ sg_uf <chr> "RO", "RO", "RO", "RO", "RO", "RO", "RO", "RO", "…
$ nm_mun <chr> "Porto Velho", "Porto Velho", "Guajará-Mirim", "M…
$ cod_escola <chr> "11000325", "11001267", "11006706", "11008598", "…
$ lat_2022 <dbl> -8.794654, -8.850409, -10.768905, -9.429623, -8.7…
$ lon_2022 <dbl> -63.88509, -63.94084, -65.33086, -62.00170, -63.8…
$ precisao_2022 <chr> "numero_aproximado", "numero_aproximado", "numero…
$ desvio_metros_2022 <int> 6, 6, 6, 6, 1222, 6, 6, 6, 971, 6, 6, 6, 6, 73, 6…
$ tipo_resultado_2022 <chr> "da03", "pa01", "da01", "pa01", "dc02", "dn01", "…
$ ano_censos_pres_2022 <chr> "2022, 2023", "2022, 2023, 2024, 2025", "2022", "…
$ lat_2023 <dbl> -8.794654, -8.850409, NA, -9.429623, -8.723806, -…
$ lon_2023 <dbl> -63.88509, -63.94084, NA, -62.00170, -63.84758, -…
$ precisao_2023 <chr> "numero_aproximado", "numero_aproximado", NA, "nu…
$ desvio_metros_2023 <int> 6, 6, NA, 6, 1222, 6, 6, 6, 6, 6, 6, 6, 6, 73, 6,…
$ tipo_resultado_2023 <chr> "da03", "pa01", NA, "pa01", "dc02", "dn01", "dn01…
$ ano_censos_pres_2023 <chr> "2022, 2023", "2022, 2023, 2024, 2025", NA, "2022…
$ lat_2024 <dbl> NA, -8.850409, NA, -9.429623, -8.751167, -9.92009…
$ lon_2024 <dbl> NA, -63.94084, NA, -62.00170, -63.90322, -63.0171…
$ precisao_2024 <chr> NA, "numero_aproximado", NA, "numero_aproximado",…
$ desvio_metros_2024 <int> NA, 6, NA, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 73, 271,…
$ tipo_resultado_2024 <chr> NA, "pa01", NA, "pa01", "dn01", "dn01", "dn01", "…
$ ano_censos_pres_2024 <chr> NA, "2022, 2023, 2024, 2025", NA, "2022, 2023, 20…
$ lat_2025 <dbl> NA, -9.111448, NA, -9.423916, -8.751251, -9.91967…
$ lon_2025 <dbl> NA, -63.91765, NA, -62.07344, -63.90341, -63.0171…
$ precisao_2025 <chr> NA, "cep", NA, "cep", "cep", "cep", "numero", "ce…
$ desvio_metros_2025 <int> NA, 120198, NA, 50054, 36, 6, 6, 16596, 6, 134, 6…
$ tipo_resultado_2025 <chr> NA, "dc02", NA, "dc02", "dc01", "dc01", "dn01", "…
$ ano_censos_pres_2025 <chr> NA, "2022, 2023, 2024, 2025", NA, "2022, 2023, 20…
# Identifique a presença das escolas geocodificados ao longo dos anos
escolas_geocod_tds_anos |>
mutate(ano_censos_pres = case_when(
is.na(ano_censos_pres_2025) & is.na(ano_censos_pres_2024) ~ ano_censos_pres_2023,
is.na(ano_censos_pres_2025) & !is.na(ano_censos_pres_2024) ~ ano_censos_pres_2024,
.default = ano_censos_pres_2025
)) |>
count(ano_censos_pres, sort = T, name = "tot_esc") |>
mutate(prop = scales::percent(tot_esc/sum(tot_esc), accuracy = 0.1)) |>
janitor::adorn_totals() |>
knitr::kable(col.names = c("Presença nos censos (ano)", "Total de escolas", "Propoção (%)"), align = 'lcc')| Presença nos censos (ano) | Total de escolas | Propoção (%) |
|---|---|---|
| 2022, 2023, 2024, 2025 | 24520 | 62.6% |
| 2025 | 3657 | 9.3% |
| 2024, 2025 | 2938 | 7.5% |
| 2023, 2024, 2025 | 2627 | 6.7% |
| NA | 1556 | 4.0% |
| 2022, 2023 | 1279 | 3.3% |
| 2022, 2023, 2024 | 1215 | 3.1% |
| 2024 | 264 | 0.7% |
| 2023, 2024 | 237 | 0.6% |
| 2023 | 229 | 0.6% |
| 2022, 2023, 2025 | 222 | 0.6% |
| 2022, 2024, 2025 | 202 | 0.5% |
| 2022, 2024 | 102 | 0.3% |
| 2022, 2025 | 66 | 0.2% |
| 2023, 2025 | 57 | 0.1% |
| Total | 39171 | - |
Como demonstra a estrutura da base, com exceção das variáveis relacionadas à unidade federativa (sg_uf), ao nome do município (nm_mun) e ao código de identificação único da escola (cod_escola), para todas as outras existem uma versão relacionada a cada ano do censo analisado (lat_2023, lon_2023, precisao_2023, etc.). No caso específico das coordenadas geográficas, deve-se ter apenas um par de referência - em tese, o de maior acurácia.
Nesse sentido, baseando-se no menor valor de desvio da localização da escola e na busca pelo dado mais recente possível, as próximas linhas do código selecionarão o caso (escola) com as melhores coordenadas. Apenas para exemplificar o exposto, se o desvio constatado para uma escola for de 6 metros, em 2023, e de 36 metros, em 2024, o par de coordenadas selecionado seria o do primeiro ano (2023). Por sua vez, se o desvio encontrado para ambos os anos for o mesmo, as coordenadas recuperadas estariam atreladas ao ano de 2024 (mais recente e adequado possível). Por fim, para fins de registro e análise, o histórico dos dados constará na base gerada.
# Transforme as colunas anuais em formato longo
escolas_geocod_long <- escolas_geocod_tds_anos |>
pivot_longer(
cols = matches("^(precisao_|desvio_metros_|lat_|lon_)\\d{4}$"),
# cols = matches("^(desvio_metros_)\\d{4}$"), # Esse linha não empilha as coord. geo.
names_to = c(".value", "ano"),
names_pattern = "^(.*)_(\\d{4})$") |>
relocate(ends_with(as.character(censo_esc_anos)), .after = "desvio_metros")
# Selecione a escola com o menor desvio
escolas_geocod_melhor_ano <- escolas_geocod_long |>
group_by(cod_escola, sg_uf, nm_mun) |>
arrange(cod_escola, sg_uf, nm_mun, desvio_metros, desc(ano), .by_group = T) |>
slice_head(n = 1) |>
ungroup() |>
rename(melhor_ano = ano,
melhor_desvio = desvio_metros,
melhor_latitude = lat,
melhor_longitude = lon,
melhor_precisao = precisao)
# Adicione todas as variávies para análise histórica
escolas_geocod_compatib <- escolas_geocod_tds_anos |>
left_join(escolas_geocod_melhor_ano) |>
relocate(.after = cod_escola, starts_with("melhor"))Joining with `by = join_by(sg_uf, nm_mun, cod_escola, tipo_resultado_2022,
ano_censos_pres_2022, tipo_resultado_2023, ano_censos_pres_2023,
tipo_resultado_2024, ano_censos_pres_2024, tipo_resultado_2025,
ano_censos_pres_2025)`
A seguir, apresentam-se dois gráficos referentes à qualidade dos dados gerados, o primeiro para o Brasil, como um todo, e o segundo para as unidades de federativas (estados).
Code
# Crie um gráfico sobre a precisão das estimativas geradas durante a geocodificação (Brasil)
escolas_geocod_compatib |>
summarize(n = n(), .by = melhor_precisao) |>
mutate(
prop = scales::percent((n / sum(n)), accuracy = 0.1),
lab_val_abs_rel = str_c(n, "\n(", prop,")"),
precisao = factor(
melhor_precisao,
levels = c("numero", "numero_aproximado", "logradouro", "cep", "localidade", "municipio"))) |>
ggplot(aes(x = precisao, y = n, label = lab_val_abs_rel)) + # , label = (prop)
geom_col(fill = "#4C6CB3") +
geom_text(
vjust = -0.25,
size = 4,
fontface = "bold") +
scale_y_discrete(expand = expansion(mult = c(0.05, 0.15))) +
scale_x_discrete(labels = c(
"numero" = "Número",
"numero_aproximado" = "Número aproximado",
"logradouro" = "Logradouro",
"cep" = "CEP",
"localidade" = "Localidade",
"municipio" = "Município")) +
labs(
title = "Distribuição das escolas geocodificadas segundo o nível de precisão (Brasil)",
x = NULL,
y = NULL) +
theme_classic() +
theme(
axis.text.x = element_text(size = 15, angle = 45, vjust = 0.5),
plot.title = element_text(size = 20),
plot.title.position = "plot"
)Code
# Crie um gráfico sobre a precisão das estimativas geradas durante a geocodificação (Estados - UF)
escolas_geocod_compatib |>
group_by(sg_uf, melhor_precisao, .drop = FALSE) |>
summarize(tot_escolas = n()) |> # , .by = melhor_precisao
mutate(
prop = scales::percent((tot_escolas / sum(tot_escolas)), accuracy = 0.1),
lab_val_abs_rel = str_c(tot_escolas, " (", prop,")"),
precisao = factor(
melhor_precisao,
levels = c("numero", "numero_aproximado", "logradouro", "cep", "localidade", "municipio"))
) |>
drop_na() |>
ggplot(aes(x = precisao, y = tot_escolas, label = lab_val_abs_rel)) + # , label = (prop)
geom_col(fill = "#4C6CB3") +
geom_text(
hjust = -0.15,
size = 2.5,
fontface = "bold") +
scale_y_discrete(expand = expansion(mult = c(0.05, 0.15))) +
scale_x_discrete(labels = c(
"numero" = "Número",
"numero_aproximado" = "Número aproximado",
"logradouro" = "Logradouro",
"cep" = "CEP",
"localidade" = "Localidade",
"municipio" = "Município")) +
labs(
title = "Distribuição das escolas geocodificadas segundo o nível de precisão (Estados - UF)",
x = NULL,
y = NULL) +
theme_classic() +
theme(
axis.text.x = element_text(size = 5),
plot.title = element_text(size = 20),
plot.title.position = "plot"
) +
facet_wrap(vars(sg_uf)) +
coord_flip()`summarise()` has regrouped the output.
ℹ Summaries were computed grouped by sg_uf and melhor_precisao.
ℹ Output is grouped by sg_uf.
ℹ Use `summarise(.groups = "drop_last")` to silence this message.
ℹ Use `summarise(.by = c(sg_uf, melhor_precisao))` for per-operation grouping
(`?dplyr::dplyr_by`) instead.
Crie uma base única com as coordenadas geográficas geradas
Para a criação de uma base onde todas as escolas terão um par de coordenadas geográficas associado, a seguir serão selecionadas apenas algumas das variáveis da base proveniente da geocodificação.
# Selecione o padrão de exclusão que será utilizado para excluri as colunas a seguir - neste caso, todas as variáveis que terminem com os seus respectivos anos
colunas_excluir <- "\\d{4}$"
# Exclua e adicione colunas de interesse e registre a fonte do dado
escolas_geocod_compatib <- escolas_geocod_compatib |>
select(-any_of(matches(colunas_excluir))) |>
mutate(fonte_coord_geo = "geocodebr") |>
left_join(base_unica_map_com_rep, join_by(sg_uf, nm_mun, cod_escola, melhor_ano == ano_cn_escolar)) O próximo passo consiste em integrar ambas as bases com coordenadas geográficas (escolas_com_coord_geo e escolas_geocod_compatib).
# Junte as bases com coordenadas geográficas (originais e geocodificadas)
escolas_geo_tot <- escolas_com_coord_geo |>
bind_rows(escolas_geocod_compatib)Com a base única gerada (“escolas_geo_tot”), algumas transformações iniciais serão realizadas. Atreladas à organização das variáveis já existentes, as primeiras dizem respeito à criação de um campo único para armazenar as coordenadas geográficas - neste momento, verifica-se a existência das coordenadas geográficas provenientes do Catálogo de Escolas (“lat_inep” e “long_inep”) e as geradas pela geocodificação (“melhor_latitude” e “melhor_longitude”) - tratamento similar é realizado para o ano. Por sua vez, o outro grupo de modificações diz respeito ao ajuste da classe de algumas variáveis e a renomeação de algumas variáveis. Por fim, define-se um novo ordenamento para as variáveis e os casos.
escolas_geo_tot <- escolas_geo_tot |>
mutate(
# Junte as informações das coordenadas geográficas nos mesmos campos
lat = if_else(!is.na(lat_inep), as.numeric(lat_inep), melhor_latitude),
lon = if_else(!is.na(long_inep), as.numeric(long_inep), melhor_longitude),
fonte_ano_cn_escolar = if_else(!is.na(melhor_ano), melhor_ano, ano_cn_escolar),
# Modifique a classe de algumas variáveis
across(c(fonte_ano_cn_escolar, tp_adm, sg_uf, cod_mun, nm_mun, fonte_coord_geo), as.factor)) |>
select(!c(lat_inep, long_inep, melhor_ano, melhor_latitude, melhor_longitude, ano_cn_escolar)) |>
# drop_na(c(lat, lon)) |>
rename(
precisao = melhor_precisao,
desvio = melhor_desvio
) |>
relocate(cod_escola, nm_escola, lat, lon, precisao, desvio, fonte_coord_geo, fonte_ano_cn_escolar, tp_adm, qt_mat_bas, sg_uf, nm_mun, cod_mun, cep, endereco, num_endereco, nm_bairro) |>
arrange(cod_escola)
escolas_geo_tot |>
glimpse()Rows: 189,545
Columns: 20
$ cod_escola <chr> "11000023", "11000040", "11000058", "11000082", "…
$ nm_escola <chr> "EEEE ABNAEL MACHADO DE LIMA - CENE", "EMEIEF PEQ…
$ lat <dbl> -8.758459, -8.793730, -8.760734, -8.765205, -8.76…
$ lon <dbl> -63.85401, -63.88392, -63.90199, -63.89618, -63.8…
$ precisao <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
$ desvio <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
$ fonte_coord_geo <fct> catalogo_inep, catalogo_inep, catalogo_inep, cata…
$ fonte_ano_cn_escolar <fct> 2024, 2024, 2024, 2024, 2024, 2022, 2024, 2024, 2…
$ tp_adm <fct> Pública - Estadual, Pública - Municipal, Privada,…
$ qt_mat_bas <chr> "71", "207", "1135", "58", "556", "175", "1046", …
$ sg_uf <fct> RO, RO, RO, RO, RO, RO, RO, RO, RO, RO, RO, RO, R…
$ nm_mun <fct> Porto Velho, Porto Velho, Porto Velho, Porto Velh…
$ cod_mun <fct> 1100205, 1100205, 1100205, 1100205, 1100205, 1100…
$ cep <chr> "76824556", "76808108", "76801123", "76804214", "…
$ endereco <chr> "AVENIDA AMAZONAS", "RUA CAETANO", "AVENIDA CARLO…
$ num_endereco <chr> "6492", "3256", "1135", "1483", "1056", "605", "4…
$ nm_bairro <chr> "TIRADENTES", "CALADINHO", "CENTRO", "SANTA BARBA…
$ no_censos_pres <int> 4, 4, 4, 3, 4, 1, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4…
$ ano_censos_pres <chr> "2022, 2023, 2024, 2025", "2022, 2023, 2024, 2025…
$ tipo_censos_pres <chr> "4_bases", "4_bases", "4_bases", "3_bases", "4_ba…
Realizadas esses primeiros ajustes, uma nova forma de registrar a presença das escolas ao longo do tempo é feita. Para isso, são criadas variáveis específicas para cada um dos anos dos censos analisados. Essas variáveis, por sua vez, indicarão a presença (“TRUE”) ou ausência (FALSE) da escola naquele ano.
escolas_geo_tot <- escolas_geo_tot |>
mutate(
pres_ano_22 = str_detect(ano_censos_pres, pattern = "2022"),
pres_ano_23 = str_detect(ano_censos_pres, pattern = "2023"),
pres_ano_24 = str_detect(ano_censos_pres, pattern = "2024"),
pres_ano_25 = str_detect(ano_censos_pres, pattern = "2025")
)Com a base organizada, é possível ver, por exemplo, o resultado final a partir da fonte original/produtora do dado espacial.
# Visualize a fonte dos dados geográficos na base única gerada
escolas_geo_tot |>
count(fonte_coord_geo, name = "tot_escolas") |>
mutate(prop = tot_escolas / sum(tot_escolas)) |>
arrange(desc("tot_escolas")) |>
mutate(prop = scales::percent(prop, accuracy = 0.1)) |>
knitr::kable(
digits = 1,
col.names = c("Fonte do dado geográfico", "No. de escolas", "Proporção (%)"),
caption = "Origem dos dados geográficos associados às escolas",
align = "lcc",
format.args = list(big.mark = ".", decimal.mark = ","))| Fonte do dado geográfico | No. de escolas | Proporção (%) |
|---|---|---|
| catalogo_inep | 150.374 | 79.3% |
| geocodebr | 39.171 | 20.7% |
Exportação dos dados
Salvando a base final sem o formato espacial
Após a união/junção e organização dos dados do Censo Escolar e do Catálogo de Escolas, uma primeira versão da base única já pode ser exportada em três formatos distintos: “csv”, “parquet” e “rds”.
Para isso, a seguir serão criadas duas estratégias para a exportação. Na primeira, a base será única, com colunas específicas para cada um dos anos indicando a presença (TRUE) ou a ausência (FALSE) da escola naquele ano. Ou seja, o filtro é realizado por colunas específicas para cada ano do censo.
# Exporte a base gerada no formato .csv
write_csv(escolas_geo_tot, file.path(pasta_dados_processados, str_c("escolas_geo_hist.csv")))
# Exporte a base gerada no formato .csv
write_parquet(escolas_geo_tot, file.path(pasta_dados_processados, str_c("escolas_geo_hist.parquet")))
# Exporte a base no formato .rds, nativo do R.
saveRDS(
escolas_geo_tot,
file.path(pasta_dados_processados, str_c("escolas_geo_hist.rds")))Note que, ainda que apresente as coordenadas geográficas para todas as escolas, a base recém-exportada não é um objeto espacial. Para isso, ela precisa ser transformada, como será feito a seguir.
# Transforme a base em um objeto espacial do tipo "sf"
escolas_tot_geo <- st_as_sf(
escolas_geo_tot |> drop_na(c(lon, lat)),
coords = c("lon", "lat"),
crs = 4674) # SIRGAS 2000
# Cheque se a classe do objeto foi realizada
class(escolas_tot_geo)
# Visualize rapidamente se a transformação ocorreu como esperado (os pontos deveriam formar uma ideia dos limites do Brasil)
plot(escolas_tot_geo["cod_escola"], main = "Distribuição das escolas brasileiras (2022 a 2025)")Criado o objeto espacial, os dados serão exportados como geopackage, um formato de dados geoespacial aberto.
# Exporte o objeto espacial criado como geopackage
st_write(
escolas_tot_geo,
dsn = file.path(
pasta_dados_processados,
str_c("escolas_geo_hist.gpkg")),
append = FALSE)