options(repos = c(CRAN = "https://cloud.r-project.org"))
# INSTALACIÓN Y CARGA DE PAQUETES

# Instalar (solo la primera vez)
install.packages("tidyverse") # dplyr, tidyr, ggplot2, readr, tibbles
Installing package into 'C:/Users/john/AppData/Local/R/win-library/4.5'
(as 'lib' is unspecified)
package 'tidyverse' successfully unpacked and MD5 sums checked

The downloaded binary packages are in
    C:\Users\john\AppData\Local\Temp\Rtmpm6opRW\downloaded_packages
install.packages("mice") # imputación múltiple
Installing package into 'C:/Users/john/AppData/Local/R/win-library/4.5'
(as 'lib' is unspecified)
package 'mice' successfully unpacked and MD5 sums checked
Warning: cannot remove prior installation of package 'mice'
Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
C:\Users\john\AppData\Local\R\win-library\4.5\00LOCK\mice\libs\x64\mice.dll a
C:\Users\john\AppData\Local\R\win-library\4.5\mice\libs\x64\mice.dll:
Permission denied
Warning: restored 'mice'

The downloaded binary packages are in
    C:\Users\john\AppData\Local\Temp\Rtmpm6opRW\downloaded_packages
install.packages("VIM") # diagnóstico y visualización de NA
Installing package into 'C:/Users/john/AppData/Local/R/win-library/4.5'
(as 'lib' is unspecified)
package 'VIM' successfully unpacked and MD5 sums checked
Warning: cannot remove prior installation of package 'VIM'
Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
C:\Users\john\AppData\Local\R\win-library\4.5\00LOCK\VIM\libs\x64\VIM.dll a
C:\Users\john\AppData\Local\R\win-library\4.5\VIM\libs\x64\VIM.dll: Permission
denied
Warning: restored 'VIM'

The downloaded binary packages are in
    C:\Users\john\AppData\Local\Temp\Rtmpm6opRW\downloaded_packages
install.packages("writexl") # exportar a Excel
Installing package into 'C:/Users/john/AppData/Local/R/win-library/4.5'
(as 'lib' is unspecified)
package 'writexl' successfully unpacked and MD5 sums checked
Warning: cannot remove prior installation of package 'writexl'
Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
C:\Users\john\AppData\Local\R\win-library\4.5\00LOCK\writexl\libs\x64\writexl.dll
a C:\Users\john\AppData\Local\R\win-library\4.5\writexl\libs\x64\writexl.dll:
Permission denied
Warning: restored 'writexl'

The downloaded binary packages are in
    C:\Users\john\AppData\Local\Temp\Rtmpm6opRW\downloaded_packages
install.packages("MASS") # estadísticas (conflicto con select)
Installing package into 'C:/Users/john/AppData/Local/R/win-library/4.5'
(as 'lib' is unspecified)
package 'MASS' successfully unpacked and MD5 sums checked
Warning: cannot remove prior installation of package 'MASS'
Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
C:\Users\john\AppData\Local\R\win-library\4.5\00LOCK\MASS\libs\x64\MASS.dll a
C:\Users\john\AppData\Local\R\win-library\4.5\MASS\libs\x64\MASS.dll:
Permission denied
Warning: restored 'MASS'

The downloaded binary packages are in
    C:\Users\john\AppData\Local\Temp\Rtmpm6opRW\downloaded_packages
install.packages("openxlsx") # leer/escribir Excel
Installing package into 'C:/Users/john/AppData/Local/R/win-library/4.5'
(as 'lib' is unspecified)
package 'openxlsx' successfully unpacked and MD5 sums checked
Warning: cannot remove prior installation of package 'openxlsx'
Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
C:\Users\john\AppData\Local\R\win-library\4.5\00LOCK\openxlsx\libs\x64\openxlsx.dll
a C:\Users\john\AppData\Local\R\win-library\4.5\openxlsx\libs\x64\openxlsx.dll:
Permission denied
Warning: restored 'openxlsx'

The downloaded binary packages are in
    C:\Users\john\AppData\Local\Temp\Rtmpm6opRW\downloaded_packages
install.packages("stringi") # manejo avanzado de texto
Installing package into 'C:/Users/john/AppData/Local/R/win-library/4.5'
(as 'lib' is unspecified)
package 'stringi' successfully unpacked and MD5 sums checked
Warning: cannot remove prior installation of package 'stringi'
Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
C:\Users\john\AppData\Local\R\win-library\4.5\00LOCK\stringi\libs\x64\stringi.dll
a C:\Users\john\AppData\Local\R\win-library\4.5\stringi\libs\x64\stringi.dll:
Permission denied
Warning: restored 'stringi'

The downloaded binary packages are in
    C:\Users\john\AppData\Local\Temp\Rtmpm6opRW\downloaded_packages
install.packages("janitor") # limpieza de nombres y tablas
Installing package into 'C:/Users/john/AppData/Local/R/win-library/4.5'
(as 'lib' is unspecified)
package 'janitor' successfully unpacked and MD5 sums checked

The downloaded binary packages are in
    C:\Users\john\AppData\Local\Temp\Rtmpm6opRW\downloaded_packages
install.packages("lubridate") # manejo de fechas
Installing package into 'C:/Users/john/AppData/Local/R/win-library/4.5'
(as 'lib' is unspecified)
package 'lubridate' successfully unpacked and MD5 sums checked
Warning: cannot remove prior installation of package 'lubridate'
Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
C:\Users\john\AppData\Local\R\win-library\4.5\00LOCK\lubridate\libs\x64\lubridate.dll
a
C:\Users\john\AppData\Local\R\win-library\4.5\lubridate\libs\x64\lubridate.dll:
Permission denied
Warning: restored 'lubridate'

The downloaded binary packages are in
    C:\Users\john\AppData\Local\Temp\Rtmpm6opRW\downloaded_packages
install.packages("stringr") # funciones de texto
Installing package into 'C:/Users/john/AppData/Local/R/win-library/4.5'
(as 'lib' is unspecified)
package 'stringr' successfully unpacked and MD5 sums checked

The downloaded binary packages are in
    C:\Users\john\AppData\Local\Temp\Rtmpm6opRW\downloaded_packages
install.packages("readr") # lectura eficiente de CSV
Installing package into 'C:/Users/john/AppData/Local/R/win-library/4.5'
(as 'lib' is unspecified)
package 'readr' successfully unpacked and MD5 sums checked
Warning: cannot remove prior installation of package 'readr'
Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
C:\Users\john\AppData\Local\R\win-library\4.5\00LOCK\readr\libs\x64\readr.dll a
C:\Users\john\AppData\Local\R\win-library\4.5\readr\libs\x64\readr.dll:
Permission denied
Warning: restored 'readr'

The downloaded binary packages are in
    C:\Users\john\AppData\Local\Temp\Rtmpm6opRW\downloaded_packages
install.packages("dplyr") # manipulación de datos
Installing package into 'C:/Users/john/AppData/Local/R/win-library/4.5'
(as 'lib' is unspecified)
package 'dplyr' successfully unpacked and MD5 sums checked
Warning: cannot remove prior installation of package 'dplyr'
Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
C:\Users\john\AppData\Local\R\win-library\4.5\00LOCK\dplyr\libs\x64\dplyr.dll a
C:\Users\john\AppData\Local\R\win-library\4.5\dplyr\libs\x64\dplyr.dll:
Permission denied
Warning: restored 'dplyr'

The downloaded binary packages are in
    C:\Users\john\AppData\Local\Temp\Rtmpm6opRW\downloaded_packages
install.packages("purrr") # programación funcional
Installing package into 'C:/Users/john/AppData/Local/R/win-library/4.5'
(as 'lib' is unspecified)
package 'purrr' successfully unpacked and MD5 sums checked
Warning: cannot remove prior installation of package 'purrr'
Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
C:\Users\john\AppData\Local\R\win-library\4.5\00LOCK\purrr\libs\x64\purrr.dll a
C:\Users\john\AppData\Local\R\win-library\4.5\purrr\libs\x64\purrr.dll:
Permission denied
Warning: restored 'purrr'

The downloaded binary packages are in
    C:\Users\john\AppData\Local\Temp\Rtmpm6opRW\downloaded_packages
install.packages("fs") # manejo de archivos y directorios
Installing package into 'C:/Users/john/AppData/Local/R/win-library/4.5'
(as 'lib' is unspecified)
package 'fs' successfully unpacked and MD5 sums checked
Warning: cannot remove prior installation of package 'fs'
Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
C:\Users\john\AppData\Local\R\win-library\4.5\00LOCK\fs\libs\x64\fs.dll a
C:\Users\john\AppData\Local\R\win-library\4.5\fs\libs\x64\fs.dll: Permission
denied
Warning: restored 'fs'

The downloaded binary packages are in
    C:\Users\john\AppData\Local\Temp\Rtmpm6opRW\downloaded_packages
install.packages("openxlsx") # crear, leer y escribir archivos Excel (.xlsx)
Installing package into 'C:/Users/john/AppData/Local/R/win-library/4.5'
(as 'lib' is unspecified)
package 'openxlsx' successfully unpacked and MD5 sums checked
Warning: cannot remove prior installation of package 'openxlsx'
Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
C:\Users\john\AppData\Local\R\win-library\4.5\00LOCK\openxlsx\libs\x64\openxlsx.dll
a C:\Users\john\AppData\Local\R\win-library\4.5\openxlsx\libs\x64\openxlsx.dll:
Permission denied
Warning: restored 'openxlsx'

The downloaded binary packages are in
    C:\Users\john\AppData\Local\Temp\Rtmpm6opRW\downloaded_packages

0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1

1 PROCESAMIENTO COMPLETO DEL SABER 11 (2010–2022)

2 - FASE 0: Cargar base original

3 - FASE 1: Crear carpetas por año y dividir por periodos

4 - FASE 2: Unificar periodos de cada año

5 Autor: John Jairo Prado Piñeres

5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1

6 FASE 1: CARGAR LIBRERÍAS

# Conjunto principal de librerías para manejo, limpieza y exportación de datos

library(readr) # lectura rápida y eficiente de archivos CSV
library(dplyr) # manipulación de datos (filter, mutate, group_by)

Adjuntando el paquete: 'dplyr'
The following objects are masked from 'package:stats':

    filter, lag
The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
library(purrr) # programación funcional (map, walk)
Warning: package 'purrr' was built under R version 4.5.2
library(fs) # manejo de archivos y creación de directorios
Warning: package 'fs' was built under R version 4.5.2
library(openxlsx)

Esta sección carga todas las librerías necesarias para procesar tus bases de datos del Saber 11. Usamos exclude = “select” para evitar conflictos entre MASS y dplyr.

7 **CARGA DE DATOS ORIGINALES

# CARGA DE DATOS ORIGINALES

saber11_raw <- read_csv(
  "C:/Users/john/Desktop/Saber_11_2025/data/Resultados_únicos_Saber_11_20251019.csv"
)
Warning: One or more parsing issues, call `problems()` on your data frame for details,
e.g.:
  dat <- vroom(...)
  problems(dat)
Rows: 7109704 Columns: 51
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (43): ESTU_TIPODOCUMENTO, ESTU_CONSECUTIVO, COLE_AREA_UBICACION, COLE_BI...
dbl  (8): PERIODO, COLE_COD_DANE_ESTABLECIMIENTO, PUNT_INGLES, PUNT_MATEMATI...

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# confirmar
glimpse(saber11_raw)
Rows: 7,109,704
Columns: 51
$ PERIODO                       <dbl> 20131, 20194, 20194, 20122, 20132, 20194…
$ ESTU_TIPODOCUMENTO            <chr> "CR", "TI", "TI", "TI", "TI", "TI", "TI"…
$ ESTU_CONSECUTIVO              <chr> "SB11201310000414", "SB11201940464873", …
$ COLE_AREA_UBICACION           <chr> "URBANO", "RURAL", "RURAL", "URBANO", "U…
$ COLE_BILINGUE                 <chr> "N", "N", "N", "N", "N", "N", "N", "N", …
$ COLE_CALENDARIO               <chr> "B", "A", "A", "A", "A", "A", "A", "A", …
$ COLE_CARACTER                 <chr> "ACADÉMICO", "TÉCNICO/ACADÉMICO", "TÉCNI…
$ COLE_COD_DANE_ESTABLECIMIENTO <dbl> 311848000812, 141016000305, 141016000305…
$ COLE_COD_DANE_SEDE            <chr> "311848000812", "241016000342", "2410160…
$ COLE_COD_DEPTO_UBICACION      <chr> "11", "41", "41", "63", "19", "41", "41"…
$ COLE_COD_MCPIO_UBICACION      <chr> "11001", "41016", "41016", "63130", "190…
$ COLE_CODIGO_ICFES             <chr> "022574", "194878", "194878", "013029", …
$ COLE_DEPTO_UBICACION          <chr> "BOGOTA", "HUILA", "HUILA", "QUINDIO", "…
$ COLE_GENERO                   <chr> "FEMENINO", "MIXTO", "MIXTO", "MIXTO", "…
$ COLE_JORNADA                  <chr> "COMPLETA", "COMPLETA", "COMPLETA", "MAÑ…
$ COLE_MCPIO_UBICACION          <chr> "BOGOTÁ D.C.", "AIPE", "AIPE", "CALARCÁ"…
$ COLE_NATURALEZA               <chr> "NO OFICIAL", "OFICIAL", "OFICIAL", "OFI…
$ COLE_NOMBRE_ESTABLECIMIENTO   <chr> "GIMN FEMENINO", "INSTITUCION EDUCATIVA …
$ COLE_NOMBRE_SEDE              <chr> "GIMN FEMENINO", "DINDAL", "DINDAL", "AN…
$ COLE_SEDE_PRINCIPAL           <chr> "S", "N", "N", "S", "S", "S", "S", "S", …
$ ESTU_COD_DEPTO_PRESENTACION   <chr> "11", "41", "41", "63", "19", "41", "41"…
$ ESTU_COD_MCPIO_PRESENTACION   <chr> "11001", "41016", "41016", "63130", "190…
$ ESTU_COD_RESIDE_DEPTO         <chr> "11", "41", "41", "63", "19", "41", "41"…
$ ESTU_COD_RESIDE_MCPIO         <chr> "11001", "41016", "41016", "63130", "190…
$ ESTU_DEPTO_PRESENTACION       <chr> "BOGOTÁ", "HUILA", "HUILA", "QUINDIO", "…
$ ESTU_DEPTO_RESIDE             <chr> "BOGOTÁ", "HUILA", "HUILA", "QUINDIO", "…
$ ESTU_ESTADOINVESTIGACION      <chr> "PUBLICAR", "PUBLICAR", "PUBLICAR", "PUB…
$ ESTU_ESTUDIANTE               <chr> "ESTUDIANTE", "ESTUDIANTE", "ESTUDIANTE"…
$ ESTU_FECHANACIMIENTO          <chr> "08/08/1994", "15/02/2003", "15/02/2003"…
$ ESTU_GENERO                   <chr> "F", "F", "F", "F", "F", "F", "F", "M", …
$ ESTU_MCPIO_PRESENTACION       <chr> "BOGOTÁ D.C.", "AIPE", "AIPE", "CALARCÁ"…
$ ESTU_MCPIO_RESIDE             <chr> "BOGOTÁ D.C.", "AIPE", "AIPE", "CALARCÁ"…
$ ESTU_NACIONALIDAD             <chr> "COLOMBIA", "COLOMBIA", "COLOMBIA", "COL…
$ ESTU_PAIS_RESIDE              <chr> "COLOMBIA", "COLOMBIA", "COLOMBIA", "COL…
$ ESTU_PRIVADO_LIBERTAD         <chr> "N", "N", "N", "N", "N", "N", "N", "N", …
$ FAMI_CUARTOSHOGAR             <chr> "Cuatro", "Dos", "Dos", "Dos", "Cinco", …
$ FAMI_EDUCACIONMADRE           <chr> "Educación profesional completa", "Postg…
$ FAMI_EDUCACIONPADRE           <chr> "Educación profesional completa", "Prima…
$ FAMI_ESTRATOVIVIENDA          <chr> "Estrato 6", "Estrato 2", "Estrato 2", "…
$ FAMI_PERSONASHOGAR            <chr> "Cuatro", "1 a 2", "1 a 2", "Cuatro", "O…
$ FAMI_TIENEAUTOMOVIL           <chr> "Si", "No", "No", "No", "No", "No", "No"…
$ FAMI_TIENECOMPUTADOR          <chr> "Si", "Si", "Si", "Si", "Si", "No", "No"…
$ FAMI_TIENEINTERNET            <chr> "Si", "Si", "Si", "Si", "Si", "No", "No"…
$ FAMI_TIENELAVADORA            <chr> "Si", "Si", "Si", "No", "Si", "No", "No"…
$ DESEMP_INGLES                 <chr> "B+", "B1", "B1", "A1", "A-", "A-", "A-"…
$ PUNT_INGLES                   <dbl> 94.00, 71.00, 71.00, 48.00, 43.00, 46.00…
$ PUNT_MATEMATICAS              <dbl> 88.00, 66.00, 66.00, 45.00, 52.00, 43.00…
$ PUNT_SOCIALES_CIUDADANAS      <dbl> NA, 70, 70, NA, NA, 31, 31, 46, NA, 54, …
$ PUNT_C_NATURALES              <dbl> NA, 65, 65, NA, NA, 40, 40, 57, NA, 44, …
$ PUNT_LECTURA_CRITICA          <dbl> NA, 69, 69, NA, NA, 43, 43, 57, NA, 54, …
$ PUNT_GLOBAL                   <dbl> NA, 339, 339, NA, NA, 199, 199, 272, NA,…
names(saber11_raw)
 [1] "PERIODO"                       "ESTU_TIPODOCUMENTO"           
 [3] "ESTU_CONSECUTIVO"              "COLE_AREA_UBICACION"          
 [5] "COLE_BILINGUE"                 "COLE_CALENDARIO"              
 [7] "COLE_CARACTER"                 "COLE_COD_DANE_ESTABLECIMIENTO"
 [9] "COLE_COD_DANE_SEDE"            "COLE_COD_DEPTO_UBICACION"     
[11] "COLE_COD_MCPIO_UBICACION"      "COLE_CODIGO_ICFES"            
[13] "COLE_DEPTO_UBICACION"          "COLE_GENERO"                  
[15] "COLE_JORNADA"                  "COLE_MCPIO_UBICACION"         
[17] "COLE_NATURALEZA"               "COLE_NOMBRE_ESTABLECIMIENTO"  
[19] "COLE_NOMBRE_SEDE"              "COLE_SEDE_PRINCIPAL"          
[21] "ESTU_COD_DEPTO_PRESENTACION"   "ESTU_COD_MCPIO_PRESENTACION"  
[23] "ESTU_COD_RESIDE_DEPTO"         "ESTU_COD_RESIDE_MCPIO"        
[25] "ESTU_DEPTO_PRESENTACION"       "ESTU_DEPTO_RESIDE"            
[27] "ESTU_ESTADOINVESTIGACION"      "ESTU_ESTUDIANTE"              
[29] "ESTU_FECHANACIMIENTO"          "ESTU_GENERO"                  
[31] "ESTU_MCPIO_PRESENTACION"       "ESTU_MCPIO_RESIDE"            
[33] "ESTU_NACIONALIDAD"             "ESTU_PAIS_RESIDE"             
[35] "ESTU_PRIVADO_LIBERTAD"         "FAMI_CUARTOSHOGAR"            
[37] "FAMI_EDUCACIONMADRE"           "FAMI_EDUCACIONPADRE"          
[39] "FAMI_ESTRATOVIVIENDA"          "FAMI_PERSONASHOGAR"           
[41] "FAMI_TIENEAUTOMOVIL"           "FAMI_TIENECOMPUTADOR"         
[43] "FAMI_TIENEINTERNET"            "FAMI_TIENELAVADORA"           
[45] "DESEMP_INGLES"                 "PUNT_INGLES"                  
[47] "PUNT_MATEMATICAS"              "PUNT_SOCIALES_CIUDADANAS"     
[49] "PUNT_C_NATURALES"              "PUNT_LECTURA_CRITICA"         
[51] "PUNT_GLOBAL"                  
# CREAR COLUMNA ANIO A PARTIR DE PERIODO

saber11 <- saber11_raw %>%
  mutate(
    PERIODO = as.character(PERIODO),
    ANIO = substr(PERIODO, 1, 4)
  )

# Años detectados
anios <- unique(saber11$ANIO)
print(anios)
 [1] "2013" "2019" "2012" "2016" "2017" "2010" "2014" "2011" "2015" "2020"
[11] "2022" "2021" "2018"
#GUARDAR ARCHIVOS POR AÑO Y PERIODO

base_dir <- "C:/Users/john/Desktop/Saber_11_2025/data/chunks/"

walk(anios, function(anio) {
  
  # Crear carpeta del año
  year_dir <- file.path(base_dir, anio)
  dir_create(year_dir)
  
  # Filtrar datos del año
  data_year <- saber11 %>% filter(ANIO == anio)
  
  # Periodos dentro del año (ej: 20101, 20102, 20103)
  periodos <- unique(data_year$PERIODO)
  
  # Guardar cada periodo como archivo independiente
  walk(periodos, function(periodo) {
    
    data_periodo <- data_year %>% filter(PERIODO == periodo)
    
    file_out <- file.path(year_dir, paste0("Saber11_", periodo, ".csv"))
    
    write_csv(data_periodo, file_out)
  })
})

message("\nFase 1 completada: archivos separados por año y periodo\n")

Fase 1 completada: archivos separados por año y periodo
# UNIFICAR ARCHIVOS DE CADA AÑO Y EXPORTAR CSV + XLSX

output_dir <- "C:/Users/john/Desktop/Saber_11_2025/data/UNIDOS/"
dir_create(output_dir)

# Detectar carpetas 2010–2022
anios_disponibles <- dir_ls(
  base_dir,
  type = "directory",
  regexp = "[0-9]{4}$"
) %>% path_file()

print(anios_disponibles)
 [1] "2010" "2011" "2012" "2013" "2014" "2015" "2016" "2017" "2018" "2019"
[11] "2020" "2021" "2022"
# Tipos robustos para leer todos los periodos
tipos_forzados <- cols(
  .default = col_character(),
  PERIODO = col_double(),
  PUNT_INGLES = col_double(),
  PUNT_MATEMATICAS = col_double(),
  PUNT_SOCIALES_CIUDADANAS = col_double(),
  PUNT_C_NATURALES = col_double(),
  PUNT_LECTURA_CRITICA = col_double(),
  PUNT_GLOBAL = col_double()
)


walk(anios_disponibles, function(anio) {
  
  message("UNIFICANDO AÑO: ", anio)
  
  ruta_anio <- file.path(base_dir, anio)
  
  archivos <- dir_ls(
    ruta_anio,
    regexp = "\\.csv$",
    type = "file"
  )
  
  if (length(archivos) == 0) {
    warning("No hay archivos CSV en: ", ruta_anio)
    return(NULL)
  }
  
  # Leer + unir periodos del año
  data_anio <- archivos %>%
    map(~ read_csv(.x, col_types = tipos_forzados, show_col_types = FALSE)) %>%
    bind_rows()
  
  message("Registros totales en ", anio, ": ", nrow(data_anio))
  
  # Exportar CSV
  write_csv(
    data_anio,
    file.path(output_dir, paste0("Saber11_", anio, "_UNIDO.csv"))
  )
  
  # Exportar XLSX
  write.xlsx(
    data_anio,
    file = file.path(output_dir, paste0("Saber11_", anio, "_UNIDO.xlsx")),
    overwrite = TRUE
  )
  
  message("Exportado CSV + XLSX para ", anio)
})
UNIFICANDO AÑO: 2010
Registros totales en 2010: 670030
Exportado CSV + XLSX para 2010
UNIFICANDO AÑO: 2011
Registros totales en 2011: 650420
Exportado CSV + XLSX para 2011
UNIFICANDO AÑO: 2012
Registros totales en 2012: 680388
Exportado CSV + XLSX para 2012
UNIFICANDO AÑO: 2013
Registros totales en 2013: 583775
Exportado CSV + XLSX para 2013
UNIFICANDO AÑO: 2014
Registros totales en 2014: 571637
Exportado CSV + XLSX para 2014
UNIFICANDO AÑO: 2015
Registros totales en 2015: 570464
Exportado CSV + XLSX para 2015
UNIFICANDO AÑO: 2016
Registros totales en 2016: 563370
Exportado CSV + XLSX para 2016
UNIFICANDO AÑO: 2017
Registros totales en 2017: 561287
Exportado CSV + XLSX para 2017
UNIFICANDO AÑO: 2018
Registros totales en 2018: 32348
Exportado CSV + XLSX para 2018
UNIFICANDO AÑO: 2019
Registros totales en 2019: 1109085
Exportado CSV + XLSX para 2019
UNIFICANDO AÑO: 2020
Registros totales en 2020: 15435
Exportado CSV + XLSX para 2020
UNIFICANDO AÑO: 2021
Registros totales en 2021: 15528
Exportado CSV + XLSX para 2021
UNIFICANDO AÑO: 2022
Registros totales en 2022: 1085937
Exportado CSV + XLSX para 2022

8 Tabla por años y porcentaje

Año Registros Porcentaje (%)
2010 670,030 10.99%
2011 650,420 10.66%
2012 680,388 11.16%
2013 583,775 9.57%
2014 571,637 9.37%
2015 570,464 9.35%
2016 563,370 9.24%
2017 561,287 9.20%
2018 32,348 0.53%
2019 1,109,085 18.19%
2020 15,435 0.25%
2021 15,528 0.25%
2022 1,085,937 17.80%
TOTAL 6,099,664 100%

9 CONCLUSIONES

El proceso de depuración, estandarización y unificación de los microdatos del examen Saber 11 permitió consolidar un conjunto de datos robusto y metodológicamente consistente para el periodo 2010–2022. A partir del archivo original —que contenía 7.109.704 registros— se identificó que únicamente 6.099.664 correspondían a observaciones válidas dentro del intervalo temporal oficial del estudio. La diferencia se explicó por la presencia de registros adicionales no pertinentes para el análisis longitudinal, tales como observaciones sin código de periodo, inconsistencias de formato en la variable PERIODO, registros administrativos y casos atípicos asociados a pruebas extraordinarias o datos sin correspondencia en el calendario oficial del ICFES.

La clasificación y procesamiento de los registros permitieron garantizar que únicamente se conservaran los datos coherentes con la estructura histórica del examen Saber 11. De esta manera, se aseguraron comparaciones válidas y uniformes a lo largo del tiempo, evitando sesgos derivados de reformulaciones del instrumento, cambios administrativos o variaciones en la población evaluada. La homogeneización de tipos de datos, la preservación de los identificadores administrativos y la eliminación de duplicados entre periodos fueron fundamentales para estabilizar la base analítica.

Los resultados evidenciaron además la fuerte variabilidad anual en el número de estudiantes que presentaron la prueba, especialmente durante los años 2018, 2020 y 2021, afectados por cambios operativos y por las restricciones generadas por la pandemia de COVID-19. Estas fluctuaciones deben considerarse en futuros modelos predictivos y análisis espaciotemporales, dado que pueden introducir patrones no atribuibles a tendencias educativas sino a condiciones externas.

El conjunto final constituye una base de datos estructuralmente confiable y empíricamente consistente para el desarrollo de modelos de grafos (GNN), análisis de series temporales y proyecciones del rendimiento académico hacia el periodo 2023–2026. La limpieza y organización del dataset garantizan que las estimaciones, inferencias y predicciones derivadas de los modelos analíticos se fundamenten sobre información válida, comparable y metodológicamente sólida, lo que fortalece la calidad y reproducibilidad de la investigación.