El examen de admisión a licenciatura de la UNAM fue realizado en línea por primera vez en su historia; cuando se publicaron los resultados, las personas en internet comenzaron a notar que la distribución de los aciertos fue anormal para varias carreras, muchos de los aspirantes habían hecho trampa para poder ingresar.
En este trabajo se hará una comparación de los resultados de los años anteriores con los del concurso de selección de este año 2026. Los datos fueron recopilados de un dataset de libre acceso en GitHub (Karen Arlet Castrillo Cruz. (2026). Resultados UNAM — Datos de admisión a licenciatura (2021–2026).
En este caso, solo se usará el archivo csv con los siguientes datos:
| Columna | Tipo | Descripción |
|---|---|---|
| folio | entero | Folio del aspirante (identificador anónimo, no es información personal) |
| aciertos | entero / NA | Número de respuestas correctas en el examen. Nulo si el aspirante no presentó |
| acreditado | S / N /C / NA | S = seleccionado, N = no
seleccionado, C = cancelado. Nulo cuando no aplica |
| año | entero | Año del proceso de admisión (2021–2026) |
| area | entero (1-4) | Área de conocimiento según clasificación de la DGAE |
| carrera | texto | Carrera solicitada |
| plantel | texto | Plantel/facultad solicitada |
La base de datos cuenta con más de 1 millón de registros desde el año 2021 hasta el 2026
Hay 116 carreras ofertadas y se imparten en 54 planteles
La carrera con mayor cantidad de registros es la de Médico Cirujano
# cargar librerias
library("plotly")
library("dplyr")
library("tidyr")
# cargar base de datos
u <- read.csv("aciertos_unam_2021_2026.csv")
# Revisar la estructura de datos
str(u)
## 'data.frame': 1027716 obs. of 7 variables:
## $ folio : int 1 30 56 133 148 151 167 208 283 326 ...
## $ aciertos : num 71 93 49 90 62 51 111 85 NA 106 ...
## $ acreditado: chr "" "" "" "" ...
## $ año : int 2021 2021 2021 2021 2021 2021 2021 2021 2021 2021 ...
## $ area : int 1 1 1 1 1 1 1 1 1 1 ...
## $ carrera : chr "ACTUARIA" "ACTUARIA" "ACTUARIA" "ACTUARIA" ...
## $ plantel : chr "FACULTAD DE CIENCIAS" "FACULTAD DE CIENCIAS" "FACULTAD DE CIENCIAS" "FACULTAD DE CIENCIAS" ...
# eliminar NAs
unam <- na.omit(u)
Ya que cargamos los datos y eliminamos los NAs, vamos a hacer el cálculo de la estadística en general.
# Vemos el resumen de los aciertos
summary(unam$aciertos)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.0 42.0 54.0 58.3 71.0 120.0
desv_st <- sd(unam$aciertos)
print(paste("Desviación estándar global:", round(desv_st, 2)))
## [1] "Desviación estándar global: 20.97"
Ahora, vamos a ver la distribución de los aciertos con histogramas
# Histograma
plot_ly(
type = "histogram",
x = unam$aciertos,
marker = list(color = "#6E8B3D")
) %>%
layout(
title = "Distribución General de Aciertos (2021-2026)",
xaxis = list(title = "Aciertos"),
yaxis = list(title = "Frecuencia")
)
En esta gráfica observamos la distribución de los datos del año 2021-2026. Ahora presento una comparativa de los años previos vs 2026.
En este caso, vamos a separar los periodos y a graficar en boxplots para poder ver la comparación entre cada año:
unam <- unam %>%
mutate(periodo = ifelse(año == 2026, "2026 (Sospecha?)", "2021-2025"))
# Graficamos el Boxplot para evidenciar el salto en los puntajes
plot_ly(
data = unam,
type = "box",
y = ~aciertos,
color = ~periodo,
colors = c("#A2CD5A", "#FFB90F")
) %>%
layout(
title = "Anomalía de Puntajes: 2026 vs Años Previos",
xaxis = list(title = "Periodo"),
yaxis = list(title = "Aciertos")
)
Podemos observar que los puntajes se dispararon, en años previos la mediana se mantuvo al rededor de los 52 aciertos, para el año 2026,la mediana subió a 71.
# Calcular cuartiles y percentiles altos por año
percentiles_por_año <- unam %>%
group_by(año) %>%
summarise(
Mediana = median(aciertos),
Top_25_Porciento = quantile(aciertos, 0.75),
Top_10_Porciento = quantile(aciertos, 0.90)
)
print(percentiles_por_año)
## # A tibble: 6 × 4
## año Mediana Top_25_Porciento Top_10_Porciento
## <int> <dbl> <dbl> <dbl>
## 1 2021 52 67 84
## 2 2022 51 66 82
## 3 2023 52 68 84
## 4 2024 52 68 86
## 5 2025 52 68 86
## 6 2026 71 93 105
Se observa que de 2021-2025 la mediana se quedó entre 51 y 52 aciertos, la mitad de los aspirantes sacaban menos de 52 aciertos
Además, entre 2021-2025 el top 10% de los mejores aspirantes lograban sacar de 84-86 aciertos
En 2026 la mediana subió a 71 aciertos, el top10% de los aspirantes alcanzó los 105 aciertos
¿Qué carreras son las que tienen más solicitudes? Quiero investigar si hay una correlación entre las carreras más solicitadas y los puntajes, en este caso, buscaremos si hay un incremento en el número de aciertos en esas carreras en comparación con los años anteriores.
top_carreras <- unam %>%
count(carrera, sort = TRUE) %>%
head(5)
print("Las 5 carreras más solicitadas:")
## [1] "Las 5 carreras más solicitadas:"
print(top_carreras)
## carrera n
## 1 MEDICO CIRUJANO 134189
## 2 DERECHO 63152
## 3 PSICOLOGIA 53144
## 4 ARQUITECTURA 44345
## 5 ADMINISTRACION 44274
plot_ly(
x = top_carreras$carrera,
y = top_carreras$n,
type = "bar",
marker = list(color = "#EEA2AD")
) %>%
layout(
title = "Top 5 Carreras con Mayor Demanda",
xaxis = list(title = "Carrera"),
yaxis = list(title = "Número de Aspirantes")
)
Vamos a enfocarnos en las tres carreras con mayor volúmen histórico: Médico Cirujano, Derecho y Psicología.
# Filtrar las 3 carreras más solicitadas
carreras_top3 <- c("MEDICO CIRUJANO", "DERECHO", "PSICOLOGIA")
datos_top3 <- unam %>%
filter(carrera %in% carreras_top3)
# Resumen de promedios por año para estas 3 carreras
resumen_top3 <- datos_top3 %>%
group_by(carrera, año) %>%
summarise(promedio = round(mean(aciertos), 1), .groups = 'drop') %>%
pivot_wider(names_from = año, values_from = promedio)
print(resumen_top3, width = Inf)
## # A tibble: 3 × 7
## carrera `2021` `2022` `2023` `2024` `2025` `2026`
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 DERECHO 53.4 52.3 53.1 54 54 70.8
## 2 MEDICO CIRUJANO 59.7 58.1 61 60 60.9 78.1
## 3 PSICOLOGIA 52.1 51.8 54.3 52.8 52.9 65.9
Se observa lo siguiente:
Médico cirujano: Anteriormente el promedio de aciertos rondaba los 60 aciertos. En 2026, el promedio se disparó a 78 aciertos
Derecho: La media histórica era de 53 aciertos, en 2026 saltó a 71
Psicología: Su promedio era de 52 aciertos y en 2026 subió a 65 aciertos
# Pre-calcular las frecuencias
datos_animacion <- unam %>%
# Creamos los bloques de aciertos (0-5, 5-10, etc.)
mutate(grupo_aciertos = cut(aciertos, breaks = seq(0, 125, by = 5), right = FALSE)) %>%
group_by(año, grupo_aciertos) %>%
summarise(frecuencia = n(), .groups = 'drop') %>%
# Sacamos el numero inicial del bloque para ponerlo en el eje X
mutate(aciertos_eje_x = as.numeric(sub("\\[([0-9]+),.*", "\\1", grupo_aciertos))) %>%
# Limpiamos los NA que puedan salir por el corte
drop_na()
# 2.animación con "bar"
plot_ly(
data = datos_animacion,
x = ~aciertos_eje_x,
y = ~frecuencia,
frame = ~año,
type = "bar",
marker = list(color = "#6E8B3D", line = list(color = "white", width = 0.5)),
width = 0.8
) %>%
layout(
title = "Evolución Histórica de Aciertos (2021-2026)",
xaxis = list(
title = "Aciertos",
range = c(0, 120),
dtick = 10
),
yaxis = list(
title = "Frecuencia de Aspirantes",
range = c(0, max(datos_animacion$frecuencia) + 2000) # Ajuste automático de altura
)
) %>%
animation_opts(
frame = 1500, # Duración de cada año en milisegundos
transition = 800, # Suavidad del movimiento de las barras
easing = "linear",
redraw = FALSE
) %>%
animation_slider(
currentvalue = list(prefix = "Año Evaluado: ", font = list(color = "#CD3700"))
)
# Tabla de frecuencias para los planteles
top_planteles <- unam %>%
count(plantel, sort = TRUE) %>%
head(10)
print(top_planteles)
## plantel n
## 1 FES ZARAGOZA 96039
## 2 FACULTAD DE MEDICINA 78823
## 3 FES IZTACALA 75888
## 4 FES ARAGÓN 73470
## 5 FES ACATLÁN 53195
## 6 FACULTAD DE INGENIERÍA 49338
## 7 FACULTAD DE CONTADURÍA Y ADMINISTRACIÓN 42420
## 8 FES CUAUTITLÁN 41543
## 9 FACULTAD DE DERECHO 32670
## 10 FACULTAD DE CIENCIAS 29866
La UNAM divide las carreras en 4 áreas:
Área 1 (Ciencias Físico-Matemáticas)
Área 2 (Biológicas y de la Salud)
Área 3 (Ciencias Sociales)
Área 4 (Humanidades y de las Artes)
# Calcular frecuencias por área
demanda_area <- unam %>%
count(area) %>%
mutate(area_nombre = paste("Área", area))
# Gráfico de pastel interactivo con Plotly
plot_ly(
data = demanda_area,
type = "pie",
labels = ~area_nombre,
values = ~n,
hole = 0.4 # Esto lo hace un gráfico de dona (opcional, se ve muy bien)
) %>%
layout(title = "Distribución de Aspirantes por Área de Conocimiento")
Filtramos para analizar únicamente el plantel de la ENES Juriquilla
datos_juriquilla <- unam %>%
filter(grepl("JURIQUILLA", plantel, ignore.case = TRUE))
demanda_juri <- datos_juriquilla %>%
count(carrera, sort = TRUE)
print("Demanda por carrera en ENES Juriquilla:")
## [1] "Demanda por carrera en ENES Juriquilla:"
print(demanda_juri)
## carrera n
## 1 CIENCIAS DE LA TIERRA 282
## 2 ORTESIS Y PROTESIS 215
## 3 PSICOLOGIA 196
## 4 TECNOLOGIA 146
## 5 INGENIERIA EN COMPUTACION 112
## 6 MATEMATICAS PARA EL DESARROLLO 86
## 7 INGENIERIA EN ENERGIAS RENOVABLES 66
# Tabla del promedio de aciertos por año en cada carrera
resumen_juri <- datos_juriquilla %>%
group_by(carrera, año) %>%
summarise(prom_aciertos = round(mean(aciertos), 1), .groups = 'drop') %>%
pivot_wider(names_from = año, values_from = prom_aciertos)
print("Evolución de promedios de aciertos en Juriquilla:")
## [1] "Evolución de promedios de aciertos en Juriquilla:"
print(resumen_juri, width = Inf)
## # A tibble: 7 × 6
## carrera `2021` `2022` `2023` `2025` `2026`
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 CIENCIAS DE LA TIERRA 70.6 62.9 64 61.8 72
## 2 INGENIERIA EN COMPUTACION NA NA NA NA 74.4
## 3 INGENIERIA EN ENERGIAS RENOVABLES NA NA NA NA 76.6
## 4 MATEMATICAS PARA EL DESARROLLO NA NA NA 73.9 83.8
## 5 ORTESIS Y PROTESIS NA NA NA 55.4 72.8
## 6 PSICOLOGIA NA NA NA NA 68.8
## 7 TECNOLOGIA NA NA NA 64.4 76.2