O Censo Escolar é a principal investigação estatística da educação básica no Brasil, realizada anualmente pelo Inep, uma autarquia vinculada ao Ministério da Educação (MEC).
Iremos trabalhar especificamente com o recorte das escolas em Pernambuco, a fim de realizar cruzamentos de dados e análises aprofundadas.
MicroDadosPEFinal.csv
presente na pasta do projeto.# Pacotes necessários
if (!requireNamespace("pacman", quietly = TRUE)) install.packages("pacman")
pacman::p_load(dplyr, stringr, ggplot2, plotly, tidyr, scales)
# Carregar dados (ajuste o encoding se necessário)
educacao_data <- read.csv2("MicroDadosPEFinal.csv", fileEncoding = "latin1", stringsAsFactors = FALSE,
na.strings = c("", "NA", "N/A", "na", "n/a", "NULL"))
# Rápido diagnóstico
str(educacao_data)
## 'data.frame': 9935 obs. of 426 variables:
## $ NU_ANO_CENSO : int 2024 2024 2024 2024 2024 2024 2024 2024 2024 2024 ...
## $ NO_REGIAO : chr "Nordeste" "Nordeste" "Nordeste" "Nordeste" ...
## $ CO_REGIAO : int 2 2 2 2 2 2 2 2 2 2 ...
## $ NO_UF : chr "Pernambuco" "Pernambuco" "Pernambuco" "Pernambuco" ...
## $ SG_UF : chr "PE" "PE" "PE" "PE" ...
## $ CO_UF : int 26 26 26 26 26 26 26 26 26 26 ...
## $ NO_MUNICIPIO : chr "Abreu e Lima" "Abreu e Lima" "Abreu e Lima" "Abreu e Lima" ...
## $ CO_MUNICIPIO : int 2600054 2600054 2600054 2600054 2600054 2600054 2600054 2600054 2600054 2600054 ...
## $ NO_REGIAO_GEOG_INTERM : chr "Recife" "Recife" "Recife" "Recife" ...
## $ CO_REGIAO_GEOG_INTERM : int 2601 2601 2601 2601 2601 2601 2601 2601 2601 2601 ...
## $ NO_REGIAO_GEOG_IMED : chr "Recife" "Recife" "Recife" "Recife" ...
## $ CO_REGIAO_GEOG_IMED : int 260001 260001 260001 260001 260001 260001 260001 260001 260001 260001 ...
## $ NO_MESORREGIAO : chr "Metropolitana de Recife" "Metropolitana de Recife" "Metropolitana de Recife" "Metropolitana de Recife" ...
## $ CO_MESORREGIAO : int 5 5 5 5 5 5 5 5 5 5 ...
## $ NO_MICRORREGIAO : chr "Recife" "Recife" "Recife" "Recife" ...
## $ CO_MICRORREGIAO : int 17 17 17 17 17 17 17 17 17 17 ...
## $ NO_DISTRITO : chr "Abreu e Lima" "Abreu e Lima" "Abreu e Lima" "Abreu e Lima" ...
## $ CO_DISTRITO : int 260005405 260005405 260005405 260005405 260005405 260005405 260005405 260005405 260005405 260005405 ...
## $ NO_ENTIDADE : chr "EM - CENTRO COMU E EDUC ISAAC MARTINS RODRIGUES" "EM - CENTRO COM EDUCACIONAL WILIBALDO DE FRANCA SEIXAS" "ESCOLA DE REFERENCIA EM ENSINO FUNDAMENTAL GENERAL ABREU E LIMA" "ESCOLA JESUS MENINO" ...
## $ CO_ENTIDADE : int 26106450 26106477 26106582 26106590 26106612 26106620 26106647 26106655 26106671 26106680 ...
## $ TP_DEPENDENCIA : int 3 3 2 4 2 4 3 3 3 3 ...
## $ TP_CATEGORIA_ESCOLA_PRIVADA : int NA NA NA NA NA NA NA NA NA NA ...
## $ TP_LOCALIZACAO : int 1 1 1 1 1 1 2 1 1 2 ...
## $ TP_LOCALIZACAO_DIFERENCIADA : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ DS_ENDERECO : chr "3ª TRAVESSA TRINTA E UM DE MARCO" "AVENIDA A" "AV DUQUE DE CAXIAS" "RUA CENTO E TRINTA E OITO" ...
## $ NU_ENDERECO : chr "S/N" "S/N" "660" "46" ...
## $ DS_COMPLEMENTO : chr NA NA NA NA ...
## $ NO_BAIRRO : chr "PLANALTO" "CAETES II" "CENTRO" "CAETES I" ...
## $ CO_CEP : int 53550798 53540010 53510050 53530240 53590000 53525030 53590000 53570564 53570720 53580365 ...
## $ NU_DDD : int 81 81 81 81 81 81 81 81 81 81 ...
## $ NU_TELEFONE : int NA 985350133 31812930 35422467 31814898 35421128 999247440 NA 87761925 984472988 ...
## $ TP_SITUACAO_FUNCIONAMENTO : int 1 1 1 2 1 2 1 1 1 1 ...
## $ CO_ORGAO_REGIONAL : int 3 3 3 3 3 3 3 3 3 3 ...
## $ DT_ANO_LETIVO_INICIO : chr "05FEB2024:00:00:00" "05FEB2024:00:00:00" "01FEB2024:00:00:00" NA ...
## $ DT_ANO_LETIVO_TERMINO : chr "20DEC2024:00:00:00" "20DEC2024:00:00:00" "20DEC2024:00:00:00" NA ...
## $ IN_VINCULO_SECRETARIA_EDUCACAO: int 1 1 1 NA 1 NA 1 1 1 1 ...
## $ IN_VINCULO_SEGURANCA_PUBLICA : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ IN_VINCULO_SECRETARIA_SAUDE : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ IN_VINCULO_OUTRO_ORGAO : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ IN_PODER_PUBLICO_PARCERIA : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ TP_PODER_PUBLICO_PARCERIA : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_TERMO_COLABORA : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_TERMO_FOMENTO : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_ACORDO_COOP : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_PRESTACAO_SERV : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_COOP_TEC_FIN : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_CONSORCIO_PUB : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_MU_TERMO_COLAB : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_MU_TERMO_FOMENTO: int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_MU_ACORDO_COOP : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_MU_PREST_SERV : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_MU_COOP_TEC_FIN : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_MU_CONSORCIO_PUB: int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_ES_TERMO_COLAB : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_ES_TERMO_FOMENTO: int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_ES_ACORDO_COOP : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_ES_PREST_SERV : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_ES_COOP_TEC_FIN : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_FORMA_CONT_ES_CONSORCIO_PUB: int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_MANT_ESCOLA_PRIVADA_EMP : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_MANT_ESCOLA_PRIVADA_ONG : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_MANT_ESCOLA_PRIVADA_OSCIP : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_MANT_ESCOLA_PRIV_ONG_OSCIP : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_MANT_ESCOLA_PRIVADA_SIND : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_MANT_ESCOLA_PRIVADA_SIST_S : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_MANT_ESCOLA_PRIVADA_S_FINS : int NA NA NA NA NA NA NA NA NA NA ...
## $ NU_CNPJ_ESCOLA_PRIVADA : num NA NA NA NA NA NA NA NA NA NA ...
## $ NU_CNPJ_MANTENEDORA : num NA NA NA NA NA NA NA NA NA NA ...
## $ TP_REGULAMENTACAO : int 2 1 1 NA 1 NA 1 1 1 1 ...
## $ TP_RESPONSAVEL_REGULAMENTACAO : int 2 2 2 NA 2 NA 2 3 2 2 ...
## $ CO_ESCOLA_SEDE_VINCULADA : int NA NA NA NA NA NA NA NA NA NA ...
## $ CO_IES_OFERTANTE : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_LOCAL_FUNC_PREDIO_ESCOLAR : int 1 1 1 NA 1 NA 1 1 1 1 ...
## $ TP_OCUPACAO_PREDIO_ESCOLAR : int 1 1 3 NA 1 NA 1 1 1 1 ...
## $ IN_LOCAL_FUNC_SOCIOEDUCATIVO : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ IN_LOCAL_FUNC_UNID_PRISIONAL : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ IN_LOCAL_FUNC_PRISIONAL_SOCIO : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ IN_LOCAL_FUNC_GALPAO : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ TP_OCUPACAO_GALPAO : int NA NA NA NA NA NA NA NA NA NA ...
## $ IN_LOCAL_FUNC_SALAS_OUTRA_ESC : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ IN_LOCAL_FUNC_OUTROS : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ IN_PREDIO_COMPARTILHADO : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ IN_AGUA_POTAVEL : int 1 1 1 NA 1 NA 1 1 1 1 ...
## $ IN_AGUA_REDE_PUBLICA : int 1 1 1 NA 1 NA 0 1 1 1 ...
## $ IN_AGUA_POCO_ARTESIANO : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ IN_AGUA_CACIMBA : int 0 0 0 NA 0 NA 1 0 0 1 ...
## $ IN_AGUA_FONTE_RIO : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ IN_AGUA_INEXISTENTE : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ IN_AGUA_CARRO_PIPA : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ IN_ENERGIA_REDE_PUBLICA : int 1 1 1 NA 1 NA 1 1 1 1 ...
## $ IN_ENERGIA_GERADOR_FOSSIL : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ IN_ENERGIA_RENOVAVEL : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ IN_ENERGIA_INEXISTENTE : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ IN_ESGOTO_REDE_PUBLICA : int 0 0 0 NA 1 NA 0 0 1 0 ...
## $ IN_ESGOTO_FOSSA_SEPTICA : int 0 0 0 NA 0 NA 1 1 0 0 ...
## $ IN_ESGOTO_FOSSA_COMUM : int 1 1 1 NA 0 NA 0 0 0 1 ...
## $ IN_ESGOTO_FOSSA : int 1 1 1 NA 0 NA 1 1 0 1 ...
## $ IN_ESGOTO_INEXISTENTE : int 0 0 0 NA 0 NA 0 0 0 0 ...
## $ IN_LIXO_SERVICO_COLETA : int 1 1 1 NA 1 NA 1 1 1 1 ...
## [list output truncated]
head(educacao_data)
Transformações aplicadas para normalizar textos, indicadores e tratar valores missing.
library(stringr)
# Função para limpar textos: trim, collapse spaces, normalizar acentos e Title Case
clean_text <- function(x) {
x <- as.character(x)
x[trimws(x) == ""] <- NA
x[x %in% c("NA", "N/A", "na", "n/a", "NULL")] <- NA
x <- ifelse(is.na(x), NA, trimws(x))
x <- ifelse(is.na(x), NA, str_squish(x))
idx <- which(!is.na(x))
if (length(idx) > 0) {
res_utf8 <- iconv(x[idx], from = "UTF-8", to = "ASCII//TRANSLIT")
na_idx <- which(is.na(res_utf8) & !is.na(x[idx]))
if (length(na_idx) > 0) {
res_lat <- iconv(x[idx][na_idx], from = "latin1", to = "ASCII//TRANSLIT")
res_utf8[na_idx] <- res_lat
}
x[idx] <- res_utf8
}
x <- ifelse(is.na(x), NA, tolower(x))
x <- ifelse(is.na(x), NA, str_to_title(x))
x
}
# Função para normalizar colunas indicador (IN_)
clean_indicator <- function(x) {
if (is.numeric(x)) {
x <- as.integer(x)
return(x)
}
x <- as.character(x)
x[trimws(tolower(x)) == ""] <- NA
x[ x %in% c("NA", "N/A", "na", "n/a", "NULL") ] <- NA
x2 <- tolower(trimws(x))
x_out <- ifelse(is.na(x2), NA,
ifelse(x2 %in% c("1","sim","s","yes","y","true","t"), 1,
ifelse(x2 %in% c("0","nao","não","n","no","false","f"), 0, NA)))
as.integer(x_out)
}
# Aplicar limpeza às colunas de texto alvo
text_cols <- c("NO_MESORREGIAO", "NO_MUNICIPIO")
text_cols_present <- intersect(text_cols, names(educacao_data))
if (length(text_cols_present) > 0) {
educacao_data <- educacao_data %>%
mutate(across(all_of(text_cols_present), clean_text))
}
# Limpar demais colunas caractere
char_cols <- names(educacao_data)[sapply(educacao_data, is.character)]
other_char_cols <- setdiff(char_cols, text_cols_present)
if (length(other_char_cols) > 0) {
educacao_data <- educacao_data %>%
mutate(across(all_of(other_char_cols), ~ {x <- as.character(.x); x[trimws(x) == ""] <- NA; str_squish(trimws(x))}))
}
# Normalizar colunas de indicador que começam com 'IN_'
indicator_cols <- names(educacao_data)[grepl("^IN_", names(educacao_data))]
if (length(indicator_cols) > 0) {
educacao_data <- educacao_data %>%
mutate(across(all_of(indicator_cols), clean_indicator))
}
# Resumo rápido após limpeza
cat("Limpeza concluída. Resumo de NA por coluna:\n")
## Limpeza concluída. Resumo de NA por coluna:
print(sort(sapply(educacao_data, function(x) sum(is.na(x))), decreasing = TRUE)[1:20])
## CO_LINGUA_INDIGENA_3 CO_ESCOLA_SEDE_VINCULADA
## 9935 9932
## CO_LINGUA_INDIGENA_2 IN_FORMA_CONT_ES_TERMO_COLAB
## 9930 9925
## IN_FORMA_CONT_ES_TERMO_FOMENTO IN_FORMA_CONT_ES_ACORDO_COOP
## 9925 9925
## IN_FORMA_CONT_ES_PREST_SERV IN_FORMA_CONT_ES_COOP_TEC_FIN
## 9925 9925
## IN_FORMA_CONT_ES_CONSORCIO_PUB CO_LINGUA_INDIGENA_1
## 9925 9923
## CO_IES_OFERTANTE TP_OCUPACAO_GALPAO
## 9918 9900
## TP_INDIGENA_LINGUA IN_FORMA_CONT_MU_TERMO_COLAB
## 9774 9761
## IN_FORMA_CONT_MU_TERMO_FOMENTO IN_FORMA_CONT_MU_ACORDO_COOP
## 9761 9761
## IN_FORMA_CONT_MU_PREST_SERV IN_FORMA_CONT_MU_COOP_TEC_FIN
## 9761 9761
## IN_FORMA_CONT_MU_CONSORCIO_PUB TP_PODER_PUBLICO_PARCERIA
## 9761 9751
cat("Valores únicos (amostra) para 'NO_MUNICIPIO':\n")
## Valores únicos (amostra) para 'NO_MUNICIPIO':
if ("NO_MUNICIPIO" %in% names(educacao_data)) print(unique(na.omit(head(educacao_data$NO_MUNICIPIO, 50))))
## [1] "Abreu E Lima"
Aqui escolhemos variáveis de interesse para análises (ex.: indicadores de infraestrutura) e preparamos possíveis métricas/composições.
# Exemplo: seleção de features de infraestrutura
infra_features <- c(
"IN_LABORATORIO_CIENCIAS",
"IN_BIBLIOTECA",
"IN_REFEITORIO",
"IN_QUADRA_ESPORTES",
"IN_INTERNET",
"IN_COZINHA",
"IN_PISCINA"
)
infra_present <- intersect(infra_features, names(educacao_data))
cat("Colunas de infraestrutura detectadas:", paste(infra_present, collapse = ", "), "\n")
## Colunas de infraestrutura detectadas: IN_LABORATORIO_CIENCIAS, IN_BIBLIOTECA, IN_REFEITORIO, IN_QUADRA_ESPORTES, IN_INTERNET, IN_COZINHA, IN_PISCINA
# Criar resumo por feature
if (length(infra_present) > 0) {
df_feat <- lapply(infra_present, function(f) {
vals <- educacao_data[[f]]
present <- sum(vals == 1, na.rm = TRUE)
non_na <- sum(!is.na(vals))
percent <- ifelse(non_na > 0, present / non_na, NA)
data.frame(feature = f, present = present, non_na = non_na, percent = percent)
}) %>% bind_rows() %>% arrange(desc(present))
df_feat$label <- recode(df_feat$feature,
IN_LABORATORIO_CIENCIAS = "Laboratório de Ciências",
IN_BIBLIOTECA = "Biblioteca",
IN_REFEITORIO = "Refeitório",
IN_QUADRA_ESPORTES = "Quadra de Esportes",
IN_INTERNET = "Internet",
IN_COZINHA = "Cozinha",
IN_PISCINA = "Piscina",
.default = df_feat$feature)
print(df_feat)
}
## feature present non_na percent label
## 1 IN_INTERNET 7509 8013 0.93710221 Internet
## 2 IN_COZINHA 6892 8013 0.86010233 Cozinha
## 3 IN_BIBLIOTECA 3798 8013 0.47397978 Biblioteca
## 4 IN_QUADRA_ESPORTES 2400 8013 0.29951329 Quadra de Esportes
## 5 IN_REFEITORIO 2164 8013 0.27006115 Refeitório
## 6 IN_LABORATORIO_CIENCIAS 1091 8013 0.13615375 Laboratório de Ciências
## 7 IN_PISCINA 297 8013 0.03706477 Piscina
Vários plots para entender a distribuição espacial (por município/mesorregião) e infraestrutura.
# 1) Contagem por município (top N)
schools_by_muni <- educacao_data %>%
filter(!is.na(NO_MUNICIPIO)) %>%
group_by(NO_MUNICIPIO) %>%
summarise(n_schools = n(), .groups = "drop") %>%
arrange(desc(n_schools))
top_n <- 20
schools_by_muni_top <- head(schools_by_muni, top_n)
p_muni <- ggplot(schools_by_muni_top, aes(x = reorder(NO_MUNICIPIO, n_schools), y = n_schools)) +
geom_col(fill = "steelblue") +
coord_flip() +
labs(title = paste0("Top ", top_n, " municípios por número de escolas"), x = "Município", y = "Número de escolas") +
theme_minimal()
p_muni
# 2) Contagem por mesorregião
schools_by_meso <- educacao_data %>%
filter(!is.na(NO_MESORREGIAO)) %>%
group_by(NO_MESORREGIAO) %>%
summarise(n_schools = n(), .groups = "drop") %>%
arrange(desc(n_schools))
p_meso <- ggplot(schools_by_meso, aes(x = reorder(NO_MESORREGIAO, n_schools), y = n_schools)) +
geom_col(fill = "darkgreen") +
coord_flip() +
labs(title = "Escolas por Mesorregião", x = "Mesorregião", y = "Número de escolas") +
theme_minimal()
p_meso
# 3) Gráficos de infraestrutura
if (length(infra_present) > 0) {
df_feat <- df_feat
p_infra_overall <- ggplot(df_feat, aes(x = reorder(label, present), y = present)) +
geom_col(fill = "steelblue") +
coord_flip() +
geom_text(aes(label = paste0(present, " (", scales::percent(percent, accuracy = 0.1), ")")),
hjust = -0.05, size = 3) +
labs(title = "Número de escolas por tipo de infraestrutura",
subtitle = "(valor absoluto e % sobre registros não-missing)", x = "Infraestrutura", y = "Número de escolas") +
theme_minimal() +
scale_y_continuous(expand = expansion(mult = c(0, 0.15)))
p_infra_overall
# Distribuição do número de infraestruturas presentes por escola
infra_matrix <- educacao_data[, infra_present, drop = FALSE]
infra_count <- rowSums(infra_matrix == 1, na.rm = TRUE)
df_count <- data.frame(n_resources = infra_count)
p_infra_count <- ggplot(df_count, aes(x = n_resources)) +
geom_bar(fill = "coral") +
labs(title = "Distribuição do número de infraestruturas presentes por escola",
x = "Número de infraestruturas (marcadas)", y = "Número de escolas") +
theme_minimal()
p_infra_count
}