Analisis de datos PISA en Colombia, Peru, Panama

Análisis del conjunto de datos PISA 2022

Author

Sergio Martinez Vallejo, Andres Camilo Vargas Ramos

Published

October 13, 2026

1 Introducción

1.1 Marco de antecedentes y contexto del conjunto de datos

PISA (Programme for International Student Assessment) es un estudio internacional a gran escala que la Organización para la Cooperación y el Desarrollo Económicos (OCDE) aplica cada tres años desde el año 2000, con el propósito de evaluar en qué medida los estudiantes de 15 años han adquirido los conocimientos y las habilidades esenciales para participar plenamente en la sociedad (OCDE 2023). El estudio evalúa tres competencias principales: lectura, matemáticas y ciencias. Y en cada ciclo una de ellas se toma como dominio principal, mientras las otras dos se evalúan de forma más reducida.

El ciclo de 2022 corresponde a la octava aplicación del estudio y tuvo que posponerse de 2021 a 2022 debido a la pandemia de COVID-19 (OCDE 2023). En esta edición, matemáticas fue el dominio principal de evaluación, tal como ocurrió también en los ciclos de 2003 y 2012 (OCDE 2023). En total, participaron 81 países y economías (OCDE 2023), entre ellos los tres que son objeto de este trabajo: Colombia, Perú y Panamá.

1.2 Información sobre la recolección de los datos

La recolección de los datos de PISA sigue un diseño muestral estratificado en dos etapas. En la primera etapa se seleccionan las escuelas de cada país, con una probabilidad de selección proporcional al número estimado de estudiantes de 15 años matriculados en cada una; en la segunda etapa, se seleccionan estudiantes dentro de las escuelas elegidas mediante un muestreo sistemático (OCDE 2024). Este diseño busca garantizar que la muestra final sea representativa de la población de estudiantes de 15 años de cada país participante, y no solo de un subgrupo particular.

Los estándares técnicos internacionales de PISA exigen, para cada país, un mínimo de 150 escuelas participantes y 6.300 estudiantes evaluados, o la totalidad de la población objetivo cuando esta es menor a esa cifra (OCDE 2024). Además, se exige una tasa de respuesta ponderada de al menos el 80% de los estudiantes muestreados en las escuelas participantes, con el fin de minimizar el sesgo por no respuesta (OCDE 2024).

En cuanto a los instrumentos, los estudiantes no resuelven todos los ítems de la prueba cognitiva ni responden todas las preguntas del cuestionario: se les asigna un bloque de ítems según su desempeño en los bloques anteriores, dentro de un diseño adaptativo de aplicación por computador (OCDE 2023). Adicionalmente, cada estudiante responde un cuestionario de contexto de aproximadamente 35 minutos de duración, que recoge información sobre su entorno familiar, sus actitudes hacia el aprendizaje y sus experiencias escolares (OCDE 2023).

1.3 Justificación de la selección del conjunto de datos

Se eligió la base de datos de PISA 2022 porque reúne, para un mismo estudiante, un conjunto amplio y diverso de variables cuantitativas y cualitativas: puntajes de desempeño académico, características demográficas, condiciones socioeconómicas del hogar, percepciones sobre el entorno escolar y actitudes hacia el aprendizaje, entre otras. Esta diversidad permite poner en práctica las principales herramientas de la estadística descriptiva multivariada vistas en el curso: la descripción univariada de variables de distinta naturaleza, el análisis de relaciones entre variables cualitativas y cuantitativas, y la interpretación de índices compuestos construidos a partir de varias preguntas del cuestionario.

Además, se trata de una base pública, con documentación técnica detallada y de amplio uso en la investigación educativa internacional (OCDE 2024), lo que permite verificar la definición exacta de cada variable y contrastar los resultados de este trabajo con estudios previos, como los revisados en la sección anterior. Su tamaño también es una ventaja: con más de 19.000 estudiantes en los tres países analizados, hay suficientes datos para describir con claridad la forma de las distribuciones y comparar grupos, aunque algunas categorías sean pequeñas.

Se optó por concentrar el análisis en Colombia, Perú y Panamá porque, al ser países de una misma región geográfica y con contextos económicos y sociales cercanos, facilitan la comparación entre sus estudiantes. Además, trabajar con tres países permite delimitar el tamaño de la base de datos, que en su versión completa reúne más de 600.000 estudiantes, y hacerla más manejable para un análisis descriptivo. Por último, la base incluye variables que conectan directamente con los antecedentes revisados, como el nivel socioeconómico (ESCS), los recursos tecnológicos en el hogar (ICTRES) y la ansiedad ante las matemáticas (ANXMAT), lo que permite que este trabajo pueda relacionar estas variables.

2 Revisión de estudios o análisis relacionados

2.1 Primer estudio: Desigualdad de Aprendizajes en América Latina.

Adrogué and Orlicki (2025) analizan la desigualdad de aprendizajes en América Latina, utilizando los datos PISA 2022 únicamente de 7 países: Argentina, Brasil, Chile, Colombia, México, Perú y Uruguay. Las autoras, para medir las desigualdades de aprendizaje, crean un indicador que tiene como objetivo diferenciar a los jóvenes que logran tener los conocimientos necesarios en lengua y matemáticas entre los jóvenes de menor y mayor nivel socioeconómico; además, se calcula para hombres y mujeres de manera separada. Este indicador está construido de esta forma:

\[Indicador\space de \space desigualdad \space de\space aprendizaje =\frac{Porcentaje \space de \space alumnos \space que \space alcanzan \space aprendizajes\space minimos \space entre \space los \space estudiantes \space menos \space vulnerables }{Porcentaje \space de \space alumnos \space que \space alcanzan \space aprendizajes\space minimos \space entre \space los \space estudiantes \space mas \space vulnerables}\] Este indicador está construido para poder comparar las situaciones en los 7 países.

Entre sus hallazgos, destacan que las desigualdades de aprendizaje son mayores en matemáticas que en lengua, que Perú, Colombia y Argentina presentan las brechas más altas, mientras que Chile y Uruguay muestran las más bajas, y que, en matemáticas, la desigualdad por nivel socioeconómico es considerablemente más marcada entre las mujeres que entre los hombres.

Este estudio evidencia la importancia de cruzar el desempeño académico con variables socioeconómicas y de género, algo que se va a explorar en este trabajo.

2.2 Segundo estudio : Habilidades socioemocionales y rendimiento matemático en Uruguay

Mateauda and Valverde (2026) analizan la relación entre habilidades socioemocionales y el rendimiento en matemáticas de los estudiantes uruguayos en PISA 2022, con una muestra analítica de 6.618 estudiantes. Se centran en tres constructos: asertividad, curiosidad y control emocional, medidos mediante índices de Estimación de Verosimilitud Ponderada (WLE), la misma familia de índices utilizada en este trabajo para variables como la autoeficacia matemática o el sentido de pertenencia escolar. Como variable dependiente usan el rendimiento en matemáticas operacionalizado a partir de los diez valores plausibles (PV1MATH a PV10MATH), y como variables de control incluyen el índice de estatus económico, social y cultural (ESCS) y el género.

Los resultados muestran que los estudiantes uruguayos se ubican, en promedio, por debajo del puntaje de referencia de la OCDE tanto en ESCS como en rendimiento matemático, mientras que en curiosidad y asertividad presentan niveles similares o levemente superiores al promedio internacional. Mediante modelos de regresión, los autores encuentran que los tres constructos socioemocionales predicen de forma estadísticamente significativa el rendimiento en matemáticas, siendo la asertividad el predictor más fuerte.

Este estudio sirve como antecedente especialmente para el presente trabajo, ya que utiliza la misma base de datos (PISA 2022), utiliza el mismo tipo de índices WLE que varias de las variables seleccionadas aquí, y evidencia metodológicamente la importancia de controlar por ESCS y género al estudiar el desempeño académico.

2.3 Tercer estudio :Uso de dispositivos digitales en Colombia según PISA 2022

El Laboratorio de Economía de la Educación (LEE) de la Pontificia Universidad Javeriana (2025) analiza, con los microdatos de PISA 2022, el acceso y uso de dispositivos digitales entre los estudiantes colombianos, comparándolos con países de la región y con referentes de alto desempeño como Singapur y Estados Unidos. El informe encuentra que Colombia presenta una cobertura tecnológica limitada: solo el 62% de los estudiantes reporta tener computador en casa (frente a más del 96% en Singapur), apenas el 36,8% tiene acceso a software o aplicaciones educativas, y el 77% vive en hogares con menos de seis dispositivos con pantalla. El celular con acceso a internet es el dispositivo más disponible (79,2%), lo que refleja una tendencia regional de acceso a la tecnología principalmente a través de dispositivos móviles, con limitaciones funcionales frente a un computador para tareas escolares más complejas.

En cuanto al tiempo de uso, el informe identifica que el tiempo dedicado a actividades académicas con dispositivos es bajo en comparación con el tiempo de uso recreativo, y documenta indicadores de bienestar digital preocupantes: solo el 29% de los estudiantes colombianos apaga las notificaciones durante la clase, el 43% mantiene el dispositivo cerca todo o casi todo el tiempo en casa para responder mensajes, y el 7,6% reporta sentirse ansioso cuando no tiene su dispositivo cerca. Los autores concluyen que la relación entre tenencia tecnológica y desempeño académico no es lineal ni determinista, y que el reto va más allá de cerrar la brecha de infraestructura, hacia una inclusión digital que incluya alfabetización crítica y bienestar digital.

Este estudio aborda el acceso de recursos tecnologicos en el hogar de los estudiantes Colombianos, lo mismo que la variable ICTRES que se encuentra en los datos PISA 2022 scholar student

2.4 Cuarto estudio: Informe nacional de resultados para Colombia 2022

El Icfes (2024), en su Informe nacional de resultados para Colombia 2022, presenta el índice de ansiedad matemática construido por la OCDE a partir de seis respuestas de los estudiantes sobre sus sentimientos al estudiar matemáticas, donde valores positivos indican una ansiedad mayor que el promedio de los países de la OCDE. El informe confirma que desde 2012 PISA ha documentado una relación negativa y estadísticamente significativa entre este índice y el desempeño en matemáticas en todos los países participantes, independientemente de las características de los estudiantes o de sus establecimientos educativos.

Para Colombia, el índice de ansiedad matemática resultó ligeramente por debajo del promedio de Latinoamérica (0,55), mientras que el promedio regional se ubicó 0,38 unidades por encima del promedio de la OCDE (0,17). El informe destaca que, en la región, el índice de ansiedad matemática explicó cerca del 31% de la variación en el desempeño de matemáticas, 6 puntos porcentuales más que el 25% reportado para el conjunto de países de PISA 2022. En términos de magnitud, un aumento de una unidad en el índice se asoció con una disminución de 10 puntos en el puntaje de matemáticas en Colombia, frente a una caída de 18 puntos en el promedio de la OCDE y de 11 puntos en el promedio de Latinoamérica.

3 Descripción del conjunto de datos

La base de datos completa de PISA 2022 contiene 1.278 variables, organizadas en los siguientes grandes bloques :

Grupo temático Prefijo / ejemplos Qué contiene
Identificación y diseño muestral CNT, CNTRYID, CNTSCHID, CNTSTUID, STRATUM, SUBNATIO, REGION, OECD, ADMINMODE, BOOKID Códigos de país, escuela y estudiante, estrato muestral, modo de aplicación; no son variables analíticas
Ponderadores (weights) W_FSTUWT, W_FSTURWT1 a W_FSTURWT80, SENWT Pesos muestrales y de replicación usados para estimaciones representativas a nivel poblacional
Antecedentes familiares (ítems crudos) ST250–ST261, ST005, ST006, ST007, ST008 Preguntas individuales sobre educación y ocupación de los padres, posesiones del hogar; insumos de ESCS y HOMEPOS
Trabajo y rutinas del estudiante WORKPAY, WORKHOME, STUDYHMW, EXERPRAC Horas o veces por semana dedicadas a trabajo pagado, trabajo del hogar, tareas y actividad física
Trayectoria y asistencia escolar REPEAT, GRADE, ISCEDP, PROGN, MISSSC, SKIPPING, TARDYSD Repitencia, grado relativo al esperado, programa educativo, inasistencia y puntualidad
Clima escolar y bienestar BELONG, BULLIED, FEELSAFE, SCHRISK, LIFESAT, PSYCHSYM, EUDMO Índices WLE sobre pertenencia, acoso, seguridad y satisfacción con la vida
Actitudes hacia matemáticas (ítems crudos) ST292–ST297 Preguntas individuales sobre ansiedad, motivación y autoeficacia matemática; insumos de ANXMAT, MATHEFF, MATHMOT
Rasgos personales (Big Five) PERSEVAGR, CURIOAGR, COOPAGR, EMPATAGR, ASSERAGR, STRESAGR, EMOCOAGR Índices de perseverancia, curiosidad, cooperación, empatía, asertividad, manejo del estrés y control emocional
Uso y recursos TIC IC170–IC184 (crudas), ICTRES, ICTHOME, ICTSCH, ICTWKDY, ICTWKEND Preguntas sobre uso de dispositivos y el índice resumen de recursos tecnológicos en el hogar y la escuela
Educación financiera (opcional) FL150–FL172 Preguntas del cuestionario opcional de competencia financiera
Nivel socioeconómico ESCS, HISEI, HOMEPOS, MISCED, FISCED, HISCED, PAREDINT, BMMJ1, BFMJ2 Índice compuesto de estatus económico, social y cultural, y sus componentes individuales
Cuestionario de padres (ítems crudos) PA001–PA195 Percepciones parentales sobre la educación del hijo/a; participación y expectativas de los padres
Rendimiento académico PV1MATH–PV10MATH, PV1READ–PV10READ, PV1SCIE–PV10SCIE Diez valores plausibles por dominio evaluado (matemáticas, lectura, ciencias)
Demografía y migración AGE, IMMIG, COBN_S, COBN_M, COBN_F, LANGN Edad, estatus migratorio, país de nacimiento del estudiante y de sus padres, idioma hablado en casa
Expectativas a futuro EXPECEDU, BSMJ, OCOD1–OCOD3 Nivel educativo y ocupación que el estudiante espera alcanzar

De este conjunto, para el presente trabajo se seleccionaron 21 variables (11 cualitativas y 10 cuantitativas), descritas en la tabla a continuación.

3.1 Variables seleccionadas

Table 1: Variables seleccionadas
Nombre de la variable Que mide Escala
CNT Pais del estudiante Nominal
ST004D01T Sexo del estudiante Binaria Nominal
IMMIG Estado migratorio Nominal
REPEAT Repitio algun grado Nominal(binaria)
ISCEDP Niveles de los programas educativos Nominal
LANGN Idioma que se habla en casa Nominal
EXPECEDU Máximo nivel educativo previsto Ordinal
WORKPAY Trabaja por un pago Ordinal
WORKHOME Realizar tareas domésticas o cuidar a familiares antes o después de la escuela. Ordinal
DURECEC Duración de la educación y atención de la primera infancia Ordinal
GRADE Grado relativo al esperado para su edad Ordinal
AGE Edad del estudiante Continua
PV1MATH Desempeño en matemáticas Continua
PV1READ Desempeño en lectura Continua
PV1SCIE Desempeño en ciencias Continua
ESCS Índice de nivel económico, social y cultural Continua
ICTRES Índice de recursos TIC en el hogar Continua
BELONG Sentido de pertenencia Continua
FEELSAFE Percepción de seguridad en la escuela Continua
ANXMAT Ansiedad ante las matemáticas Continua
MATHEFF Autoeficacia matemática Continua

La selección de las variables siguió tres criterios. El primero fue cubrir distintas dimensiones del estudiante sin duplicar información: demografía (CNT, ST004D01T, IMMIG, LANGN, AGE), trayectoria escolar (REPEAT, GRADE, ISCEDP, DURECEC), expectativas (EXPECEDU), trabajo y rutinas (WORKPAY, WORKHOME), nivel socioeconómico (ESCS), recursos tecnológicos (ICTRES), clima escolar (BELONG, FEELSAFE), actitudes hacia las matemáticas (ANXMAT, MATHEFF) y rendimiento académico (PV1MATH, PV1READ, PV1SCIE).

El segundo criterio fue que las variables conectaran con los antecedentes revisados. El nivel socioeconómico (ESCS) y el sexo (ST004D01T) permiten explorar las brechas de aprendizaje que analizan Adrogué and Orlicki (2025), quienes cruzan el desempeño con el nivel socioeconómico y el género. Los índices del estudiante, como ANXMAT, MATHEFF y BELONG, son del mismo tipo (WLE) que las habilidades socioemocionales que Mateauda and Valverde (2026) relacionan con el rendimiento en matemáticas, y permiten ver si en estos tres países se observa un patrón parecido. ICTRES conecta con el estudio del Laboratorio de Economía de la Educación (LEE) (2025) sobre los recursos tecnológicos en los hogares colombianos, y ANXMAT con el informe del Icfes (2024) sobre ansiedad matemática y desempeño. Los puntajes en matemáticas, lectura y ciencias son la variable de resultado de todos esos estudios.

El tercer criterio fue metodológico. Siguiendo la indicación del curso, se usaron variables sintéticas, es decir, índices y puntajes ya calculados (ESCS, ANXMAT, MATHEFF, BELONG, PV1MATH, entre otras), y no las preguntas individuales con las que se construyen, que requieren Teoría de Respuesta al Ítem. Para los puntajes de rendimiento se usó el primer valor de cada área (PV1MATH, PV1READ, PV1SCIE), una simplificación frente al uso de los diez valores. Por último, se descartaron variables redundantes con otras ya incluidas, como OECD (equivalente a CNT en esta muestra) y COBN_S (relacionada con IMMIG), y variables con demasiados datos faltantes, como LIFESAT.

4 Análisis univariado

4.1 CNT - Pais del estudiante

library(dplyr)
library(knitr)
pisa <- read.csv("pisa_filtrado.csv")
tabla_cnt <- pisa %>%
  mutate(País = case_when(
    CNT == "COL" ~ "Colombia",
    CNT == "PER" ~ "Perú",
    CNT == "PAN" ~ "Panamá",
    is.na(CNT)   ~ "Faltantes"
  )) %>%
  count(País, name = "Frecuencia") %>%
  mutate(`Porcentaje (%)` = round(Frecuencia / sum(Frecuencia) * 100, 2))

kable(tabla_cnt, caption = "Distribución de los estudiantes por país")
Distribución de los estudiantes por país
País Frecuencia Porcentaje (%)
Colombia 7804 40.40
Panamá 4544 23.52
Perú 6968 36.07

Como se mencionó en la introducción, para este trabajo se usaron los datos de los estudiantes de PISA 2022 de tres países: Colombia, Perú y Panamá. En la tabla se ve que Colombia es el país con más estudiantes (40,40%), seguido de Perú (36,07%) y Panamá (23,52%). El orden coincide con el tamaño de los países, ya que Colombia es el más grande, aunque las proporciones no siguen exactamente la población: Panamá tiene muchos menos habitantes, pero aporta una parte importante de los estudiantes. Esto se debe a que en PISA cada país evalúa una muestra propia. Por eso, los resultados generales de la base van a reflejar un poco más a Colombia y a Perú que a Panamá.

library(plotly)

resumen_pais <- pisa %>%
  count(CNT)

fig0 <- plot_ly(resumen_pais, labels = ~CNT, values = ~n, type = 'pie',
                marker = list(colors = c('lightblue', 'lightpink', '#66C2A5'),
                              line = list(color = '#030303', width = 1)),
                textinfo = 'label+percent',
                insidetextorientation = 'radial')

fig1 <- fig0 %>% layout(title = "Distribución de estudiantes por país",
                        showlegend = TRUE)
fig1

El gráfico de torta muestra cómo se reparten los estudiantes entre los tres países. Colombia y Perú juntos reúnen poco más de tres cuartas partes de la base (76,47%), mientras que Panamá aporta poco menos de una cuarta parte. Esto quiere decir que los tres países no pesan lo mismo en el análisis, y que los resultados generales van a reflejar más a los estudiantes de Colombia y Perú.

4.2 ST004D01T - Sexo del estudiante

tabla_sexo <- pisa %>%
  mutate(Sexo = case_when(
    ST004D01T == 1 ~ "Mujer",
    ST004D01T == 2 ~ "Hombre",
    is.na(ST004D01T) ~ "Faltantes"
  ),
  Sexo = factor(Sexo, levels = c("Mujer", "Hombre", "Faltantes"))) %>%
  count(Sexo, name = "Frecuencia", .drop = FALSE) %>%
  mutate(`Porcentaje (%)` = round(Frecuencia / sum(Frecuencia) * 100, 2))
kable(tabla_sexo, caption = "Distribución de los estudiantes según sexo")
Distribución de los estudiantes según sexo
Sexo Frecuencia Porcentaje (%)
Mujer 9708 50.26
Hombre 9608 49.74
Faltantes 0 0.00

La variable sexo del estudiante está codificada con dos valores: 1 para mujeres y 2 para hombres. En la tabla se ve que la proporción de mujeres (50.26%) y de hombres (49.74%) es muy parecida, es decir, los dos grupos están bien representados en la base. Además, esta variable no tiene valores faltantes, por lo que se cuenta con la información de todos los estudiantes.

resumen_sexo <- pisa %>%
  mutate(sexo = case_when(
    ST004D01T == 1 ~ "Mujer",
    ST004D01T == 2 ~ "Hombre"
  )) %>%
  count(sexo)
fig2 <- plot_ly(resumen_sexo, labels = ~sexo, values = ~n, type = 'pie',
                marker = list(colors = c('lightblue', 'lightpink'),
                              line = list(color = '#030303', width = 1)),
                textinfo = 'label+percent',
                insidetextorientation = 'radial')

fig2 <- fig2 %>% layout(title = "Distribución por sexo",
                        showlegend = TRUE)
fig2

Como se ve en el gráfico de torta, la proporción de mujeres y hombres es casi igual, las dos porciones tienen un tamaño muy parecido y ninguno de los dos grupos domina sobre el otro.

4.3 IMMIG - Estado migratorio

tabla_immig <- pisa %>%
  mutate(`Estatus migratorio` = case_when(
    IMMIG == 1 ~ "Nativo",
    IMMIG == 2 ~ "Segunda generación",
    IMMIG == 3 ~ "Primera generación",
    is.na(IMMIG) ~ "Faltantes"
  ),
  `Estatus migratorio` = factor(`Estatus migratorio`,
                                levels = c("Nativo", "Segunda generación",
                                           "Primera generación", "Faltantes"))) %>%
  count(`Estatus migratorio`, name = "Frecuencia", .drop = FALSE) %>%
  mutate(`Porcentaje (%)` = round(Frecuencia / sum(Frecuencia) * 100, 2))

kable(tabla_immig, caption = "Distribución de los estudiantes según estatus migratorio")
Distribución de los estudiantes según estatus migratorio
Estatus migratorio Frecuencia Porcentaje (%)
Nativo 17360 89.87
Segunda generación 90 0.47
Primera generación 370 1.92
Faltantes 1496 7.74

Esta variable está codificada con tres valores: 1 para estudiantes nativos, 2 para migrantes de segunda generación(nacieron en el país donde presentaron la prueba, pero sus padres nacieron en el extranjero) y 3 para migrantes de primera generación(Nacieron en otro pais). Como se observa en la tabla, la gran mayoría de los estudiantes son nativos (89,87%), mientras que los migrantes de segunda y primera generación son minorías pequeñas . Además, hay estudiantes sin información de su estado migratorio, que equivalen a un poco más del 7% del total.

immig_plot <- pisa %>%
  filter(!is.na(IMMIG)) %>%
  mutate(IMMIG = case_when(
    IMMIG == 1 ~ "Nativo",
    IMMIG == 2 ~ "Segunda generación",
    IMMIG == 3 ~ "Primera generación"
  )) %>%
  count(IMMIG) %>%
  mutate(porcentaje = round(n / sum(n) * 100, 1))
fig4 <- plot_ly(immig_plot, x = ~IMMIG, y = ~n, type = 'bar',
                text = ~paste0(porcentaje, "%"), textposition = 'outside',
                marker = list(color = 'lightblue',
                              line = list(color = '#030303', width = 1)))
fig4 <- fig4 %>% layout(title = "Distribución por estatus migratorio",
                        xaxis = list(title = "Estatus migratorio",
                                     categoryorder = "array",
                                     categoryarray = c("Nativo", "Segunda generación", "Primera generación")),
                        yaxis = list(title = "Frecuencia absoluta"))
fig4

En el gráfico de barras se ve con claridad que los estudiantes nativos dominan la base, mientras que las barras de segunda y primera generación son tan pequeñas que casi no se distinguen. El cambio de porcentaje en relación con la tabla presentada anteriormente se debe a que en el gráfico se calculó únicamente con los estudiantes de los que se conoce el estado migratorio.

4.4 REPEAT - Repitio algun grado

tabla_repeat <- pisa %>%
  mutate(`Repitió algún grado` = case_when(
    REPEAT == 0 ~ "No repitió",
    REPEAT == 1 ~ "Repitió",
    is.na(REPEAT) ~ "Faltantes"
  ),
  `Repitió algún grado` = factor(`Repitió algún grado`,
                                 levels = c("No repitió", "Repitió", "Faltantes"))) %>%
  count(`Repitió algún grado`, name = "Frecuencia", .drop = FALSE) %>%
  mutate(`Porcentaje (%)` = round(Frecuencia / sum(Frecuencia) * 100, 2))
kable(tabla_repeat, caption = "Distribución de los estudiantes según si han repetido algún grado")
Distribución de los estudiantes según si han repetido algún grado
Repitió algún grado Frecuencia Porcentaje (%)
No repitió 13672 70.78
Repitió 4692 24.29
Faltantes 952 4.93

Esta variable es binaria: el valor 0 indica que el estudiante nunca ha repetido un grado, y el valor 1 que ha repetido al menos uno. Como se ve en la tabla, el 70,78% de los estudiantes nunca ha repetido un grado y el 24,29% ha repetido al menos uno. Además, el 4,93% de los estudiantes no tiene información en esta variable.

repitio <- pisa %>%
  mutate(REPEAT = case_when(
    REPEAT == 1 ~ "Repitió",
    REPEAT == 0 ~ "No repitió",
    is.na(REPEAT) ~ "Faltantes"
  )) %>%
  count(REPEAT) %>%
  mutate(porcentaje = round(n / sum(n) * 100, 2),
         REPEAT = factor(REPEAT, levels = c("No repitió", "Repitió", "Faltantes"))) %>%
  arrange(REPEAT)
fig444 <- plot_ly(repitio, labels = ~REPEAT, values = ~n, type = 'pie',
                  sort = FALSE,
                  marker = list(colors = c('lightblue', 'lightpink', '#BDBDBD'),
                                line = list(color = '#030303', width = 1)),
                  textinfo = 'label+percent',
                  insidetextorientation = 'radial') %>%
  layout(title = "Estudiantes que han repetido algún grado")

fig444

El gráfico de torta confirma lo que se veía en la tabla, cerca de una cuarta parte de los estudiantes (24,29%) ha repetido al menos un grado. El resto de la torta se reparte entre quienes nunca han repetido, que son la gran mayoría (70,78%), y los datos faltantes, que ocupan una porción muy pequeña (4,93%).

4.5 ISCEDP - Niveles de los programas educativos

descr <- data.frame(
  Código = c("244", "254", "341", "343", "344", "354", "453", "Faltantes"),
  Descripción = c("Secundaria baja, general, con acceso directo a secundaria alta",
                  "Secundaria baja, vocacional, con acceso directo a secundaria alta",
                  "Secundaria alta, general, nivel incompleto",
                  "Secundaria alta, general, completo, sin acceso directo a terciaria",
                  "Secundaria alta, general, completo, con acceso directo a terciaria",
                  "Secundaria alta, vocacional, completo, con acceso directo a terciaria",
                  "Postsecundaria no terciaria, vocacional, completo, sin acceso directo a terciaria",
                  "Sin información"))
tabla_isced <- pisa %>%
  mutate(Código = ifelse(is.na(ISCEDP), "Faltantes", as.character(ISCEDP)),
         Código = factor(Código, levels = descr$Código)) %>%
  count(Código, name = "Frecuencia", .drop = FALSE) %>%
  mutate(Código = as.character(Código)) %>%
  left_join(descr, by = "Código") %>%
  mutate(`Porcentaje (%)` = round(Frecuencia / sum(Frecuencia) * 100, 2)) %>%
  select(Código, Descripción, Frecuencia, `Porcentaje (%)`)
kable(tabla_isced, caption = "Distribución de los estudiantes según el nivel del programa educativo (ISCED)")
Distribución de los estudiantes según el nivel del programa educativo (ISCED)
Código Descripción Frecuencia Porcentaje (%)
244 Secundaria baja, general, con acceso directo a secundaria alta 5326 27.57
254 Secundaria baja, vocacional, con acceso directo a secundaria alta 8 0.04
341 Secundaria alta, general, nivel incompleto 0 0.00
343 Secundaria alta, general, completo, sin acceso directo a terciaria 0 0.00
344 Secundaria alta, general, completo, con acceso directo a terciaria 12732 65.91
354 Secundaria alta, vocacional, completo, con acceso directo a terciaria 1250 6.47
453 Postsecundaria no terciaria, vocacional, completo, sin acceso directo a terciaria 0 0.00
Faltantes Sin información 0 0.00

Esta variable indica el nivel del programa educativo en el que está inscrito el estudiante. En la tabla se ve que la gran mayoría cursa dos programas: el 65,91% está en secundaria alta general con acceso directo a educación terciaria, y el 27,57% en secundaria baja general. El 6,47% cursa secundaria alta vocacional, y solo 8 estudiantes (0,04%) están en secundaria baja vocacional. Los demás programas no aparecen en los tres países de este trabajo, y la variable no tiene valores faltantes.

isced_graf <- tabla_isced %>%
  filter(Código != "Faltantes") %>%
  mutate(porcentaje = round(Frecuencia / sum(Frecuencia) * 100, 1))

fig_isced <- plot_ly(isced_graf, x = ~Código, y = ~Frecuencia, type = 'bar',
                     text = ~paste0(porcentaje, "%"), textposition = 'outside',
                     marker = list(color = 'lightblue',
                                   line = list(color = '#030303', width = 1))) %>%
  layout(title = "Distribución por programa educativo (ISCED)",
         xaxis = list(title = "Código ISCED del programa", type = "category",
                      categoryorder = "array", categoryarray = isced_graf$Código),
         yaxis = list(title = "Frecuencia absoluta",
                      range = c(0, max(isced_graf$Frecuencia) * 1.12)),
         margin = list(l = 80, b = 80, t = 100))
fig_isced

El gráfico de barras muestra que la distribución está muy concentrada en dos programas: el 344 (65,9%), que corresponde a secundaria alta general, y el 244 (27,6%), que corresponde a secundaria baja general. La barra del 354, secundaria alta vocacional, es bastante más pequeña (6,5%), y el resto de los programas casi no se ven. Esto indica que los estudiantes de los tres países se reparten entre estos tres programas.

4.6 LANGN - Idioma que se habla en casa del estudiante

tabla_langn <- pisa %>%
  mutate(`Idioma en casa` = case_when(
    LANGN == 156 ~ "Español",
    LANGN == 313 ~ "Inglés",
    LANGN == 358 ~ "Quechua",
    LANGN == 561 ~ "Ngäbe",
    LANGN == 999 | is.na(LANGN) ~ "Faltantes",
    TRUE ~ "Otros idiomas"
  ),
  `Idioma en casa` = factor(`Idioma en casa`,
                            levels = c("Español", "Inglés", "Quechua", "Ngäbe",
                                       "Otros idiomas", "Faltantes"))) %>%
  count(`Idioma en casa`, name = "Frecuencia", .drop = FALSE) %>%
  mutate(`Porcentaje (%)` = round(Frecuencia / sum(Frecuencia) * 100, 2))
kable(tabla_langn, caption = "Distribución de los estudiantes según el idioma que hablan en casa")  
Distribución de los estudiantes según el idioma que hablan en casa
Idioma en casa Frecuencia Porcentaje (%)
Español 17612 91.18
Inglés 187 0.97
Quechua 220 1.14
Ngäbe 171 0.89
Otros idiomas 309 1.60
Faltantes 817 4.23

Los tres países seleccionados para este trabajo tienen el español como idioma oficial, y es también el idioma que más hablan en casa los estudiantes que presentaron la prueba (91,18%). Le siguen, con porcentajes menores, el quechua (1,14%), el inglés (0,97%) y el ngäbe (0,89%), y un 1,6% habla otros idiomas. El quechua y el ngäbe son lenguas de comunidades indígenas que viven en estos países. Además, el 4,23% de los estudiantes no tiene información sobre el idioma que habla en casa.

langn_tabla <- pisa %>%
  mutate(LANGN = case_when(
    LANGN == 156 ~ "Español",
    LANGN == 313 ~ "Inglés",
    LANGN == 358 ~ "Quechua",
    LANGN == 561 ~ "Ngäbe",
    LANGN == 999 | is.na(LANGN) ~ "Faltantes",
    TRUE ~ "Otros idiomas"
  )) %>%
  count(LANGN) %>%
  mutate(porcentaje = round(n / sum(n) * 100, 1))
langn_graf <- langn_tabla %>%
  filter(LANGN != "Faltantes") %>%
  mutate(porcentaje = round(n / sum(n) * 100, 1),
         LANGN = factor(LANGN, levels = c("Español", "Inglés", "Quechua", "Ngäbe", "Otros idiomas"))) %>%
  arrange(LANGN)
fig5 <- plot_ly(langn_graf, x = ~LANGN, y = ~n, type = 'bar',
                text = ~paste0(porcentaje, "%"), textposition = 'outside',
                marker = list(color = 'lightblue',
                              line = list(color = '#030303', width = 1))) %>%
  layout(title = "Idioma que habla el estudiante en casa",
         xaxis = list(title = "Idioma"),
         yaxis = list(title = "Frecuencia absoluta"))
fig5

En el gráfico se ve con más claridad la diferencia de tamaño entre el español y el resto de los idiomas: la barra del español es tan alta que las otras cuatro casi no se distinguen entre sí. Esto quiere decir que los grupos que hablan otro idioma en casa son muy pequeños.

4.7 EXPECEDU - Máximo nivel educativo previsto

library(dplyr)
library(knitr)

niveles <- c("Menos de ISCED 2", "ISCED 2", "ISCED 3.3", "ISCED 3.4",
             "ISCED 4", "ISCED 5", "ISCED 6", "ISCED 7", "ISCED 8")

descr <- data.frame(
  `Nivel esperado` = c(niveles, "Faltantes"),
  Descripción = c("Menos que secundaria baja", "Secundaria baja",
                  "Secundaria alta (sin acceso directo a terciaria)",
                  "Secundaria alta (con acceso directo a terciaria)",
                  "Postsecundaria no terciaria", "Terciaria de ciclo corto",
                  "Pregrado o equivalente", "Maestría o equivalente",
                  "Doctorado o equivalente", "Sin información"),
  check.names = FALSE
)

tabla_expec <- pisa %>%
  mutate(`Nivel esperado` = ifelse(is.na(EXPECEDU), "Faltantes",
                                   niveles[as.numeric(EXPECEDU)]),
         `Nivel esperado` = factor(`Nivel esperado`,
                                   levels = c(niveles, "Faltantes"))) %>%
  count(`Nivel esperado`, name = "Frecuencia", .drop = FALSE) %>%
  mutate(`Porcentaje (%)` = round(Frecuencia / sum(Frecuencia) * 100, 2)) %>%
  filter(Frecuencia > 0 | `Nivel esperado` == "Faltantes") %>%
  mutate(`Nivel esperado` = as.character(`Nivel esperado`)) %>%
  left_join(descr, by = "Nivel esperado") %>%
  select(`Nivel esperado`, Descripción, Frecuencia, `Porcentaje (%)`)

kable(tabla_expec, caption = "Distribución de los estudiantes según el nivel educativo que esperan alcanzar")
Distribución de los estudiantes según el nivel educativo que esperan alcanzar
Nivel esperado Descripción Frecuencia Porcentaje (%)
ISCED 2 Secundaria baja 268 1.39
ISCED 3.3 Secundaria alta (sin acceso directo a terciaria) 221 1.14
ISCED 3.4 Secundaria alta (con acceso directo a terciaria) 550 2.85
ISCED 4 Postsecundaria no terciaria 237 1.23
ISCED 5 Terciaria de ciclo corto 494 2.56
ISCED 6 Pregrado o equivalente 1820 9.42
ISCED 7 Maestría o equivalente 1507 7.80
ISCED 8 Doctorado o equivalente 6542 33.87
Faltantes Sin información 7677 39.74

Llama la atención la cantidad de datos faltantes, el 39,74% de los estudiantes no respondió esta pregunta, el porcentaje más alto de todas las variables analizadas. Por eso, los resultados describen solo a quienes sí respondieron y no se pueden extender al resto. Aun contando a los faltantes, el nivel más frecuente es ISCED 8 (doctorado o equivalente), con el 33,87% de todos los estudiantes. Ninguno eligió la opción “menos de ISCED 2”.

expec_graf <- tabla_expec %>%
  filter(`Nivel esperado` != "Faltantes") %>%
  mutate(porcentaje = round(Frecuencia / sum(Frecuencia) * 100, 1))
fig7 <- plot_ly(expec_graf, x = ~`Nivel esperado`, y = ~Frecuencia, type = 'bar',
                text = ~paste0(porcentaje, "%"), textposition = 'outside',
                marker = list(color = 'lightblue',
                              line = list(color = '#030303', width = 1))) %>%
  layout(title = "Nivel educativo máximo que espera alcanzar",
         xaxis = list(title = "Nivel educativo (ISCED)", tickangle = -30,
                      categoryorder = "array",
                      categoryarray = as.character(expec_graf$`Nivel esperado`)),
         yaxis = list(title = "Frecuencia absoluta",
                      range = c(0, max(expec_graf$Frecuencia) * 1.12)),
         margin = list(l = 80, b = 100, t = 100))
fig7

El gráfico, que excluye a los estudiantes sin respuesta, muestra que más de la mitad de quienes respondieron (56,2%) espera llegar a un doctorado. Sumando también a quienes esperan un pregrado (15,6%) o una maestría (12,9%), cerca del 85% aspira a un nivel universitario o superior, mientras que los niveles anteriores (de secundaria a terciaria de ciclo corto) tienen poco peso.

4.8 WORKPAY- Trabajo por un pago

tabla_workpay <- pisa %>%
  mutate(`Veces por semana` = case_when(
    is.na(WORKPAY) ~ "Faltantes",
    WORKPAY == 10  ~ "10 o más",
    TRUE           ~ as.character(WORKPAY)
  ),
  `Veces por semana` = factor(`Veces por semana`,
                              levels = c(as.character(0:9), "10 o más", "Faltantes"))) %>%
  count(`Veces por semana`, name = "Frecuencia", .drop = FALSE) %>%
  mutate(`Porcentaje (%)` = round(Frecuencia / sum(Frecuencia) * 100, 2))
kable(tabla_workpay, caption = "Distribución de los estudiantes según las veces por semana que trabajan por un pago")
Distribución de los estudiantes según las veces por semana que trabajan por un pago
Veces por semana Frecuencia Porcentaje (%)
0 7788 40.32
1 874 4.52
2 1752 9.07
3 791 4.10
4 1338 6.93
5 1026 5.31
6 943 4.88
7 474 2.45
8 655 3.39
9 279 1.44
10 o más 1461 7.56
Faltantes 1935 10.02

Esta variable indica cuántas veces por semana el estudiante trabaja por un pago antes o después de la escuela. En la tabla se ve que el 40,32% de los estudiantes no trabaja nunca por un pago. Entre los que trabajan, la frecuencia más común es 2 veces por semana (9,07%). El 7,56% reporta 10 o más veces por semana, que es la categoría más alta de la escala y agrupa a todos los que trabajan 10 veces o más. Además, el 10,02% de los estudiantes no tiene información en esta variable.

w_graf <- tabla_workpay %>%
  filter(`Veces por semana` != "Faltantes") %>%
  mutate(porcentaje = round(Frecuencia / sum(Frecuencia) * 100, 1))
fig8 <- plot_ly(w_graf, x = ~`Veces por semana`, y = ~Frecuencia, type = 'bar',
                text = ~paste0(porcentaje, "%"), textposition = 'outside',
                marker = list(color = 'lightblue',
                              line = list(color = '#030303', width = 1))) %>%
  layout(title = "Veces por semana que el estudiante trabaja por un pago",
         xaxis = list(title = "Veces por semana", type = "category",
                      categoryorder = "array",
                      categoryarray = as.character(w_graf$`Veces por semana`)),
         yaxis = list(title = "Frecuencia absoluta",
                      range = c(0, max(w_graf$Frecuencia) * 1.12)),
         margin = list(l = 80, b = 80, t = 100))
fig8

El gráfico, que no incluye a los estudiantes sin información, muestra que la distribución es asimétrica hacia la derecha, la barra más alta es la de quienes no trabajan (44,8%), y luego las frecuencias van bajando, con una pequeña acumulación al final por la categoría “10 o más”. Esto significa que, entre los estudiantes con datos, un poco más de la mitad (55,2%) trabaja por un pago al menos una vez por semana.

4.9 WORKHOME - Realizar tareas domésticas o cuidar a familiares antes o después de la escuela.

tabla_workhome <- pisa %>%
  mutate(`Veces por semana` = case_when(
    is.na(WORKHOME) ~ "Faltantes",
    WORKHOME == 10  ~ "10 o más",
    TRUE            ~ as.character(WORKHOME)
  ),
  `Veces por semana` = factor(`Veces por semana`,
                              levels = c(as.character(0:9), "10 o más", "Faltantes"))) %>%
  count(`Veces por semana`, name = "Frecuencia", .drop = FALSE) %>%
  mutate(`Porcentaje (%)` = round(Frecuencia / sum(Frecuencia) * 100, 2))
kable(tabla_workhome,
      caption = "Distribución de los estudiantes según las veces por semana que trabajan en el hogar o cuidan familiares")
Distribución de los estudiantes según las veces por semana que trabajan en el hogar o cuidan familiares
Veces por semana Frecuencia Porcentaje (%)
0 1984 10.27
1 637 3.30
2 1439 7.45
3 971 5.03
4 1542 7.98
5 1684 8.72
6 1547 8.01
7 813 4.21
8 1341 6.94
9 690 3.57
10 o más 5018 25.98
Faltantes 1650 8.54
wh_graf <- tabla_workhome %>%
  filter(`Veces por semana` != "Faltantes") %>%
  mutate(porcentaje = round(Frecuencia / sum(Frecuencia) * 100, 1))
fig9 <- plot_ly(wh_graf, x = ~`Veces por semana`, y = ~Frecuencia, type = 'bar',
                text = ~paste0(porcentaje, "%"), textposition = 'outside',
                marker = list(color = 'lightblue',
                              line = list(color = '#030303', width = 1))) %>%
  layout(title = "Veces por semana que el estudiante trabaja en el hogar o cuida familiares",
         xaxis = list(title = "Veces por semana", type = "category",
                      categoryorder = "array",
                      categoryarray = as.character(wh_graf$`Veces por semana`)),
         yaxis = list(title = "Frecuencia absoluta",
                      range = c(0, max(wh_graf$Frecuencia) * 1.12)),
         margin = list(l = 80, b = 80, t = 100))
fig9

4.10 DURECEC - Duración de la educación y atención de la primera infancia

niveles_ecec <- c("Menos de 1 año", "1 a <2 años", "2 a <3 años", "3 a <4 años",
                  "4 a <5 años", "5 a <6 años", "6 a <7 años", "7 a <8 años",
                  "8 años o más")
tabla_durecec <- pisa %>%
  mutate(`Duración` = ifelse(is.na(DURECEC), "Faltantes",
                             niveles_ecec[as.numeric(DURECEC) + 1]),
         `Duración` = factor(`Duración`, levels = c(niveles_ecec, "Faltantes"))) %>%
  count(`Duración`, name = "Frecuencia", .drop = FALSE) %>%
  mutate(`Porcentaje (%)` = round(Frecuencia / sum(Frecuencia) * 100, 2))
kable(tabla_durecec, caption = "Distribución de los estudiantes según la duración de la educación en la primera infancia")
Distribución de los estudiantes según la duración de la educación en la primera infancia
Duración Frecuencia Porcentaje (%)
Menos de 1 año 853 4.42
1 a <2 años 5019 25.98
2 a <3 años 3625 18.77
3 a <4 años 3888 20.13
4 a <5 años 1442 7.47
5 a <6 años 360 1.86
6 a <7 años 112 0.58
7 a <8 años 18 0.09
8 años o más 8 0.04
Faltantes 3991 20.66

Esta variable indica cuántos años asistió el estudiante a educación en la primera infancia. El 20,66% de los estudiantes no tiene información. Entre quienes sí respondieron, la mayoría se concentra en duraciones cortas o medias: “1 a menos de 2 años” es la más frecuente (25,98%), seguida de “3 a menos de 4 años” (20,13%) y “2 a menos de 3 años” (18,77%). Muy pocos estudiantes asistieron 6 años o más, con porcentajes por debajo del 1%.

durecec_graf <- tabla_durecec %>%
  filter(`Duración` != "Faltantes") %>%
  mutate(porcentaje = round(Frecuencia / sum(Frecuencia) * 100, 1))
fig10 <- plot_ly(durecec_graf, x = ~`Duración`, y = ~Frecuencia, type = 'bar',
                 text = ~paste0(porcentaje, "%"), textposition = 'outside',
                 marker = list(color = 'lightblue',
                               line = list(color = '#030303', width = 1))) %>%
  layout(title = "Duración de la educación en la primera infancia",
         xaxis = list(title = "Años de asistencia (ECEC)", tickangle = -30,
                      categoryorder = "array",
                      categoryarray = as.character(durecec_graf$`Duración`)),
         yaxis = list(title = "Frecuencia absoluta",
                      range = c(0, max(durecec_graf$Frecuencia) * 1.12)),
         margin = list(l = 80, b = 100, t = 100))
fig10

El gráfico, que no incluye a los estudiantes sin información, muestra una distribución concentrada en las duraciones cortas: casi tres cuartas partes de los estudiantes con dato (82%) asistieron entre 1 y menos de 4 años. A partir de 5 años, la frecuencia baja mucho, y las últimas tres categorías juntas no llegan al 1%.

4.11 AGE - Edad del estudiante

library(e1071)

Attaching package: 'e1071'
The following object is masked from 'package:ggplot2':

    element
x <- pisa$AGE

tabla_age <- data.frame(
  Medida = c("Faltantes", "Mínimo", "Q1", "Mediana", "Media", "Q3", "Máximo",
             "IQR", "Desviación estándar", "CV (%)", "Asimetría", "Curtosis"),
  Valor = c(sum(is.na(x)),
            min(x, na.rm = TRUE),
            quantile(x, 0.25, na.rm = TRUE),
            median(x, na.rm = TRUE),
            mean(x, na.rm = TRUE),
            quantile(x, 0.75, na.rm = TRUE),
            max(x, na.rm = TRUE),
            IQR(x, na.rm = TRUE),
            sd(x, na.rm = TRUE),
            sd(x, na.rm = TRUE) / mean(x, na.rm = TRUE) * 100,
            skewness(x, na.rm = TRUE),
            kurtosis(x, na.rm = TRUE))
) %>%
  mutate(Valor = round(Valor, 3))

kable(tabla_age, caption = "Medidas resumen de la edad de los estudiantes")
Medidas resumen de la edad de los estudiantes
Medida Valor
Faltantes 0.000
Mínimo 15.170
Q1 15.580
Mediana 15.830
Media 15.851
Q3 16.080
Máximo 16.420
IQR 0.500
Desviación estándar 0.285
CV (%) 1.796
Asimetría 0.074
Curtosis -1.160

La tabla muestra que la edad de los estudiantes va de 15,17 a 16,42 años, con una media de 15,85 y una mediana de 15,83, valores cercanos entre sí. La desviación estándar es pequeña (0,285) y el coeficiente de variación apenas llega al 1,8%, lo que indica poca dispersión. Los estudiantes están concentrados en un rango de edad muy reducido, algo esperable porque PISA evalúa a jóvenes de 15 años. La asimetría (0,074) está muy cerca de 0, así que la distribución es prácticamente simétrica. La curtosis es negativa (-1,160), lo que señala una distribución más aplanada que la normal.

fig12 <- plot_ly(pisa, x = ~AGE, type = 'box', name = "Edad",
                 marker = list(color = 'lightblue'),
                 line = list(color = '#030303'),
                 fillcolor = 'rgba(44,127,184,0.5)') %>%
  layout(title = "Boxplot edad",
         xaxis = list(title = "Edad (años)"),
         yaxis = list(showticklabels = FALSE),
         margin = list(l = 40, b = 80, t = 80))
fig12

El diagrama de caja confirma la simetría: la mediana divide la caja casi por la mitad, y los dos bigotes tienen una longitud parecida (de 15,17 a 15,58, y de 16,08 a 16,42). No se observan valores atípicos, es decir, ningún estudiante queda fuera de este rango de edad esperado.

inicio <- floor(min(pisa$AGE, na.rm = TRUE) * 10) / 10
fin    <- ceiling(max(pisa$AGE, na.rm = TRUE) * 10) / 10
fig11 <- plot_ly(pisa, x = ~AGE, type = 'histogram',
                 xbins = list(start = inicio, end = fin, size = 0.1),
                 marker = list(color = 'lightblue',
                               line = list(color = '#030303', width = 1))) %>%
  layout(title = "Distribución de la edad de los estudiantes",
         xaxis = list(title = "Edad (años)",
                      tickmode = "linear", tick0 = inicio, dtick = 0.1,
                      tickangle = -45),
         yaxis = list(title = "Frecuencia absoluta"),
         margin = list(l = 80, b = 90, t = 80))
fig11

El histograma confirma que hay dos picos separadados uno alrededor de 15,5 años y otro alrededor de 16 año. Ademas, los datos no se concentran en un solo punto central.

4.12 GRADE - Grado relativo al esperado para su edad

niveles_grade <- c("3 grados por debajo", "2 grados por debajo",
                   "1 grado por debajo", "Grado de referencia",
                   "1 grado por encima")

tabla_grade <- pisa %>%
  mutate(`Grado relativo` = ifelse(is.na(GRADE), "Faltantes",
                                   niveles_grade[as.numeric(GRADE) + 4]),
         `Grado relativo` = factor(`Grado relativo`,
                                   levels = c(niveles_grade, "Faltantes"))) %>%
  count(`Grado relativo`, name = "Frecuencia", .drop = FALSE) %>%
  mutate(`Porcentaje (%)` = round(Frecuencia / sum(Frecuencia) * 100, 2))

kable(tabla_grade, caption = "Distribución de los estudiantes según el grado que cursan respecto al grado de referencia de su país")
Distribución de los estudiantes según el grado que cursan respecto al grado de referencia de su país
Grado relativo Frecuencia Porcentaje (%)
3 grados por debajo 448 2.32
2 grados por debajo 1273 6.59
1 grado por debajo 3605 18.66
Grado de referencia 11712 60.63
1 grado por encima 2270 11.75
Faltantes 8 0.04
grade_graf <- tabla_grade %>%
  filter(`Grado relativo` != "Faltantes") %>%
  mutate(porcentaje = round(Frecuencia / sum(Frecuencia) * 100, 1))
fig_grade <- plot_ly(grade_graf, x = ~`Grado relativo`, y = ~Frecuencia, type = 'bar',
                     text = ~paste0(porcentaje, "%"), textposition = 'outside',
                     marker = list(color = 'lightblue',
                                   line = list(color = '#030303', width = 1))) %>%
  layout(title = "Grado que cursa el estudiante respecto al grado de referencia",
         xaxis = list(title = "Grado relativo", tickangle = -20,
                      categoryorder = "array",
                      categoryarray = as.character(grade_graf$`Grado relativo`)),
         yaxis = list(title = "Frecuencia absoluta",
                      range = c(0, max(grade_graf$Frecuencia) * 1.12)),
         margin = list(l = 80, b = 100, t = 100))
fig_grade

Esta variable compara el grado que cursa cada estudiante con el grado de referencia de su país. La categoría más frecuente es, por mucho, “Grado de referencia”, con el 60,7% de los estudiantes, seguida de “1 grado por debajo” 18,7%. El resto se reparte en las categorías extremas: el 11,8% está un grado por encima de la referencia, y el 8,9% restante está dos o tres grados por debajo (6,6% y 2,3%, respectivamente).La variable tiene muy pocos datos faltantes 0,04%.

4.13 PV1MATH - Desempeño en matemáticas

x <- pisa$PV1MATH

tabla_math <- data.frame(
  Medida = c("Faltantes", "Mínimo", "Q1", "Mediana", "Media", "Q3", "Máximo",
             "IQR", "Desviación estándar", "CV (%)", "Asimetría", "Curtosis"),
  Valor = c(sum(is.na(x)),
            min(x, na.rm = TRUE),
            quantile(x, 0.25, na.rm = TRUE),
            median(x, na.rm = TRUE),
            mean(x, na.rm = TRUE),
            quantile(x, 0.75, na.rm = TRUE),
            max(x, na.rm = TRUE),
            IQR(x, na.rm = TRUE),
            sd(x, na.rm = TRUE),
            sd(x, na.rm = TRUE) / mean(x, na.rm = TRUE) * 100,
            skewness(x, na.rm = TRUE),
            kurtosis(x, na.rm = TRUE))
) %>%
  mutate(Valor = round(Valor, 2))

kable(tabla_math, caption = "Medidas resumen del puntaje en matemáticas (PV1MATH)")
Medidas resumen del puntaje en matemáticas (PV1MATH)
Medida Valor
Faltantes 0.00
Mínimo 162.19
Q1 329.80
Mediana 376.51
Media 383.28
Q3 430.95
Máximo 727.58
IQR 101.15
Desviación estándar 74.44
CV (%) 19.42
Asimetría 0.41
Curtosis 0.04

El puntaje en matemáticas de los estudiantes va de 162,19 a 727,58 puntos, con una media de 383,28 y una mediana de 376,51. Como la media es un poco mayor que la mediana, hay una leve asimetría hacia la derecha, lo que confirma el valor de asimetría (0,41).El coeficiente de variación es 19,42%, y esta variable no tiene ningún dato faltante.

fig15 <- plot_ly(pisa, x = ~PV1MATH, type = 'box', name = "MATEMATICAS",
                 marker = list(color = 'lightblue'),
                 line = list(color = '#030303'),
                 fillcolor = 'rgba(44,127,184,0.5)') %>%
  layout(title = "Boxplot puntaje de matematicas",
         xaxis = list(title = "Puntaje de matematicas"),
         yaxis = list(showticklabels = FALSE),
         margin = list(l = 40, b = 80, t = 80))
fig15

El diagrama de caja muestra la mitad central de los estudiantes entre 329,80 y 430,95 puntos (el rango intercuartílico), con la mediana un poco más cerca del primer cuartil que del tercero. Se observan varios valores atípicos por encima del bigote superior, alrededor de 580 puntos en adelante, y uno por debajo del bigote inferior, cerca de 170. Con casi 19,000 estudiantes, es esperable encontrar algunos casos con puntajes muy altos o muy bajos

fig16 <- plot_ly(pisa, x = ~PV1MATH, type = 'histogram',
                 xbins = list(size = 25),
                 marker = list(color = 'lightblue',
                               line = list(color = '#030303', width = 1))) %>%
  layout(title = "Distribución del puntaje en matemáticas",
         xaxis = list(title = "Puntaje en matemáticas (PV1MATH)"),
         yaxis = list(title = "Frecuencia absoluta"),
         margin = list(l = 80, b = 80, t = 80))
fig16

El histograma confirma el pico alrededor de 350 a 400 puntos, y muestra con más claridad la cola larga hacia la derecha que ya se veía en el boxplot

4.14 PV1READ - Desempeño en lectura

x <- pisa$PV1READ
tabla_read <- data.frame(
  Medida = c("Faltantes", "Mínimo", "Q1", "Mediana", "Media", "Q3", "Máximo",
             "IQR", "Desviación estándar", "CV (%)", "Asimetría", "Curtosis"),
  Valor = c(sum(is.na(x)),
            min(x, na.rm = TRUE),
            quantile(x, 0.25, na.rm = TRUE),
            median(x, na.rm = TRUE),
            mean(x, na.rm = TRUE),
            quantile(x, 0.75, na.rm = TRUE),
            max(x, na.rm = TRUE),
            IQR(x, na.rm = TRUE),
            sd(x, na.rm = TRUE),
            sd(x, na.rm = TRUE) / mean(x, na.rm = TRUE) * 100,
            skewness(x, na.rm = TRUE),
            kurtosis(x, na.rm = TRUE))
) %>%
  mutate(Valor = round(Valor, 2))

kable(tabla_read, caption = "Medidas resumen del puntaje en lectura (PV1READ)")
Medidas resumen del puntaje en lectura (PV1READ)
Medida Valor
Faltantes 0.00
Mínimo 73.00
Q1 341.72
Mediana 405.03
Media 408.39
Q3 472.09
Máximo 756.02
IQR 130.37
Desviación estándar 92.97
CV (%) 22.77
Asimetría 0.14
Curtosis -0.26

El puntaje en lectura va de 73 a 756,02 puntos, con una media de 408,39 y una mediana de 405,03, valores muy cercanos entre sí. La asimetría 0,14 y la curtosis -0,26 están cerca de 0, lo que indica una distribución casi simétrica y de forma similar a la normal. El coeficiente de variación es 22,77%, y no hay datos faltantes.

fig17 <- plot_ly(pisa, x = ~PV1READ, type = 'box', name = "lectura",
                 marker = list(color = 'lightblue'),
                 line = list(color = '#030303'),
                 fillcolor = 'rgba(44,127,184,0.5)') %>%
  layout(title = "Boxplot puntaje de lectura",
         xaxis = list(title = "Puntaje de lectura"),
         yaxis = list(showticklabels = FALSE),
         margin = list(l = 40, b = 80, t = 80))
fig17

El diagrama de caja muestra que la mitad central de los estudiantes se ubica entre 341,72 y 472,09 puntos, con la mediana prácticamente en el centro de la caja, lo que confirma la simetría vista en la tabla. Hay algunos valores atípicos en ambos extremos, tanto por debajo de 150 como por encima de 660 puntos, un poco más en el extremo superior.

gg <- ggplot(pisa, aes(x = PV1READ)) +
  geom_histogram(aes(y = after_stat(density)), binwidth = 25,
                 fill = "lightblue", color = "#030303", alpha = 0.7) +
  geom_density(color = "#030303", linewidth = 1) +
  labs(x = "Puntaje en lectura (PV1READ)", y = "Densidad")
fig18 <- ggplotly(gg) %>%
  layout(title = "Distribución del puntaje en lectura",
         plot_bgcolor = grey(0.95),
         margin = list(l = 80, b = 80, t = 80))
fig18

El histograma muestra un pico cerca de 400 puntos, y una forma acampanada bastante simétrica, sin colas marcadamente más largas hacia ningún lado. Esto coincide con la asimetría y la curtosis cercanas a 0 de la tabla.

4.15 PV1SCIE - Desempeño en ciencias

x <- pisa$PV1SCIE
tabla_scie <- data.frame(
  Medida = c("Faltantes", "Mínimo", "Q1", "Mediana", "Media", "Q3", "Máximo",
             "IQR", "Desviación estándar", "CV (%)", "Asimetría", "Curtosis"),
  Valor = c(sum(is.na(x)),
            min(x, na.rm = TRUE),
            quantile(x, 0.25, na.rm = TRUE),
            median(x, na.rm = TRUE),
            mean(x, na.rm = TRUE),
            quantile(x, 0.75, na.rm = TRUE),
            max(x, na.rm = TRUE),
            IQR(x, na.rm = TRUE),
            sd(x, na.rm = TRUE),
            sd(x, na.rm = TRUE) / mean(x, na.rm = TRUE) * 100,
            skewness(x, na.rm = TRUE),
            kurtosis(x, na.rm = TRUE))
) %>%
  mutate(Valor = round(Valor, 2))
kable(tabla_scie, caption = "Medidas resumen del puntaje en ciencias (PV1SCIE)")
Medidas resumen del puntaje en ciencias (PV1SCIE)
Medida Valor
Faltantes 0.00
Mínimo 124.04
Q1 346.42
Mediana 403.88
Media 408.86
Q3 467.69
Máximo 761.87
IQR 121.26
Desviación estándar 87.54
CV (%) 21.41
Asimetría 0.25
Curtosis -0.11

El puntaje en ciencias va de 124,04 a 761,87 puntos, con una media de 408,86 y una mediana de 403,88, valores cercanos entre sí. La asimetría 0,25 y la curtosis -0,11 están cerca de 0, lo que indica una distribución aproximadamente simétrica y de forma similar a la normal. El coeficiente de variación es 21,41%, y no hay datos faltantes.

fig19 <- plot_ly(pisa, x = ~PV1SCIE, type = 'box', name = "CIENCIAS",
                 marker = list(color = 'lightblue'),
                 line = list(color = '#030303'),
                 fillcolor = 'rgba(44,127,184,0.5)') %>%
  layout(title = "Boxplot puntaje de ciencias",
         xaxis = list(title = "Puntaje de ciencias"),
         yaxis = list(showticklabels = FALSE),
         margin = list(l = 40, b = 80, t = 80))
fig19

El diagrama de caja muestra que la mitad central de los estudiantes está entre 346,42 y 467,69 puntos, con la mediana muy cerca del centro de la caja. Se observan varios valores atípicos, sobre todo por encima del bigote superior, cerca de 650 puntos en adelante.

gg <- ggplot(pisa, aes(x = PV1SCIE)) +
  geom_histogram(aes(y = after_stat(density)), binwidth = 25,
                 fill = "lightblue", color = "#030303", alpha = 0.7) +
  geom_line(stat = "density", color = "#030303", linewidth = 1) +
  labs(x = "Puntaje en ciencias (PV1SCIE)", y = "Densidad")
fig20 <- ggplotly(gg) %>%
  layout(title = "Distribución del puntaje en ciencias",
         plot_bgcolor = grey(0.95),
         margin = list(l = 80, b = 80, t = 80))
fig20

El histograma muestra una sola moda, cerca de 390 puntos, con una forma acampanada y una leve cola hacia la derecha, coherente con la asimetría positiva de la tabla.

Al comparar las tres áreas, matemáticas, lectura y ciencias tienen medias y medianas parecidas, todas alrededor de 380 a 410 puntos, y distribuciones aproximadamente simétricas. Lectura es la de mayor dispersión CV = 22,77% y matemáticas la de menor CV = 19,42%, mientras que ciencias queda en un punto intermedio CV = 21,41%. Ninguna de las tres variables tiene datos faltantes.

4.16 ESCS - Índice de nivel económico, social y cultural

x <- pisa$ESCS
tabla_ESCS <- data.frame(
  Medida = c("Faltantes", "Mínimo", "Q1", "Mediana", "Media", "Q3", "Máximo",
             "IQR", "Desviación estándar", "Asimetría", "Curtosis"),
  Valor = c(sum(is.na(x)),
            min(x, na.rm = TRUE),
            quantile(x, 0.25, na.rm = TRUE),
            median(x, na.rm = TRUE),
            mean(x, na.rm = TRUE),
            quantile(x, 0.75, na.rm = TRUE),
            max(x, na.rm = TRUE),
            IQR(x, na.rm = TRUE),
            sd(x, na.rm = TRUE),
            skewness(x, na.rm = TRUE),
            kurtosis(x, na.rm = TRUE))
) %>%
  mutate(Valor = round(Valor, 2))
kable(tabla_ESCS, caption = "Medidas resumen del índice de nivel económico, social y cultural (ESCS)")
Medidas resumen del índice de nivel económico, social y cultural (ESCS)
Medida Valor
Faltantes 709.00
Mínimo -6.02
Q1 -1.84
Mediana -1.03
Media -1.02
Q3 -0.08
Máximo 2.27
IQR 1.76
Desviación estándar 1.23
Asimetría -0.20
Curtosis -0.45

El índice de nivel económico, social y cultural va de -6,02 a 2,27, con una media de -1,02 y una mediana de -1,03, valores muy cercanos entre sí. Como la referencia de este índice es 0 para el promedio de los países de la OCDE(Organización para la Cooperación y el Desarrollo Económicos), una media negativa indica que, los estudiantes de Colombia, Perú y Panamá tienen un nivel socioeconómico y cultural por debajo de ese promedio. La asimetría -0,20 y la curtosis -0,45 están cerca de 0, lo que indica una distribución bastante simétrica, algo aplanada respecto a la normal. El 3,7% de los estudiantes no tiene información en esta variable.

fig21 <- plot_ly(pisa, x = ~ESCS, type = 'box', name = "ESCS",
                 marker = list(color = 'lightblue'),
                 line = list(color = '#030303'),
                 fillcolor = 'rgba(44,127,184,0.5)') %>%
  layout(title = "Índice de nivel económico, social y cultural",
         xaxis = list(title = "Indice ESCS"),
         yaxis = list(showticklabels = FALSE),
         margin = list(l = 40, b = 80, t = 80))
fig21
Warning: Ignoring 709 observations

El diagrama de caja confirma que la mayoría de los estudiantes se ubica en valores negativos: la caja va de -1,84 a -0,08, y la línea vertical en 0 (la referencia de la OCDE) queda por fuera de la caja, hacia su extremo derecho. Esto refleja que más de la mitad de los estudiantes está por debajo de ese promedio internacional. Se observan varios valores atípicos hacia la izquierda, con estudiantes de nivel socioeconómico muy bajo.

fig22 <- plot_ly(pisa, x = ~ESCS, type = 'histogram',
                 xbins = list(size = 0.25),
                 marker = list(color = 'lightblue',
                               line = list(color = '#030303', width = 1))) %>%
  layout(title = "Distribución del Índice de nivel económico, social y cultural ",
         xaxis = list(title = "Indice ESCS"),
         yaxis = list(title = "Frecuencia absoluta"),
         margin = list(l = 80, b = 80, t = 80))
fig22
Warning: Ignoring 709 observations

El histograma muestra un solo pico, alrededor de -1,3 a -1,1, y confirma que la mayor parte de los estudiantes se concentra en valores negativos, con una cola algo más larga hacia la izquierda que hacia la derecha. Muy pocos estudiantes superan el valor 1, el nivel que correspondería a un estatus socioeconómico y cultural bastante por encima del promedio de la OCDE.

4.17 ICTRES - Índice de recursos TIC en el hogar

x <- pisa$ICTRES
tabla_ictres <- data.frame(
  Medida = c("Faltantes", "Mínimo", "Q1", "Mediana", "Media", "Q3", "Máximo",
             "IQR", "Desviación estándar", "Asimetría", "Curtosis"),
  Valor = c(sum(is.na(x)),
            min(x, na.rm = TRUE),
            quantile(x, 0.25, na.rm = TRUE),
            median(x, na.rm = TRUE),
            mean(x, na.rm = TRUE),
            quantile(x, 0.75, na.rm = TRUE),
            max(x, na.rm = TRUE),
            IQR(x, na.rm = TRUE),
            sd(x, na.rm = TRUE),
            skewness(x, na.rm = TRUE),
            kurtosis(x, na.rm = TRUE))
) %>%
  mutate(Valor = round(Valor, 2))
kable(tabla_ictres, caption = "Medidas resumen del índice de recursos TIC en el hogar (ICTRES)")
Medidas resumen del índice de recursos TIC en el hogar (ICTRES)
Medida Valor
Faltantes 821.00
Mínimo -5.08
Q1 -2.19
Mediana -1.35
Media -1.39
Q3 -0.53
Máximo 5.25
IQR 1.66
Desviación estándar 1.34
Asimetría -0.24
Curtosis 0.44

El índice de recursos TIC en el hogar va de -5,08 a 5,25, con una media de -1,39 y una mediana de -1,35, valores muy cercanos entre sí. Como este índice también tiene su referencia en 0 para el promedio de la OCDE, una media negativa indica que, en conjunto, los estudiantes de Colombia, Perú y Panamá cuentan con menos recursos tecnológicos en el hogar que ese promedio. La asimetría (-0,24) es leve. El 4,25% de los estudiantes (821) no tiene información en esta variable.

fig23 <- plot_ly(pisa, x = ~ICTRES, type = 'box', name = "ICTRES",
                 marker = list(color = 'lightblue'),
                 line = list(color = '#030303'),
                 fillcolor = 'rgba(44,127,184,0.5)') %>%
  layout(title = "Índice de recursos TIC en el hogar",
         xaxis = list(title = "Indice ICTRES"),
         yaxis = list(showticklabels = FALSE),
         margin = list(l = 40, b = 80, t = 80))
fig23
Warning: Ignoring 821 observations

El boxplot confirma que la mayoría de los estudiantes se ubica en valores negativos: la caja va de -2,19 a -0,53, y la línea de referencia en 0 queda fuera de la caja, cerca de su extremo derecho. Esto quiere decir que más de la mitad de los estudiantes tiene menos recursos TIC que ese promedio internacional. Se observan varios valores atípicos hacia la derecha, con estudiantes que reportan un acceso a tecnología bastante superior al resto

fig24 <- plot_ly(pisa, x = ~ICTRES, type = 'histogram',
                 xbins = list(size = 0.25),
                 marker = list(color = 'lightblue',
                               line = list(color = '#030303', width = 1))) %>%
  layout(title = "Distribución del Índice de recursos TIC en el hogar ",
         xaxis = list(title = "Indice ICTRES"),
         yaxis = list(title = "Frecuencia absoluta"),
         margin = list(l = 80, b = 80, t = 80))
fig24
Warning: Ignoring 821 observations

El histograma muestra una distribución con una sola moda, alrededor de -1,3, y confirma que la mayor parte de los estudiantes se concentra en valores negativos. A diferencia de ESCS, aquí se nota una barra alta y aislada en el extremo izquierdo, cerca de -5.

Este resultado es coherente con el de ESCS: los estudiantes de estos tres países tienen, en promedio, menos recursos tecnológicos en el hogar que el promedio de la OCDE

4.18 BELONG - Sentido de pertenencia

x <- pisa$BELONG
tabla_belong <- data.frame(
  Medida = c("Faltantes", "Mínimo", "Q1", "Mediana", "Media", "Q3", "Máximo",
             "IQR", "Desviación estándar", "Asimetría", "Curtosis"),
  Valor = c(sum(is.na(x)),
            min(x, na.rm = TRUE),
            quantile(x, 0.25, na.rm = TRUE),
            median(x, na.rm = TRUE),
            mean(x, na.rm = TRUE),
            quantile(x, 0.75, na.rm = TRUE),
            max(x, na.rm = TRUE),
            IQR(x, na.rm = TRUE),
            sd(x, na.rm = TRUE),
            skewness(x, na.rm = TRUE),
            kurtosis(x, na.rm = TRUE))
) %>%
  mutate(Valor = round(Valor, 2))
kable(tabla_belong, caption = "Medidas resumen del índice de sentido de pertenencia a la escuela (BELONG)")
Medidas resumen del índice de sentido de pertenencia a la escuela (BELONG)
Medida Valor
Faltantes 1714.00
Mínimo -3.32
Q1 -0.69
Mediana -0.33
Media -0.17
Q3 0.21
Máximo 2.78
IQR 0.90
Desviación estándar 0.91
Asimetría 0.87
Curtosis 2.28

El índice de sentido de pertenencia a la escuela va de -3,32 a 2,78, con una media de -0,17 y una mediana de -0,33. Como la media es mayor que la mediana, hay una asimetría hacia la derecha, confirmada por el valor de asimetría (0,87), que es claramente positivo. La curtosis es alta (2,28), lo que indica una distribución más puntiaguda que la normal. La referencia de este índice es 0 para el promedio de la OCDE, y como la mediana es negativa, más de la mitad de los estudiantes reporta un sentido de pertenencia menor a ese promedio. El 8,88% de los estudiantes no tiene información en esta variable.

fig25 <- plot_ly(pisa, x = ~BELONG, type = 'box', name = "BELONG",
                 marker = list(color = 'lightblue'),
                 line = list(color = '#030303'),
                 fillcolor = 'rgba(44,127,184,0.5)') %>%
  layout(title = "Índice de sentido de pertenencia a la escuela",
         xaxis = list(title = "Índice BELONG"),
         yaxis = list(showticklabels = FALSE),
         margin = list(l = 40, b = 80, t = 80))
fig25
Warning: Ignoring 1714 observations

El diagrama de caja muestra la mitad central de los estudiantes entre -0,69 y 0,21, con la mediana un poco más cerca del tercer cuartil, lo que refleja la asimetría hacia la derecha señalada en la tabla. Se observan valores atípicos en ambos extremos, aunque son más numerosos hacia la izquierda, con estudiantes que reportan un sentido de pertenencia muy bajo.

gg <- pisa %>%
  filter(!is.na(BELONG)) %>%
  ggplot(aes(x = BELONG)) +
  geom_histogram(aes(y = after_stat(density)), binwidth = 0.25,
                 fill = "lightblue", color = "#030303", alpha = 0.7) +
  geom_line(stat = "density", color = "#030303", linewidth = 1) +
  labs(x = "Índice BELONG", y = "Densidad")

fig26 <- ggplotly(gg) %>%
  layout(title = "Distribución del índice de sentido de pertenencia",
         plot_bgcolor = grey(0.95),
         margin = list(l = 80, b = 80, t = 80))
fig26

El histograma confirma un pico alto y angosto cerca de -0,3, coherente con la curtosis elevada de la tabla.También se ve una pequeña acumulación de estudiantes en el extremo superior de la escala, que corresponde a quienes reportan el nivel más alto posible de pertenencia.

4.19 FEELSAFE - Percepción de seguridad en la escuela

x <- pisa$FEELSAFE
tabla_feelsafe <- data.frame(
  Medida = c("Faltantes", "Mínimo", "Q1", "Mediana", "Media", "Q3", "Máximo",
             "IQR", "Desviación estándar", "Asimetría", "Curtosis"),
  Valor = c(sum(is.na(x)),
            min(x, na.rm = TRUE),
            quantile(x, 0.25, na.rm = TRUE),
            median(x, na.rm = TRUE),
            mean(x, na.rm = TRUE),
            quantile(x, 0.75, na.rm = TRUE),
            max(x, na.rm = TRUE),
            IQR(x, na.rm = TRUE),
            sd(x, na.rm = TRUE),
            skewness(x, na.rm = TRUE),
            kurtosis(x, na.rm = TRUE))
) %>%
  mutate(Valor = round(Valor, 2))
kable(tabla_feelsafe, caption = "Medidas resumen del índice de percepción de seguridad en la escuela (FEELSAFE)")
Medidas resumen del índice de percepción de seguridad en la escuela (FEELSAFE)
Medida Valor
Faltantes 1534.00
Mínimo -2.79
Q1 -0.76
Mediana -0.76
Media -0.21
Q3 1.12
Máximo 1.17
IQR 1.88
Desviación estándar 1.00
Asimetría 0.00
Curtosis -1.12

El índice de percepción de seguridad en la escuela va de -2,79 a 1,17, con una media de -0,21 y una mediana de -0,76. Aquí la media queda por encima de la mediana, y la asimetría (0,00) sale casi exactamente en 0, la curtosis -1,12 es negativa, lo que indica una distribución bastante aplanada, con los datos repartidos. Esta variable tiene un porcentaje alto de faltantes, el 7,94% de los estudiantes no tiene información.

fig27 <- plot_ly(pisa, x = ~FEELSAFE, type = 'box', name = "FEELSAFE",
                 marker = list(color = 'lightblue'),
                 line = list(color = '#030303'),
                 fillcolor = 'rgba(44,127,184,0.5)') %>%
  layout(title = "Índice de Percepción de seguridad en la escuela",
         xaxis = list(title = "Índice FEELSAFE"),
         yaxis = list(showticklabels = FALSE),
         margin = list(l = 40, b = 80, t = 80))
fig27
Warning: Ignoring 1534 observations

El diagrama de caja muestra la mitad central de los estudiantes entre -0,76 y 1,12, con la mediana ubicada justo en el borde inferior de la caja. El bigote inferior es mucho más largo que el superior, lo que indica una cola extendida hacia los valores bajos, aunque sin puntos marcados como atípicos.

gg <- pisa %>%
  filter(!is.na(FEELSAFE)) %>%
  ggplot(aes(x = FEELSAFE)) +
  geom_histogram(aes(y = after_stat(density)), binwidth = 0.25,
                 fill = "lightblue", color = "#030303", alpha = 0.7) +
  geom_line(stat = "density", color = "#030303", linewidth = 1) +
  labs(x = "Índice FEELSAFE", y = "Densidad")
fig28 <- ggplotly(gg) %>%
  layout(title = "Distribución del índice percepción de seguridad",
         plot_bgcolor = grey(0.95),
         margin = list(l = 80, b = 80, t = 80))
fig28

El histograma explica lo que no se veía en los otros dos, la distribución tiene al menos dos picos marcados, uno cerca de -0,75 y otro cerca de 1, es decir, hay dos grupos claramente diferenciados de estudiantes, uno que reporta una percepción de seguridad moderadamente baja, y otro con la percepción más alta.

4.20 ANXMAT - Ansiedad ante las matemáticas

x <- pisa$ANXMAT
tabla_ANXMAT <- data.frame(
  Medida = c("Faltantes", "Mínimo", "Q1", "Mediana", "Media", "Q3", "Máximo",
             "IQR", "Desviación estándar", "Asimetría", "Curtosis"),
  Valor = c(sum(is.na(x)),
            min(x, na.rm = TRUE),
            quantile(x, 0.25, na.rm = TRUE),
            median(x, na.rm = TRUE),
            mean(x, na.rm = TRUE),
            quantile(x, 0.75, na.rm = TRUE),
            max(x, na.rm = TRUE),
            IQR(x, na.rm = TRUE),
            sd(x, na.rm = TRUE),
            skewness(x, na.rm = TRUE),
            kurtosis(x, na.rm = TRUE))
) %>%
  mutate(Valor = round(Valor, 2))
kable(tabla_ANXMAT, caption = "Medidas resumen del índice de ansiedad ante las matemáticas (ANXMAT)")
Medidas resumen del índice de ansiedad ante las matemáticas (ANXMAT)
Medida Valor
Faltantes 5726.00
Mínimo -2.39
Q1 0.05
Mediana 0.57
Media 0.54
Q3 0.91
Máximo 2.63
IQR 0.86
Desviación estándar 0.99
Asimetría -0.12
Curtosis 1.09

El índice de ansiedad ante las matemáticas tiene media de 0,54 y mediana de 0,57, valores cercanos y positivos, lo que indica que estos estudiantes reportan más ansiedad que el promedio de referencia de la OCDE . La curtosis 1,09 sugiere un pico más marcado que en una distribución normal. El 29,65% de los estudiantes no tiene información, el porcentaje de faltantes más alto entre los índices analizados.

fig29 <- plot_ly(pisa, x = ~ANXMAT, type = 'box', name = "ANXMAT",
                 marker = list(color = 'lightblue'),
                 line = list(color = '#030303'),
                 fillcolor = 'rgba(44,127,184,0.5)') %>%
  layout(title = "Índice de Ansiedad ante las matemáticas",
         xaxis = list(title = "Índice ANXMAT"),
         yaxis = list(showticklabels = FALSE),
         margin = list(l = 40, b = 80, t = 80))
fig29
Warning: Ignoring 5726 observations

La mitad central de los estudiantes está entre 0,05 y 0,91. Se observan valores atípicos en ambos extremos, con un grupo separado hacia valores altos (2,3 a 2,6).

gg <- pisa %>%
  filter(!is.na(ANXMAT)) %>%
  ggplot(aes(x = ANXMAT)) +
  geom_histogram(aes(y = after_stat(density)), binwidth = 0.25,
                 fill = "lightblue", color = "#030303", alpha = 0.7) +
  geom_line(stat = "density", color = "#030303", linewidth = 1) +
  labs(x = "Índice ANXMAT", y = "Densidad")
fig30 <- ggplotly(gg) %>%
  layout(title = "Distribución de Ansiedad ante las matemáticas",
         plot_bgcolor = grey(0.95),
         margin = list(l = 80, b = 80, t = 80))
fig30

La distribución no es unimodal, además del pico principal cerca de 0,6, hay un segundo pico pequeño cerca de 2,5, que corresponde a un grupo de estudiantes con ansiedad claramente más alta que el resto.

4.21 MATHEFF - Autoeficacia matemática

x <- pisa$MATHEFF
tabla_matheff <- data.frame(
  Medida = c("Faltantes", "Mínimo", "Q1", "Mediana", "Media", "Q3", "Máximo",
             "IQR", "Desviación estándar", "Asimetría", "Curtosis"),
  Valor = c(sum(is.na(x)),
            min(x, na.rm = TRUE),
            quantile(x, 0.25, na.rm = TRUE),
            median(x, na.rm = TRUE),
            mean(x, na.rm = TRUE),
            quantile(x, 0.75, na.rm = TRUE),
            max(x, na.rm = TRUE),
            IQR(x, na.rm = TRUE),
            sd(x, na.rm = TRUE),
            skewness(x, na.rm = TRUE),
            kurtosis(x, na.rm = TRUE))
) %>%
  mutate(Valor = round(Valor, 2))
kable(tabla_matheff, caption = "Medidas resumen del índice de autoeficacia en matemáticas (MATHEFF)")
Medidas resumen del índice de autoeficacia en matemáticas (MATHEFF)
Medida Valor
Faltantes 5197.00
Mínimo -3.78
Q1 -1.05
Mediana -0.44
Media -0.47
Q3 0.01
Máximo 2.52
IQR 1.07
Desviación estándar 1.09
Asimetría -0.04
Curtosis 1.64

El índice de autoeficacia en matemáticas tiene media de -0,47 y mediana de -0,44, valores cercanos y negativos, lo que indica que estos estudiantes reportan menos confianza en su capacidad matemática que el promedio de referencia de la OCDE (0). La curtosis (1,64) indica un pico marcado, más alto que en una distribución normal. El 26,91% de los estudiantes (5197) no tiene información

fig31 <- plot_ly(pisa, x = ~MATHEFF, type = 'box', name = "MATHEFF",
                 marker = list(color = 'lightblue'),
                 line = list(color = '#030303'),
                 fillcolor = 'rgba(44,127,184,0.5)') %>%
  layout(title = "Índice de autoeficacia en matemáticas",
         xaxis = list(title = "Índice MATHEFF"),
         yaxis = list(showticklabels = FALSE),
         margin = list(l = 40, b = 80, t = 80))
fig31
Warning: Ignoring 5197 observations

La mitad central de los estudiantes está entre -1,05 y 0,01. Hay bastantes valores atípicos en ambos extremos, algo más numerosos hacia la izquierda.

gg <- pisa %>%
  filter(!is.na(MATHEFF)) %>%
  ggplot(aes(x = MATHEFF)) +
  geom_histogram(aes(y = after_stat(density)), binwidth = 0.25,
                 fill = "lightblue", color = "#030303", alpha = 0.7) +
  geom_line(stat = "density", color = "#030303", linewidth = 1) +
  labs(x = "Índice MATHEFF", y = "Densidad")
fig32 <- ggplotly(gg) %>%
  layout(title = "Distribución índice autoeficacia en matemáticas",
         plot_bgcolor = grey(0.95),
         margin = list(l = 80, b = 80, t = 80))
fig32

La distribución tiene un pico principal marcado cerca de 0, y dos grupos más pequeños separados del resto: uno hacia -3,5 y otro hacia 2,3. Esto muestra que, además de la mayoría con autoeficacia cercana o algo por debajo del promedio, hay grupos minoritarios con confianza muy baja y muy alta en sus habilidades matemáticas.

5 Analisis Bivariado

Ahora pasaremos a realizar un análisis bivariado de las variables. Para este análisis se tomará la variable REPEAT (¿repitió algún grado?) como cualitativa y la variable ESCS (índice de nivel económico, social y cultural) como cuantitativa; y se realizará un análisis de estas variables con las demás.

n <- nrow(pisa)
options(digits = 4, scipen = 999)

# Recodificar valores perdidos PISA
pisa[pisa == 95 | pisa == 97 | pisa == 98 | pisa == 99] <- NA

Varios de los datos de la base de PISA con valores como 95, 97, 98 y 99 suelen corresponder, muchas veces, a no respuesta; por eso es mejor renombrarlos como NA, de esa manera los cálculos no se verán afectados.

pisa[pisa == 95 | pisa == 97 | pisa == 98 | pisa == 99] <- NA
#Solo mostraremos los primeros valores de la tabla
head(pisa)
  CNT ST004D01T IMMIG REPEAT ISCEDP LANGN COBN_S EXPECEDU WORKPAY WORKHOME
1 COL         1     1      0    344   156  17000        8       2       10
2 COL         2     1      0    344   156  17000       NA       7        9
3 COL         2     1      1    244   156  17000        8       4        5
4 COL         2    NA     NA    344   999 999999       NA      NA       NA
5 COL         1     3      0    244   156  86200        9       0        0
6 COL         2     1      1    244   156  17000       NA       2        0
  DURECEC OECD   AGE GRADE PV1MATH PV1READ PV1SCIE    ESCS  ICTRES  BELONG
1       3    1 15.92     1   445.9   479.0   485.0 -1.2308 -1.1167  0.5159
2       1    1 15.92     0   338.8   244.4   322.9 -2.3695 -4.0976 -0.2482
3       3    1 16.00    -1   567.5   584.9   615.2 -0.0731 -0.5542 -1.0331
4      NA    1 15.67     0   407.1   494.4   436.0      NA      NA      NA
5       2    1 15.42    -1   297.4   329.0   315.7 -0.9326 -3.0438 -1.5970
6       1    1 15.42    -1   341.9   351.9   321.1 -1.4845 -1.9975 -0.3261
  FEELSAFE ANXMAT MATHEFF LIFESAT
1   -1.500 0.1031 -1.0540      NA
2   -1.533     NA      NA      NA
3   -0.756 0.5653  0.0977      NA
4       NA     NA      NA      NA
5   -1.104 0.6779 -0.9908      NA
6   -0.756 0.1932 -1.0760      NA

Tenemos que ver cuántos casos perdidos hay en la base de datos PISA, ya que es necesario saberlo antes de realizar análisis, pruebas, etc. Para esto veremos un ejemplo con la variable CNT.

# ¿Cuántos NA hay en REPEAT y CNT?
sum(is.na(pisa$REPEAT))
[1] 952
sum(is.na(pisa$CNT))
[1] 0
# ¿Cuántos casos completos hay?
sum(!is.na(pisa$REPEAT) & !is.na(pisa$CNT))
[1] 18364
# Comparar con n total
nrow(pisa)
[1] 19316

Con esto podemos observar que, en efecto, hay casos en los que no se tiene información completa, por lo que es necesario tener cuidado con las interpretaciones. Así son todas las variables de toda la base de datos.

Cargamos las variables tanto cualitativas como cuantitativas.

cualitativas <- c("CNT","ST004D01T","IMMIG","GRADE", "REPEAT","ISCEDP","LANGN",
                  "EXPECEDU","WORKPAY","WORKHOME","DURECEC")


cuantitativas <- c("AGE","PV1MATH","PV1READ","PV1SCIE",
                   "ESCS","ICTRES","BELONG","FEELSAFE","ANXMAT",
                   "MATHEFF")

5.1 Variable cualitativa

5.1.1 Variable REPEAT x Variable Cualitativa

Iniciaremos este estudio haciendo las relaciones entre la variable seleccionada REPEAT (cualitativa) y las demás variables cualitativas de la base de datos PISA.

En primer lugar, haremos que R clasifique las variables cualitativas como factores.

for (v in cualitativas) pisa[[v]] <- as.factor(pisa[[v]])
# Función: pone nombre a los códigos conocidos y deja el número en los demás
etiquetar <- function(x, codigos, nombres) {
  lev <- sort(unique(x))
  lab <- ifelse(lev %in% codigos, nombres[match(lev, codigos)], as.character(lev))
  factor(x, levels = lev, labels = lab)
}

pisa$CNT       <- factor(pisa$CNT, levels = c("COL", "PAN", "PER"),
                         labels = c("Colombia", "Panamá", "Perú"))
pisa$ST004D01T <- factor(pisa$ST004D01T, levels = 1:2, labels = c("Mujer", "Hombre"))
pisa$IMMIG     <- factor(pisa$IMMIG, levels = 1:3,
                         labels = c("Nativo", "2da generación", "1ra generación"))


pisa$GRADE     <- factor(pisa$GRADE, levels = -3:1,
                     labels = c("3 grados por debajo", "2 grados por debajo",
                                "1 grado por debajo", "Grado de referencia",
                                "1 grado por encima"))


pisa$REPEAT    <- factor(pisa$REPEAT, levels = 0:1, labels = c("No repitió", "Repitió"))

pisa$ISCEDP <- etiquetar(pisa$ISCEDP, c(244, 254, 344, 354),
                         c("244 Sec. baja general", "254 Sec. baja vocacional",
                           "344 Sec. alta general", "354 Sec. alta vocacional"))

pisa$LANGN <- etiquetar(pisa$LANGN, c(156, 313, 358, 561, 999),
                        c("Español", "Inglés", "Quechua", "Ngäbe", "Sin dato (999)"))

pisa$EXPECEDU <- etiquetar(pisa$EXPECEDU, 1:9,
                           c("Menos de ISCED 2", "ISCED 2", "ISCED 3.3", "ISCED 3.4",
                             "ISCED 4", "ISCED 5", "ISCED 6", "ISCED 7", "ISCED 8"))

pisa$WORKPAY  <- etiquetar(pisa$WORKPAY, 0:10, c(as.character(0:9), "10 o más"))
pisa$WORKHOME <- etiquetar(pisa$WORKHOME, 0:10, c(as.character(0:9), "10 o más"))

pisa$DURECEC <- etiquetar(pisa$DURECEC, 0:8,
                          c("<1 año", "1 a <2", "2 a <3", "3 a <4", "4 a <5",
                            "5 a <6", "6 a <7", "7 a <8", "8 o más"))

Para hacer el análisis de la variable de interés (REPEAT), tomaremos el vector de variables creado (cualitativas) y quitaremos la variable seleccionada.

cuali_otras <- setdiff(cualitativas, "REPEAT")

Comenzaremos el estudio realizando tablas de contingencia entre variables cualitativas; para este punto haremos el cruce entre la variable REPEAT y las demás.

Primero relacionaremos la variable REPEAT y la variable CNT.

# REPEAT x CNT
tc <- table(pisa$REPEAT, pisa$CNT, useNA = "ifany")
tabtc <- cbind(tc, totF = rowSums(tc))
tabtc <- rbind(tabtc, totC = colSums(tabtc))
knitr::kable(cbind(tabtc, rep(" ", nrow(tabtc)), round(tabtc/n*100, 1)), 
      digits = 1, caption = "REPEAT x PAÍS")
REPEAT x PAÍS
Colombia Panamá Perú totF Colombia Panamá Perú totF
No repitió 4618 3030 6024 13672 23.9 15.7 31.2 70.8
Repitió 2783 1050 859 4692 14.4 5.4 4.4 24.3
NA 403 464 85 952 2.1 2.4 0.4 4.9
totC 7804 4544 6968 19316 40.4 23.5 36.1 100

De esta tabla podemos observar varios aspectos. En general, se tiene que un 70,8% de los estudiantes no repitieron un curso, y Perú es el país donde más estudiantes no repitieron, con 6024 estudiantes. Por otra parte, hay un 24,3% de estudiantes que sí repitieron, con Colombia liderando este puesto. Cabe resaltar dos aspectos: el primero es que siempre se tienen más datos de Colombia, por lo que es bueno tener en cuenta esto por la proporción de datos; y, por otro lado, hay un 4,9% de datos de los que no se sabe si repitieron o no.

Seguiremos con un análisis de los estudiantes que repitieron curso por sexo (ST004D01T)

# REPEAT x ST004D01T
tc <- table(pisa$REPEAT, pisa$ST004D01T, useNA = "ifany")
tabtc <- cbind(tc, totF = rowSums(tc))
tabtc <- rbind(tabtc, totC = colSums(tabtc))
knitr::kable(cbind(tabtc, rep(" ", nrow(tabtc)), round(tabtc/n*100, 1)), 
      digits = 1, caption = "REPEAT x SEXO")
REPEAT x SEXO
Mujer Hombre totF Mujer Hombre totF
No repitió 7261 6411 13672 37.6 33.2 70.8
Repitió 1990 2702 4692 10.3 14 24.3
NA 457 495 952 2.4 2.6 4.9
totC 9708 9608 19316 50.3 49.7 100

Lo primero a mencionar es que la proporción entre sexos es similar: las mujeres tienen un 50,3% de la muestra y los hombres un 49,7%. Esta tabla muestra que, del 70,8% de los estudiantes que no repitieron curso, el 37,6% son mujeres y el 33,2% son hombres. Por otro lado, podemos observar que, de los que sí repitieron, el 10,3% son mujeres y el 14% son hombres; es decir, se tienen más repitentes de curso en el género masculino.

Ahora buscamos la relación entre si se repitió curso y el estado migratorio de los estudiantes (IMMIG)

# REPEAT x IMMIG
tc <- table(pisa$REPEAT, pisa$IMMIG, useNA = "ifany")
tabtc <- cbind(tc, totF = rowSums(tc))
tabtc <- rbind(tabtc, totC = colSums(tabtc))
knitr::kable(cbind(tabtc, rep(" ", nrow(tabtc)), round(tabtc/n*100, 1)), 
      digits = 1, caption = "REPEAT x Estado Migratorio")
REPEAT x Estado Migratorio
Nativo 2da generación 1ra generación NA totF Nativo 2da generación 1ra generación NA totF
No repitió 12929 57 256 430 13672 66.9 0.3 1.3 2.2 70.8
Repitió 4278 31 110 273 4692 22.1 0.2 0.6 1.4 24.3
NA 153 2 4 793 952 0.8 0 0 4.1 4.9
totC 17360 90 370 1496 19316 89.9 0.5 1.9 7.7 100

Para este cruce de variables podemos observar que la mayoría de los estudiantes son nativos (no inmigrantes), con un total del 89,9%. Se tiene que hay un total de 0,5% de estudiantes que son nativos pero con papás inmigrantes y, por último, se tiene un total de 1,9% de estudiantes que sí nacieron fuera del país. (Además, hay 7,7% de estudiantes sin respuesta). También podemos observar que, para los estudiantes que repitieron curso, la mayoría son nativos con un 66,9% de los estudiantes y, por otro lado, para los estudiantes que sí repitieron, un 22,1% son nativos.

Seguiremos con la variable REPEAT y el grado de los estudiantes

# REPEAT x GRADE
tc <- table(pisa$REPEAT, pisa$GRADE, useNA = "ifany")
tabtc <- cbind(tc, totF = rowSums(tc))
tabtc <- rbind(tabtc, totC = colSums(tabtc))
knitr::kable(cbind(tabtc, rep(" ", nrow(tabtc)), round(tabtc/n*100, 1)), 
      digits = 1, caption = "REPEAT x GRADE")
REPEAT x GRADE
3 grados por debajo 2 grados por debajo 1 grado por debajo Grado de referencia 1 grado por encima NA totF 3 grados por debajo 2 grados por debajo 1 grado por debajo Grado de referencia 1 grado por encima NA totF
No repitió 66 161 1017 10244 2177 7 13672 0.3 0.8 5.3 53 11.3 0 70.8
Repitió 330 1000 2330 992 39 1 4692 1.7 5.2 12.1 5.1 0.2 0 24.3
NA 52 112 258 476 54 0 952 0.3 0.6 1.3 2.5 0.3 0 4.9
totC 448 1273 3605 11712 2270 8 19316 2.3 6.6 18.7 60.6 11.8 0 100

Con esta tabla podemos observar que el 60,6% con un total de 11712 de la muestra de la estudiantes se encuentra en el grado excato previsto, el 27,6% con un total de 5326 estudiantes por lo menos un grado más abajo del que deberían estar esos estudiantes, y se tiene un 11,8% que esta un grado más alto del que deberia.

Seguiremos con la variable REPEAT y los niveles de programas educativos.

# REPEAT x ISCEDP
tc <- table(pisa$REPEAT, pisa$ISCEDP, useNA = "ifany")
tabtc <- cbind(tc, totF = rowSums(tc))
tabtc <- rbind(tabtc, totC = colSums(tabtc))
knitr::kable(cbind(tabtc, rep(" ", nrow(tabtc)), round(tabtc/n*100, 1)), 
      digits = 1, caption = "REPEAT x NIVEL_PROG_EDUCATIVO")
REPEAT x NIVEL_PROG_EDUCATIVO
244 Sec. baja general 254 Sec. baja vocacional 344 Sec. alta general 354 Sec. alta vocacional totF 244 Sec. baja general 254 Sec. baja vocacional 344 Sec. alta general 354 Sec. alta vocacional totF
No repitió 1244 7 11415 1006 13672 6.4 0 59.1 5.2 70.8
Repitió 3660 1 873 158 4692 18.9 0 4.5 0.8 24.3
NA 422 0 444 86 952 2.2 0 2.3 0.4 4.9
totC 5326 8 12732 1250 19316 27.6 0 65.9 6.5 100

De esta tabla podemos notar que la mayoría de los estudiantes son de un nivel educativo 344, con 65,9%, seguido de 244 con un 27,6%. Podemos notar que en esta muestra hay muy pocos estudiantes que se encuentran en un nivel educativo 254. Para el grupo de estudiantes que no repitieron un curso, el 59,1% son de un nivel educativo 344; pero, para el caso de los que sí repitieron, la mayoría de estudiantes se encuentran en un nivel educativo 244, representando un 18,9% del 24,3% de los estudiantes que repitieron.

Continuemos con la comparación entre repetir un curso y el idioma hablado en casa.

# REPEAT x LANGN
tc <- table(pisa$REPEAT, pisa$LANGN, useNA = "ifany")
tabtc <- cbind(tc, totF = rowSums(tc))
tabtc <- rbind(tabtc, totC = colSums(tabtc))
knitr::kable(cbind(tabtc, rep(" ", nrow(tabtc)), round(tabtc/n*100, 1)), 
      digits = 1, caption = "REPEAT x IDIOMA_CASA")
REPEAT x IDIOMA_CASA
Español Inglés Quechua 415 527 Ngäbe 562 563 565 566 567 631 641 673 674 810 841 890 Sin dato (999) totF Español Inglés Quechua 415 527 Ngäbe 562 563 565 566 567 631 641 673 674 810 841 890 Sin dato (999) totF
No repitió 13047 148 166 2 9 100 24 7 3 0 2 22 4 37 5 5 35 23 33 13672 67.5 0.8 0.9 0 0 0.5 0.1 0 0 0 0 0.1 0 0.2 0 0 0.2 0.1 0.2 70.8
Repitió 4413 37 50 1 1 60 22 7 8 1 0 10 7 28 1 8 9 11 18 4692 22.8 0.2 0.3 0 0 0.3 0.1 0 0 0 0 0.1 0 0.1 0 0 0 0.1 0.1 24.3
NA 152 2 4 1 1 11 8 0 0 0 0 1 3 0 0 0 0 3 766 952 0.8 0 0 0 0 0.1 0 0 0 0 0 0 0 0 0 0 0 0 4 4.9
totC 17612 187 220 4 11 171 54 14 11 1 2 33 14 65 6 13 44 37 817 19316 91.2 1 1.1 0 0.1 0.9 0.3 0.1 0.1 0 0 0.2 0.1 0.3 0 0.1 0.2 0.2 4.2 100
# REPEAT x EXPECEDU 
tc <- table(pisa$REPEAT, pisa$EXPECEDU , useNA = "ifany")
tabtc <- cbind(tc, totF = rowSums(tc))
tabtc <- rbind(tabtc, totC = colSums(tabtc))
knitr::kable(cbind(tabtc, rep(" ", nrow(tabtc)), round(tabtc/n*100, 1)), 
      digits = 1, caption = "REPEAT x MÁXIMO_NIVEL_EDUCATIVO_PRE")
REPEAT x MÁXIMO_NIVEL_EDUCATIVO_PRE
ISCED 2 ISCED 3.3 ISCED 3.4 ISCED 4 ISCED 5 ISCED 6 ISCED 7 ISCED 8 NA totF ISCED 2 ISCED 3.3 ISCED 3.4 ISCED 4 ISCED 5 ISCED 6 ISCED 7 ISCED 8 NA totF
No repitió 115 139 380 159 353 1356 1179 5212 4779 13672 0.6 0.7 2 0.8 1.8 7 6.1 27 24.7 70.8
Repitió 150 79 168 76 137 453 324 1309 1996 4692 0.8 0.4 0.9 0.4 0.7 2.3 1.7 6.8 10.3 24.3
NA 3 3 2 2 4 11 4 21 902 952 0 0 0 0 0 0.1 0 0.1 4.7 4.9
totC 268 221 550 237 494 1820 1507 6542 7677 19316 1.4 1.1 2.8 1.2 2.6 9.4 7.8 33.9 39.7 100

Seguiremos con una relación entre REPEAT y si tabaja por un pago

# REPEAT x WORKPAY 
tc <- table(pisa$REPEAT, pisa$WORKPAY  , useNA = "ifany")
tabtc <- cbind(tc, totF = rowSums(tc))
tabtc <- rbind(tabtc, totC = colSums(tabtc))
knitr::kable(cbind(tabtc, rep(" ", nrow(tabtc)), round(tabtc/n*100, 1)), 
      digits = 1, caption = "REPEAT x TRABAJA_PAGO")
REPEAT x TRABAJA_PAGO
0 1 2 3 4 5 6 7 8 9 10 o más NA totF 0 1 2 3 4 5 6 7 8 9 10 o más NA totF
No repitió 6132 630 1283 576 982 730 705 332 479 184 1026 613 13672 31.7 3.3 6.6 3 5.1 3.8 3.6 1.7 2.5 1 5.3 3.2 70.8
Repitió 1626 240 465 212 352 288 229 137 173 90 420 460 4692 8.4 1.2 2.4 1.1 1.8 1.5 1.2 0.7 0.9 0.5 2.2 2.4 24.3
NA 30 4 4 3 4 8 9 5 3 5 15 862 952 0.2 0 0 0 0 0 0 0 0 0 0.1 4.5 4.9
totC 7788 874 1752 791 1338 1026 943 474 655 279 1461 1935 19316 40.3 4.5 9.1 4.1 6.9 5.3 4.9 2.5 3.4 1.4 7.6 10 100

De esta tabla podemos observar que, en esta muestra, hay un 40,3% de los estudiantes que no trabaja por un pago, hay un 10% de los que no se sabe, y termina el podio con estudiantes que trabajan al menos 2 veces a la semana por un pago. También podemos concluir que, del 40,3% de los estudiantes que no trabajan, el 31,7% de los estudiantes no ha repetido un curso y el 8,4% repitió un curso.

Relacionaremos ahora REPEAT y si el estudiante realiza trabajos domésticos.

# REPEAT x WORKHOME 
tc <- table(pisa$REPEAT, pisa$WORKHOME   , useNA = "ifany")
tabtc <- cbind(tc, totF = rowSums(tc))
tabtc <- rbind(tabtc, totC = colSums(tabtc))
knitr::kable(cbind(tabtc, rep(" ", nrow(tabtc)), round(tabtc/n*100, 1)), 
      digits = 1, caption = "REPEAT x REALIZA_TRAB_DOMÉSTICOS")
REPEAT x REALIZA_TRAB_DOMÉSTICOS
0 1 2 3 4 5 6 7 8 9 10 o más NA totF 0 1 2 3 4 5 6 7 8 9 10 o más NA totF
No repitió 1418 456 1090 745 1193 1252 1216 611 1054 516 3707 414 13672 7.3 2.4 5.6 3.9 6.2 6.5 6.3 3.2 5.5 2.7 19.2 2.1 70.8
Repitió 551 174 345 225 342 424 324 199 279 172 1280 377 4692 2.9 0.9 1.8 1.2 1.8 2.2 1.7 1 1.4 0.9 6.6 2 24.3
NA 15 7 4 1 7 8 7 3 8 2 31 859 952 0.1 0 0 0 0 0 0 0 0 0 0.2 4.4 4.9
totC 1984 637 1439 971 1542 1684 1547 813 1341 690 5018 1650 19316 10.3 3.3 7.4 5 8 8.7 8 4.2 6.9 3.6 26 8.5 100

En esta tabla podemos ver que el 26% de los estudiantes realizan por lo menos 10 veces a la semana trabajos en el hogar, seguido de los que no realizan trabajos, con un 10,3%. Del 26% de los estudiantes que hacen trabajos domésticos, el 19,2% de los estudiantes no han repetido un curso, mientras que el 6,6% sí.

Como última tabla de contingencia tenemos la relación entre repetir un curso y la duración de la educación en primera infancia.

# REPEAT x DURECEC 
tc <- table(pisa$REPEAT, pisa$DURECEC   , useNA = "ifany")
tabtc <- cbind(tc, totF = rowSums(tc))
tabtc <- rbind(tabtc, totC = colSums(tabtc))
knitr::kable(cbind(tabtc, rep(" ", nrow(tabtc)), round(tabtc/n*100, 1)), 
      digits = 1, caption = "REPEAT x DURA_EDUC")
REPEAT x DURA_EDUC
<1 año 1 a <2 2 a <3 3 a <4 4 a <5 5 a <6 6 a <7 7 a <8 8 o más NA totF <1 año 1 a <2 2 a <3 3 a <4 4 a <5 5 a <6 6 a <7 7 a <8 8 o más NA totF
No repitió 508 3409 2848 3313 1170 281 78 11 5 2049 13672 2.6 17.6 14.7 17.2 6.1 1.5 0.4 0.1 0 10.6 70.8
Repitió 328 1590 756 559 267 77 30 7 3 1075 4692 1.7 8.2 3.9 2.9 1.4 0.4 0.2 0 0 5.6 24.3
NA 17 20 21 16 5 2 4 0 0 867 952 0.1 0.1 0.1 0.1 0 0 0 0 0 4.5 4.9
totC 853 5019 3625 3888 1442 360 112 18 8 3991 19316 4.4 26 18.8 20.1 7.5 1.9 0.6 0.1 0 20.7 100

Con esta tabla podemos observar que el 64,9% de los estudiantes tardaron entre 1 y 3 años en esta primera etapa de la infancia. En donde el 26% de ese 64,9% tardaron un año. En este 64,9% de los estudiantes, el 49,5% no repitieron un curso, mientras que el 15,4% de los individuos repitió un curso.

Pasamos ahora a hacer un análisis de perfiles fila y perfiles columna; además, realizaremos gráficos para estos perfiles que se puedan diferenciar bien, pues hay varias variables que tienen varias categorías y no se pueden diferenciar bien.

Iniciaremos el estudio de perfiles fila-columna y graficaremos las relaciones entre variables. Como primer cruce de variables tenemos REPEAT y país del estudiante.

tc <- table(pisa$REPEAT, pisa$CNT)

# Perfiles fila
pf <- prop.table(tc, 1)
tabla_pf <- rbind(addmargins(pf, margin = 2)*100,
                  totC = c(colSums(tc)/sum(tc)*100, 100))
knitr::kable(tabla_pf, digits = 1,
      caption = "Perfiles fila: REPEAT x País")
Perfiles fila: REPEAT x País
Colombia Panamá Perú Sum
No repitió 33.8 22.2 44.1 100
Repitió 59.3 22.4 18.3 100
totC 40.3 22.2 37.5 100

Con esta tabla podemos observar aspectos importantes. Lo primero es que la muestra cuenta con un total del 40,3% de datos de Colombia, seguida de un 37,5% de Perú y finalmente Panamá con 22,2%. También podemos concluir que Perú es el país con estudiantes que no repiten curso, con un 44,1%, seguido de Colombia con un 33,8%; además, podemos ver que en Colombia es donde más estudiantes repiten curso, teniendo un total de 59,3%, y seguido de Panamá con un total de 22,4%.

Repasemos ahora los perfiles columna.

tc <- table(pisa$REPEAT, pisa$CNT)

# Perfiles columna
pc <- prop.table(tc, 2)
tabla_pc <- cbind(addmargins(pc, margin = 1)*100,
                  totF = c(rowSums(tc)/sum(tc)*100, 100))

knitr::kable(tabla_pc, digits = 1,
      caption = "Perfiles columna: REPEAT x País")
Perfiles columna: REPEAT x País
Colombia Panamá Perú totF
No repitió 62.4 74.3 87.5 74.5
Repitió 37.6 25.7 12.5 25.5
Sum 100.0 100.0 100.0 100.0

Gracias a la matriz de perfiles fila, podemos observar el porcentaje existente entre estudiantes que repitieron al menos un curso en cada país. Podemos observar que en todos los países (Colombia, Panamá y Perú), la mayoría de los estudiantes no repiten curso. En donde Perú tiene una mayor diferencia entre los grupos, esto concuerda con el perfil fila ya mencionado.

Para ver mejor estas proporciones por países y grupos de no repitentes y sí repitentes, observemos el siguiente gráfico.

tc <- table(pisa$REPEAT, pisa$CNT)

# Gráficos de perfiles
par(mfrow = c(2,1), mai = c(0.4,1,0.3,0.1))
FactoClass::plotct(t(tc), "row", col = 2:5)
FactoClass::plotct(tc, "row", col = 2:4)

Ahora vamos con perfiles fila teniendo en cuenta si se repitió curso y el sexo.

tc <- table(pisa$REPEAT, pisa$ST004D01T)

# Perfiles fila
pf <- prop.table(tc, 1)
tabla_pf <- rbind(addmargins(pf, margin = 2)*100,
                  totC = c(colSums(tc)/sum(tc)*100, 100))
knitr::kable(tabla_pf, digits = 1,
      caption = "Perfiles fila: REPEAT x Sexo")
Perfiles fila: REPEAT x Sexo
Mujer Hombre Sum
No repitió 53.1 46.9 100
Repitió 42.4 57.6 100
totC 50.4 49.6 100

Para este caso ya habíamos mencionado la proporción de mujeres y hombres en la muestra; con esta tabla podemos notar algo nuevo, y es que las mujeres cuentan con un 53,1% que no repitieron curso, y los hombres con un 46,9%. Por otro lado, el 57,6% que son de género masculino han repetido curso, mientras que las mujeres cuentan con una proporción del 42,4% de repitentes.

tc <- table(pisa$REPEAT, pisa$ST004D01T)

# Perfiles columna
pc <- prop.table(tc, 2)
tabla_pc <- cbind(addmargins(pc, margin = 1)*100,
                  totF = c(rowSums(tc)/sum(tc)*100, 100))

knitr::kable(tabla_pc, digits = 1,
      caption = "Perfiles columna: REPEAT x ")
Perfiles columna: REPEAT x
Mujer Hombre totF
No repitió 78.5 70.4 74.5
Repitió 21.5 29.6 25.5
Sum 100.0 100.0 100.0

Con esta tabla podemos observar qué pasa con los sexos en cada uno de los grupos: para mujeres, el 78,5% no repite un curso, y por el lado de los hombres este índice es de 74,5%. Para ambos sexos, el porcentaje de estudiantes que repiten al menos un curso está por encima del 20%, en donde podemos ver que en hombres es más común ver este caso en comparación con las mujeres.

Para visualizar esto, grafiquemos ambos casos.

tc <- table(pisa$REPEAT, pisa$ST004D01T)

# Gráficos de perfiles
par(mfrow = c(2,1), mai = c(0.4,1,0.3,0.1))
FactoClass::plotct(t(tc), "row", col = 2:5)
FactoClass::plotct(tc, "row", col = 2:4)

Continuamos con la variable REPEAT y el estado migratorio de los estudiantes.

tc <- table(pisa$REPEAT, pisa$IMMIG )

# Perfiles fila
pf <- prop.table(tc, 1)
tabla_pf <- rbind(addmargins(pf, margin = 2)*100,
                  totC = c(colSums(tc)/sum(tc)*100, 100))
knitr::kable(tabla_pf, digits = 1,
      caption = "Perfiles fila: REPEAT x Estado Migratorio")
Perfiles fila: REPEAT x Estado Migratorio
Nativo 2da generación 1ra generación Sum
No repitió 97.6 0.4 1.9 100
Repitió 96.8 0.7 2.5 100
totC 97.4 0.5 2.1 100

Con este resultado podemos concluir que la mayoría de los estudiantes son nativos de sus países, con un total del 97,4%. El 97,6% de los estudiantes que no repitieron curso son de su país de origen y, además, el 96,8% de los estudiantes que sí repitieron curso también son de su país. Esto muestra que hay una tasa muy pequeña de estudiantes migrantes o estudiantes nativos con padres migrantes.

tc <- table(pisa$REPEAT, pisa$IMMIG)

# Perfiles columna
pc <- prop.table(tc, 2)
tabla_pc <- cbind(addmargins(pc, margin = 1)*100,
                  totF = c(rowSums(tc)/sum(tc)*100, 100))

knitr::kable(tabla_pc, digits = 1,
      caption = "Perfiles columna: REPEAT x Estado Migratorio")
Perfiles columna: REPEAT x Estado Migratorio
Nativo 2da generación 1ra generación totF
No repitió 75.1 64.8 69.9 75
Repitió 24.9 35.2 30.1 25
Sum 100.0 100.0 100.0 100

Podemos observar que, para los tres estados migratorios (Nativo, Nativo con papás extranjeros y completamente migrantes), se encuentra que más del 50% de los estudiantes no han repetido un curso. Algo de notar es que el porcentaje de estudiantes que han repetido al menos un curso es mayor para estudiantes que son nativos pero de papás extranjeros.

Para observar estas relaciones, grafiquemos ambos perfiles.

tc <- table(pisa$REPEAT, pisa$IMMIG)
paleta11 <- c("#E05A6D",   
              "#F4A6B0",  
              "#5FD04F",  
              "#B7E8A8",  
              "#2196E8",  
              "#A9D6F5",  
              "#9C3F52",  
              "#2E7D32",  
              "#1565A8",  
              "#F7C948",  
              "#8E6BBF")
# Gráficos de perfiles
par(mfrow = c(2,1), mai = c(0.4,1,0.3,0.1))
FactoClass::plotct(t(tc), "row", col = 2:5)
FactoClass::plotct(tc, "row", col = paleta11)

Continuamos con la variable REPEAT y el grado de los estudiantes.

tc <- table(pisa$REPEAT, pisa$GRADE)

# Perfiles fila
pf <- prop.table(tc, 1)
tabla_pf <- rbind(addmargins(pf, margin = 2)*100,
                  totC = c(colSums(tc)/sum(tc)*100, 100))
knitr::kable(tabla_pf, digits = 1,
      caption = "Perfiles fila: REPEAT x GRADO")
Perfiles fila: REPEAT x GRADO
3 grados por debajo 2 grados por debajo 1 grado por debajo Grado de referencia 1 grado por encima Sum
No repitió 0.5 1.2 7.4 75.0 15.9 100
Repitió 7.0 21.3 49.7 21.1 0.8 100
totC 2.2 6.3 18.2 61.2 12.1 100

Con este resultado podemos concluir que la mayoría de los 75% estudiantes que no han perdido un curso 75% se encuentran en el grado previsto, seguido de un 15,9% que se encuentra un grado por encima al previsto para el estudiante. Por otro lado, el grupo que tiene estudiantes que al menos repitieron un curso su mayoría se encuentra por debajo de al menos un curso previsto con un total del 78% de ellos, seguido de estudiantes que estan en el curso previsto para el estudiante con un total del 21,1%.

tc <- table(pisa$REPEAT, pisa$GRADE)

# Perfiles columna
pc <- prop.table(tc, 2)
tabla_pc <- cbind(addmargins(pc, margin = 1)*100,
                  totF = c(rowSums(tc)/sum(tc)*100, 100))

knitr::kable(tabla_pc, digits = 1,
      caption = "Perfiles columna: REPEAT x Grado")
Perfiles columna: REPEAT x Grado
3 grados por debajo 2 grados por debajo 1 grado por debajo Grado de referencia 1 grado por encima totF
No repitió 16.7 13.9 30.4 91.2 98.2 74.4
Repitió 83.3 86.1 69.6 8.8 1.8 25.6
Sum 100.0 100.0 100.0 100.0 100.0 100.0

Para los perfiles columna se puede obeservar que para estudiantes que estan por debajo de un grado al previsto es decir, las cetegorías -1,-2, -3, la mayoría de los estudiantes han repetido un curso, sin embargo, se puede observar que los porcentajes de estudiantes que nunca han perido no es tan bajo. Por otro lado, para categorías 0 y 1, se puede ver que poco más del 90% de los estudiantes no han perdido un curso y los porcentajes de los que sí, es muy bajo.

Para observar estas relaciones, grafiquemos ambos perfiles.

tc <- table(pisa$REPEAT, pisa$GRADE)

# Gráficos de perfiles
par(mfrow = c(2,1), mai = c(0.4,1,0.3,0.1))
FactoClass::plotct(t(tc), "row", col = 2:5)
FactoClass::plotct(tc, "row", col = paleta11)

Tenemos ahora una tabla del cruce entre la variable de repetir curso y niveles de los programas educativos.

tc <- table(pisa$REPEAT, pisa$ISCEDP )

# Perfiles fila
pf <- prop.table(tc, 1)
tabla_pf <- rbind(addmargins(pf, margin = 2)*100,
                  totC = c(colSums(tc)/sum(tc)*100, 100))
knitr::kable(tabla_pf, digits = 1,
      caption = "Perfiles fila: REPEAT x Niveles Educativos ")
Perfiles fila: REPEAT x Niveles Educativos
244 Sec. baja general 254 Sec. baja vocacional 344 Sec. alta general 354 Sec. alta vocacional Sum
No repitió 9.1 0.1 83.5 7.4 100
Repitió 78.0 0.0 18.6 3.4 100
totC 26.7 0.0 66.9 6.3 100

Podemos observar que los niveles de educación según la ISCEDP muestran que la mayoría de los estudiantes se encuentran en 244 y 344, como ya habíamos mencionado. En donde el 83,5% de los estudiantes que no repitieron curso son de un nivel 344, mientras que para los que sí repitieron curso su mayoría, con un 78%, son de un nivel 244.

tc <- table(pisa$REPEAT, pisa$ISCEDP)

# Perfiles columna
pc <- prop.table(tc, 2)
tabla_pc <- cbind(addmargins(pc, margin = 1)*100,
                  totF = c(rowSums(tc)/sum(tc)*100, 100))

knitr::kable(tabla_pc, digits = 1,
      caption = "Perfiles columna: REPEAT x Niveles Educativos")
Perfiles columna: REPEAT x Niveles Educativos
244 Sec. baja general 254 Sec. baja vocacional 344 Sec. alta general 354 Sec. alta vocacional totF
No repitió 25.4 87.5 92.9 86.4 74.5
Repitió 74.6 12.5 7.1 13.6 25.5
Sum 100.0 100.0 100.0 100.0 100.0

De esta tabla podemos resaltar algo interesante: para los casos 254, 344 y 354, se tiene que más del 80% de los estudiantes no han repetido un curso. Sin embargo, para el caso 244 pasa lo contrario, la mayoría de los estudiantes han repetido al menos un curso, con un total del 74,6%.

Grafiquemos esta relación.

tc <- table(pisa$REPEAT, pisa$ISCEDP)

# Gráficos de perfiles
par(mfrow = c(2,1), mai = c(0.4,1,0.3,0.1))
FactoClass::plotct(t(tc), "row", col = 2:5)
FactoClass::plotct(tc, "row", col = paleta11[1:ncol(tc)] )

Compararemos la variable REPEAT con la lengua que se habla en casa.

tc <- table(pisa$REPEAT, pisa$ LANGN )

# Perfiles fila
pf <- prop.table(tc, 1)
tabla_pf <- rbind(addmargins(pf, margin = 2)*100,
                  totC = c(colSums(tc)/sum(tc)*100, 100))
knitr::kable(tabla_pf, digits = 1,
      caption = "Perfiles fila: REPEAT x Lengua hablada en casa")
Perfiles fila: REPEAT x Lengua hablada en casa
Español Inglés Quechua 415 527 Ngäbe 562 563 565 566 567 631 641 673 674 810 841 890 Sin dato (999) Sum
No repitió 95.4 1.1 1.2 0 0.1 0.7 0.2 0.1 0.0 0 0 0.2 0.0 0.3 0 0.0 0.3 0.2 0.2 100
Repitió 94.1 0.8 1.1 0 0.0 1.3 0.5 0.1 0.2 0 0 0.2 0.1 0.6 0 0.2 0.2 0.2 0.4 100
totC 95.1 1.0 1.2 0 0.1 0.9 0.3 0.1 0.1 0 0 0.2 0.1 0.4 0 0.1 0.2 0.2 0.3 100

Podemos ver que, si bien hay varios idiomas, el que más predomina es el español, con un 95,1% de los estudiantes. Esto mismo pasa en los grupos de estudiantes que repiten y que no repiten: el 95,4% de los estudiantes que no repitieron hablan español, y el 94,1% de los estudiantes que sí repitieron tienen el dialecto de español.

langn_g <- as.character(pisa$LANGN)
langn_g[langn_g == "Sin dato (999)"] <- NA
langn_g[!(langn_g %in% c("Español", "Inglés", "Quechua", "Ngäbe")) & !is.na(langn_g)] <- "Otros idiomas"
langn_g <- factor(langn_g, levels = c("Español", "Inglés", "Quechua", "Ngäbe", "Otros idiomas"))
tc <- table(pisa$REPEAT, langn_g)


# Perfiles columna
pc <- prop.table(tc, 2)
tabla_pc <- cbind(addmargins(pc, margin = 1)*100,
                  totF = c(rowSums(tc)/sum(tc)*100, 100))

knitr::kable(tabla_pc, digits = 1,
      caption = "Perfiles columna: REPEAT x Lengua hablada en casa")
Perfiles columna: REPEAT x Lengua hablada en casa
Español Inglés Quechua Ngäbe Otros idiomas totF
No repitió 74.7 80 76.9 62.5 61 74.5
Repitió 25.3 20 23.1 37.5 39 25.5
Sum 100.0 100 100.0 100.0 100 100.0

Con los perfiles fila pudimos apreciar que la mayoría de los estudiantes hablaban español (156); aquí podemos ver que en esta lengua el 74,7% de los estudiantes no repiten curso, mientras que el 25,3% restante al menos ha repetido un curso. Como vimos en los perfiles fila, hay un sesgo para el idioma en los estudiantes, por lo que interpretar porcentajes de otras lenguas para perfiles columna podría ser algo erróneo.

Ahora veamos cómo se comportan estos perfiles gráficamente; va a haber varias categorías, sin embargo, debería apreciarse que el idioma español (156) predomina.

tc <- table(pisa$REPEAT, langn_g)

# Gráficos de perfiles
par(mfrow = c(2,1), mai = c(0.4,1,0.3,0.1))
FactoClass::plotct(t(tc), "row", col = 2:5)
FactoClass::plotct(tc, "row", col = paleta11[1:ncol(tc)])

Continuamos con el cruce entre REPEAT y EXPECEDU.

tc <- table(pisa$REPEAT, pisa$EXPECEDU )

# Perfiles fila
pf <- prop.table(tc, 1)
tabla_pf <- rbind(addmargins(pf, margin = 2)*100,
                  totC = c(colSums(tc)/sum(tc)*100, 100))
knitr::kable(tabla_pf, digits = 1,
      caption = "Perfiles fila: REPEAT x Máximo nivel previsto")
Perfiles fila: REPEAT x Máximo nivel previsto
ISCED 2 ISCED 3.3 ISCED 3.4 ISCED 4 ISCED 5 ISCED 6 ISCED 7 ISCED 8 Sum
No repitió 1.3 1.6 4.3 1.8 4.0 15.2 13.3 58.6 100
Repitió 5.6 2.9 6.2 2.8 5.1 16.8 12.0 48.6 100
totC 2.3 1.9 4.7 2.0 4.2 15.6 13.0 56.3 100

Con los perfiles file se puede establecer que parq ambos grupos de estudiantes, tanto que han repetido un curso y que nuna han repetido, el procentaje más alto se lo llevan los estudiantes que esperan un nivel máximo de Doctorado con 48,6% y 58,6% respectivamente, seguido en ambos casos por estudiantes que esperan un pregrado y por una maestría.

tc <- table(pisa$REPEAT, pisa$EXPECEDU)

# Perfiles columna
pc <- prop.table(tc, 2)
tabla_pc <- cbind(addmargins(pc, margin = 1)*100,
                  totF = c(rowSums(tc)/sum(tc)*100, 100))

knitr::kable(tabla_pc, digits = 1,
      caption = "Perfiles columna: REPEAT x Máximo nivel previsto")
Perfiles columna: REPEAT x Máximo nivel previsto
ISCED 2 ISCED 3.3 ISCED 3.4 ISCED 4 ISCED 5 ISCED 6 ISCED 7 ISCED 8 totF
No repitió 43.4 63.8 69.3 67.7 72 75 78.4 79.9 76.7
Repitió 56.6 36.2 30.7 32.3 28 25 21.6 20.1 23.3
Sum 100.0 100.0 100.0 100.0 100 100 100.0 100.0 100.0

Con los perfiles columna podemos observar que en todas las categorías excepto la categoría 2 () el porcentaje de estudiantes que nunca han repetido un curso es en todos los casos mayor al 50%. En la categoría 2 los estudiantes que repitieron un curso tiene un total del 56,6% de la muetsra para esa ctaegoría. Con esto se puede decir, que entre más nivel previsto de los estudiantes, se encuentran estudiantes que no han perdido un curso. Inclusive el porcentaje de estudiantes que no han perdido va aumentando cada que se busca un nivel mayor de estudio.

tc <- table(pisa$REPEAT, pisa$EXPECEDU)

par(mfrow = c(2,1), mai = c(0.4,1,0.3,0.1))
FactoClass::plotct(t(tc), "row", col = 2:5)
FactoClass::plotct(tc, "row", col = paleta11[1:ncol(tc)] )

Ahora analizaremos la repetición de un curso y si el estudiante trabaja por un pago.

tc <- table(pisa$REPEAT, pisa$WORKPAY  )

# Perfiles fila
pf <- prop.table(tc, 1)
tabla_pf <- rbind(addmargins(pf, margin = 2)*100,
                  totC = c(colSums(tc)/sum(tc)*100, 100))
knitr::kable(tabla_pf, digits = 1,
      caption = "Perfiles fila: REPEAT x Trabajo por pago")
Perfiles fila: REPEAT x Trabajo por pago
0 1 2 3 4 5 6 7 8 9 10 o más Sum
No repitió 47.0 4.8 9.8 4.4 7.5 5.6 5.4 2.5 3.7 1.4 7.9 100
Repitió 38.4 5.7 11.0 5.0 8.3 6.8 5.4 3.2 4.1 2.1 9.9 100
totC 44.9 5.0 10.1 4.6 7.7 5.9 5.4 2.7 3.8 1.6 8.4 100

Se puede observar que el 44,9% del total de los estudiantes no trabajan al menos una vez a la semana; además, notamos que dentro de los grupos, el 47% de los estudiantes que trabajan no pierden materias, seguido de estudiantes que trabajan al menos 2 veces por semana. En contraste, el 38,4% de los estudiantes que perdieron un curso no trabajan, seguido de un 11% de estudiantes que trabajan dos veces a la semana.

tc <- table(pisa$REPEAT, pisa$WORKPAY)

# Perfiles columna
pc <- prop.table(tc, 2)
tabla_pc <- cbind(addmargins(pc, margin = 1)*100,
                  totF = c(rowSums(tc)/sum(tc)*100, 100))

knitr::kable(tabla_pc, digits = 1,
      caption = "Perfiles columna: REPEAT x Trabajo por pago")
Perfiles columna: REPEAT x Trabajo por pago
0 1 2 3 4 5 6 7 8 9 10 o más totF
No repitió 79 72.4 73.4 73.1 73.6 71.7 75.5 70.8 73.5 67.2 71 75.5
Repitió 21 27.6 26.6 26.9 26.4 28.3 24.5 29.2 26.5 32.8 29 24.5
Sum 100 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100 100.0

Con esta tabla podemos observar que los estudiantes que no trabajan ni una sola hora por un pago tienen el mayor índice en estudiantes que no repiten curso, con un total del 79%. Para los estudiantes que trabajan, ya sean 1, 2, …, 10 o más días a la semana, se puede apreciar que el porcentaje de estudiantes que no pierden curso disminuye en comparación con los que no trabajan. Cabe resaltar que igual se tiene una mayor proporción de estudiantes que no trabajan, por lo que se puede llegar a considerar un sesgo.

Grafiquemos las relaciones entre perfiles fila y columna para ver estas diferencias entre grupos.

tc <- table(pisa$REPEAT, pisa$WORKPAY)

# Gráficos de perfiles
par(mfrow = c(2,1), mai = c(0.4,1,0.3,0.1))
FactoClass::plotct(t(tc), "row", col = 2:5)
FactoClass::plotct(tc, "row", col = paleta11[1:ncol(tc)])

Además, podemos relacionar REPEAT y trabajos domésticos.

tc <- table(pisa$REPEAT, pisa$WORKHOME   )

# Perfiles fila
pf <- prop.table(tc, 1)
tabla_pf <- rbind(addmargins(pf, margin = 2)*100,
                  totC = c(colSums(tc)/sum(tc)*100, 100))
knitr::kable(tabla_pf, digits = 1,
      caption = "Perfiles fila: REPEAT x  Trabajos Domésticos")
Perfiles fila: REPEAT x Trabajos Domésticos
0 1 2 3 4 5 6 7 8 9 10 o más Sum
No repitió 10.7 3.4 8.2 5.6 9.0 9.4 9.2 4.6 7.9 3.9 28.0 100
Repitió 12.8 4.0 8.0 5.2 7.9 9.8 7.5 4.6 6.5 4.0 29.7 100
totC 11.2 3.6 8.2 5.5 8.7 9.5 8.8 4.6 7.6 3.9 28.4 100

Para este caso notamos que el 28,4% de los estudiantes realizan trabajos un total de 10 o más en casa, seguido de estudiantes que no realizan ningún trabajo en casa. Para estudiantes que no repitieron curso, un 28% de ellos realizan más de 10 trabajos en casa; por otro lado, el 29,4% de los estudiantes que repitieron curso realizan 10 o más tareas domésticas.

tc <- table(pisa$REPEAT, pisa$WORKHOME)

# Perfiles columna
pc <- prop.table(tc, 2)
tabla_pc <- cbind(addmargins(pc, margin = 1)*100,
                  totF = c(rowSums(tc)/sum(tc)*100, 100))

knitr::kable(tabla_pc, digits = 1,
      caption = "Perfiles columna: REPEAT x Trabajos Domésticos")
Perfiles columna: REPEAT x Trabajos Domésticos
0 1 2 3 4 5 6 7 8 9 10 o más totF
No repitió 72 72.4 76 76.8 77.7 74.7 79 75.4 79.1 75 74.3 75.4
Repitió 28 27.6 24 23.2 22.3 25.3 21 24.6 20.9 25 25.7 24.6
Sum 100 100.0 100 100.0 100.0 100.0 100 100.0 100.0 100 100.0 100.0

Con esta tabla podemos ver que los estudiantes, que realizan o no trabajos domésticos, no tienen mucha diferencia entre repetir un curso o no. Para todos los casos, el porcentaje de estudiantes que no repiten un curso está por encima del 70%. Y los estudiantes que repiten curso son todos menores al 27,6%. Para esta categoría se tiene un poco más de equilibrio en el total de estudiantes que realizan trabajos y no en casa.

Ahora visualicemos estos perfiles.

tc <- table(pisa$REPEAT, pisa$WORKHOME)

# Gráficos de perfiles
par(mfrow = c(2,1), mai = c(0.4,1,0.3,0.1))
FactoClass::plotct(t(tc), "row", col = 2:5)
FactoClass::plotct(tc, "row", col = paleta11[1:ncol(tc)])

Por último, veremos la relación entre estudiantes que repiten curso y la duración en la primera infancia.

tc <- table(pisa$REPEAT, pisa$DURECEC  )

# Perfiles fila
pf <- prop.table(tc, 1)
tabla_pf <- rbind(addmargins(pf, margin = 2)*100,
                  totC = c(colSums(tc)/sum(tc)*100, 100))
knitr::kable(tabla_pf, digits = 1,
      caption = "Perfiles fila: REPEAT x Primera Infancia")
Perfiles fila: REPEAT x Primera Infancia
<1 año 1 a <2 2 a <3 3 a <4 4 a <5 5 a <6 6 a <7 7 a <8 8 o más Sum
No repitió 4.4 29.3 24.5 28.5 10.1 2.4 0.7 0.1 0.0 100
Repitió 9.1 44.0 20.9 15.5 7.4 2.1 0.8 0.2 0.1 100
totC 5.5 32.8 23.6 25.4 9.4 2.3 0.7 0.1 0.1 100

Aquí podemos notar que el 81,8% de los estudiantes se encuentran entre 1 y 3 años en esta primera instancia de infancia. Para el grupo de estudiantes que no repitió curso, el 29,3% de los estudiantes duró un año en esta instancia. Y para el grupo que sí repitió curso, el 44% también solo duró un año en la infancia.

tc <- table(pisa$REPEAT, pisa$DURECEC)

# Perfiles columna
pc <- prop.table(tc, 2)
tabla_pc <- cbind(addmargins(pc, margin = 1)*100,
                  totF = c(rowSums(tc)/sum(tc)*100, 100))

knitr::kable(tabla_pc, digits = 1,
      caption = "Perfiles columna: REPEAT x Duración en primera infancia")
Perfiles columna: REPEAT x Duración en primera infancia
<1 año 1 a <2 2 a <3 3 a <4 4 a <5 5 a <6 6 a <7 7 a <8 8 o más totF
No repitió 60.8 68.2 79 85.6 81.4 78.5 72.2 61.1 62.5 76.3
Repitió 39.2 31.8 21 14.4 18.6 21.5 27.8 38.9 37.5 23.7
Sum 100.0 100.0 100 100.0 100.0 100.0 100.0 100.0 100.0 100.0

Para esta variable tenemos un poco de sesgo para estudiantes que duraron 1, 2 y 3 años; para los otros, el porcentaje es muy bajo. Para estas tres categorías (1, 2 y 3), los porcentajes de no repetir son 68,2%, 79% y 85,6%, respectivamente. Para los otros años, el porcentaje de no pérdida es mayor al 60%. Para estas tres categorías (1, 2 y 3), en donde más estudiantes repitentes se encuentran es en la categoría 1, con un porcentaje del 31,8%, seguido de la categoría 2 con un 21% y finalmente la categoría 3 con un 14,4%.

tc <- table(pisa$REPEAT, pisa$DURECEC)

# Gráficos de perfiles
par(mfrow = c(2,1), mai = c(0.4,1,0.3,0.1))
FactoClass::plotct(t(tc), "row", col = 2:5)
FactoClass::plotct(tc, "row", col = paleta11[1:ncol(tc)])

Asociasión entre variable REPEAT y las demás cualitativas

5.2 Asociacion entre variables

knitr::kable(FactoClass::chisq.carac(pisa[, cuali_otras], pisa$REPEAT, decr = FALSE), digits = 5)
chi2 dfr pval tval phi2
CNT 1183.42 2 0.00000 34.271 0.06127
ST004D01T 159.43 1 0.00000 12.572 0.00825
IMMIG 10.06 2 0.00653 2.482 0.00052
GRADE 8661.33 4 0.00000 Inf 0.44840
ISCEDP 8497.30 3 0.00000 Inf 0.43991
LANGN 83.10 18 0.00000 6.223 0.00430
EXPECEDU 262.07 7 0.00000 15.257 0.01357
WORKPAY 107.81 10 0.00000 8.713 0.00558
WORKHOME 44.78 10 0.00000 4.575 0.00232
DURECEC 517.13 8 0.00000 21.894 0.02677

Con el paquete FactoClass y su función “chisq.carac()” podemos tomar nuestra variable cualitativa y compararla con las demás variables cualitativas. Con esta tabla podemos notar que la variables que tiene una asociación fuerte con la variable de REPEAT es ISCEDP y GRADE, teniendo un phi2 mayor a 0.4, asociaón más fuerte. Podemos observar que la segunda variable con mayor asociación con la variable REPEAT es CNT (país); sin embargo, este phi2 es mucho menor, dando así una asociación más débil. Por otro lado, podemos concluir que la variable que menos se asocia con REPEAT es IMMIG (estado migratorio), teniendo un phi2 de 0.00052, asociación que es muy débil.

FactoClass::cluster.carac(pisa[, cuali_otras], pisa$REPEAT)
class: No repitió
                                Test.Value p.Value Class.Cat Cat.Class Global
GRADE.Grado de referencia              Inf   0.000      87.5      74.9   60.6
ISCEDP.344 Sec. alta general           Inf   0.000      89.7      83.5   65.9
CNT.Perú                            37.449   0.000      86.5      44.1   36.1
GRADE.1 grado por encima            32.344   0.000      95.9      15.9   11.8
IMMIG.Nativo                        31.913   0.000      74.5      94.6   89.9
LANGN.Español                       30.693   0.000      74.1      95.4   91.2
DURECEC.3 a <4                      23.302   0.000      85.2      24.2   20.1
WORKPAY.0                           20.254   0.000      78.7      44.9   40.3
EXPECEDU.ISCED 8                    19.836   0.000      79.7      38.1   33.9
ST004D01T.Mujer                     12.382   0.000      74.8      53.1   50.3
DURECEC.2 a <3                      11.746   0.000      78.6      20.8   18.8
DURECEC.4 a <5                       9.388   0.000      81.1       8.6    7.5
ISCEDP.354 Sec. alta vocacional      8.135   0.000      80.5       7.4    6.5
WORKHOME.6                           7.314   0.000      78.6       8.9    8.0
EXPECEDU.ISCED 7                     6.870   0.000      78.2       8.6    7.8
WORKHOME.8                           6.777   0.000      78.6       7.7    6.9
WORKHOME.4                           6.143   0.000      77.4       8.7    8.0
WORKHOME.10 o más                    5.740   0.000      73.9      27.1   26.0
WORKHOME.2                           4.494   0.000      75.7       8.0    7.4
WORKHOME.3                           4.380   0.000      76.7       5.4    5.0
EXPECEDU.ISCED 6                     3.858   0.000      74.5       9.9    9.4
WORKHOME.5                           3.561   0.000      74.3       9.2    8.7
DURECEC.5 a <6                       3.280   0.001      78.1       2.1    1.9
WORKHOME.7                           3.015   0.003      75.2       4.5    4.2
WORKPAY.6                            2.971   0.003      74.8       5.2    4.9
LANGN.Inglés                         2.748   0.006      79.1       1.1    1.0
WORKPAY.2                            2.599   0.009      73.2       9.4    9.1
WORKHOME.9                           2.586   0.010      74.8       3.8    3.6
WORKPAY.4                            2.424   0.015      73.4       7.2    6.9
WORKPAY.9                           -2.013   0.044      65.9       1.3    1.4
LANGN.810                           -2.422   0.015      38.5       0.0    0.1
LANGN.673                           -2.515   0.012      56.9       0.3    0.3
EXPECEDU.ISCED 3.3                  -2.710   0.007      62.9       1.0    1.1
LANGN.565                           -2.914   0.004      27.3       0.0    0.1
LANGN.641                           -3.211   0.001      28.6       0.0    0.1
LANGN.Ngäbe                         -3.555   0.000      58.5       0.7    0.9
LANGN.562                           -4.074   0.000      44.4       0.2    0.3
DURECEC.1 a <2                      -5.259   0.000      67.9      24.9   26.0
CNT.Panamá                          -6.969   0.000      66.7      22.2   23.5
DURECEC.<1 año                      -7.224   0.000      59.6       3.7    4.4
EXPECEDU.ISCED 2                    -9.569   0.000      42.9       0.8    1.4
ST004D01T.Hombre                   -12.382   0.000      66.7      46.9   49.7
GRADE.3 grados por debajo          -25.023   0.000      14.7       0.5    2.3
CNT.Colombia                       -29.053   0.000      59.2      33.8   40.4
GRADE.2 grados por debajo             -Inf   0.000      12.6       1.2    6.6
GRADE.1 grado por debajo              -Inf   0.000      28.2       7.4   18.7
ISCEDP.244 Sec. baja general          -Inf   0.000      23.4       9.1   27.6
LANGN.Sin dato (999)                  -Inf   0.000       4.0       0.2    4.2
                                Weight
GRADE.Grado de referencia        11712
ISCEDP.344 Sec. alta general     12732
CNT.Perú                          6968
GRADE.1 grado por encima          2270
IMMIG.Nativo                     17360
LANGN.Español                    17612
DURECEC.3 a <4                    3888
WORKPAY.0                         7788
EXPECEDU.ISCED 8                  6542
ST004D01T.Mujer                   9708
DURECEC.2 a <3                    3625
DURECEC.4 a <5                    1442
ISCEDP.354 Sec. alta vocacional   1250
WORKHOME.6                        1547
EXPECEDU.ISCED 7                  1507
WORKHOME.8                        1341
WORKHOME.4                        1542
WORKHOME.10 o más                 5018
WORKHOME.2                        1439
WORKHOME.3                         971
EXPECEDU.ISCED 6                  1820
WORKHOME.5                        1684
DURECEC.5 a <6                     360
WORKHOME.7                         813
WORKPAY.6                          943
LANGN.Inglés                       187
WORKPAY.2                         1752
WORKHOME.9                         690
WORKPAY.4                         1338
WORKPAY.9                          279
LANGN.810                           13
LANGN.673                           65
EXPECEDU.ISCED 3.3                 221
LANGN.565                           11
LANGN.641                           14
LANGN.Ngäbe                        171
LANGN.562                           54
DURECEC.1 a <2                    5019
CNT.Panamá                        4544
DURECEC.<1 año                     853
EXPECEDU.ISCED 2                   268
ST004D01T.Hombre                  9608
GRADE.3 grados por debajo          448
CNT.Colombia                      7804
GRADE.2 grados por debajo         1273
GRADE.1 grado por debajo          3605
ISCEDP.244 Sec. baja general      5326
LANGN.Sin dato (999)               817
------------------------------------------------------------ 
class: Repitió
                                Test.Value p.Value Class.Cat Cat.Class Global
GRADE.2 grados por debajo              Inf   0.000      78.6      21.3    6.6
GRADE.1 grado por debajo               Inf   0.000      64.6      49.7   18.7
ISCEDP.244 Sec. baja general           Inf   0.000      68.7      78.0   27.6
CNT.Colombia                        30.133   0.000      35.7      59.3   40.4
GRADE.3 grados por debajo           22.285   0.000      73.7       7.0    2.3
DURECEC.1 a <2                      13.958   0.000      31.7      33.9   26.0
ST004D01T.Hombre                    12.410   0.000      28.1      57.6   49.7
EXPECEDU.ISCED 2                    11.168   0.000      56.0       3.2    1.4
DURECEC.<1 año                       9.432   0.000      38.5       7.0    4.4
LANGN.Español                        8.349   0.000      25.1      94.1   91.2
WORKPAY.10 o más                     4.193   0.000      28.7       9.0    7.6
EXPECEDU.ISCED 3.3                   3.934   0.000      35.7       1.7    1.1
WORKHOME.0                           3.914   0.000      27.8      11.7   10.3
IMMIG.Nativo                         3.599   0.000      24.6      91.2   89.9
EXPECEDU.ISCED 3.4                   3.531   0.000      30.5       3.6    2.8
LANGN.673                            3.403   0.001      43.1       0.6    0.3
LANGN.Ngäbe                          3.303   0.001      35.1       1.3    0.9
LANGN.565                            3.301   0.001      72.7       0.2    0.1
WORKPAY.9                            3.179   0.001      32.3       1.9    1.4
WORKPAY.5                            3.041   0.002      28.1       6.1    5.3
EXPECEDU.ISCED 4                     2.888   0.004      32.1       1.6    1.2
LANGN.810                            2.830   0.005      61.5       0.2    0.1
LANGN.562                            2.776   0.006      40.7       0.5    0.3
IMMIG.1ra generación                 2.606   0.009      29.7       2.3    1.9
WORKHOME.10 o más                    2.562   0.010      25.5      27.3   26.0
WORKPAY.7                            2.535   0.011      28.9       2.9    2.5
WORKPAY.2                            2.513   0.012      26.5       9.9    9.1
WORKPAY.1                            2.435   0.015      27.5       5.1    4.5
IMMIG.2da generación                 2.339   0.019      34.4       0.7    0.5
LANGN.563                            2.133   0.033      50.0       0.1    0.1
LANGN.641                            2.133   0.033      50.0       0.1    0.1
WORKHOME.1                           2.052   0.040      27.3       3.7    3.3
WORKPAY.4                            2.045   0.041      26.3       7.5    6.9
EXPECEDU.ISCED 5                     2.042   0.041      27.7       2.9    2.6
WORKHOME.4                          -2.276   0.023      22.2       7.3    8.0
CNT.Panamá                          -2.381   0.017      23.1      22.4   23.5
EXPECEDU.ISCED 7                    -2.856   0.004      21.5       6.9    7.8
WORKHOME.8                          -3.296   0.001      20.8       5.9    6.9
WORKHOME.6                          -3.407   0.001      20.9       6.9    8.0
DURECEC.2 a <3                      -5.522   0.000      20.9      16.1   18.8
DURECEC.4 a <5                      -5.550   0.000      18.5       5.7    7.5
WORKPAY.0                           -9.203   0.000      20.9      34.7   40.3
EXPECEDU.ISCED 8                   -10.092   0.000      20.0      27.9   33.9
ISCEDP.354 Sec. alta vocacional    -10.627   0.000      12.6       3.4    6.5
ST004D01T.Mujer                    -12.410   0.000      20.5      42.4   50.3
DURECEC.3 a <4                     -16.872   0.000      14.4      11.9   20.1
LANGN.Sin dato (999)               -18.178   0.000       2.2       0.4    4.2
CNT.Perú                           -30.278   0.000      12.3      18.3   36.1
GRADE.1 grado por encima           -32.206   0.000       1.7       0.8   11.8
GRADE.Grado de referencia             -Inf   0.000       8.5      21.1   60.6
ISCEDP.344 Sec. alta general          -Inf   0.000       6.9      18.6   65.9
                                Weight
GRADE.2 grados por debajo         1273
GRADE.1 grado por debajo          3605
ISCEDP.244 Sec. baja general      5326
CNT.Colombia                      7804
GRADE.3 grados por debajo          448
DURECEC.1 a <2                    5019
ST004D01T.Hombre                  9608
EXPECEDU.ISCED 2                   268
DURECEC.<1 año                     853
LANGN.Español                    17612
WORKPAY.10 o más                  1461
EXPECEDU.ISCED 3.3                 221
WORKHOME.0                        1984
IMMIG.Nativo                     17360
EXPECEDU.ISCED 3.4                 550
LANGN.673                           65
LANGN.Ngäbe                        171
LANGN.565                           11
WORKPAY.9                          279
WORKPAY.5                         1026
EXPECEDU.ISCED 4                   237
LANGN.810                           13
LANGN.562                           54
IMMIG.1ra generación               370
WORKHOME.10 o más                 5018
WORKPAY.7                          474
WORKPAY.2                         1752
WORKPAY.1                          874
IMMIG.2da generación                90
LANGN.563                           14
LANGN.641                           14
WORKHOME.1                         637
WORKPAY.4                         1338
EXPECEDU.ISCED 5                   494
WORKHOME.4                        1542
CNT.Panamá                        4544
EXPECEDU.ISCED 7                  1507
WORKHOME.8                        1341
WORKHOME.6                        1547
DURECEC.2 a <3                    3625
DURECEC.4 a <5                    1442
WORKPAY.0                         7788
EXPECEDU.ISCED 8                  6542
ISCEDP.354 Sec. alta vocacional   1250
ST004D01T.Mujer                   9708
DURECEC.3 a <4                    3888
LANGN.Sin dato (999)               817
CNT.Perú                          6968
GRADE.1 grado por encima          2270
GRADE.Grado de referencia        11712
ISCEDP.344 Sec. alta general     12732

Con esta tabla podemos ver las relaciones que hay entre cada grupo de repitentes y no repitentes con cada una de las categorías de las demás variables cualitativas. Primero hablemos del grupo 0, es decir, asociaciones de estudiantes que no repitieron curso: como primera variable tenemos el índice GRADE (0), seguido de ISCEDP (344), continuando con Perú con un índice de 37,49 y continuando con el estado de migración nativo. Por otro lado, hay una relación inversa con algunas categorías de ISCEDP (244) y los grados (-1 y -2) seguido de Colombia, con un índice de -29,053, seguido del género mujer con -12.382. Ahora, teniendo en cuenta el segundo grupo, en donde se encuentran los estudiantes que repitieron al menos un curso, vemos que la variable que más se relaciona es el grado tanto (-1 y -2), seguido de ISCEDP (244), además encontramos relaciones entre Colombia con un índice de 30.133, seguido de durar 1 año en la educación en primera infancia y seguido del género masculino con un valor de 12.410. Por otra parte, las variables que tienen relaciones inversas con el grupo de repetir un curso son el país de Perú, los grados 1 y 0 y el ISCEDP (344). Se puede notar que los dos grupos de estudiantes que repitieron y los que no repitieron tienen asociasiones inversamente proporcionales, categorías que se asocian positivamente con un grupo, se asocian negativamente con el otro grupo.

5.2.1 Variable REPEAT x Variable Cuantitativa

par(mfrow = c(1,3), mai = c(0.5,0.7,0.4,0.1), las = 1)
for (v in cuantitativas[1:3]) {
  boxplot(pisa[[v]] ~ pisa$REPEAT,
          main = paste(v, "según REPEAT"),
          xlab = "REPEAT", ylab = v,
          col = c("lightblue", "lightpink"))
}

Boxplot de REPEAT x AGE: Podemos observar que, para ambos grupos, la mediana de los dos grupos está alrededor de 15.8; se puede apreciar que la dispersión de la edad en ambos grupos es igual; sin embargo, podemos ver que la edad en los estudiantes que repiten un curso es mayor, iniciando desde casi 15.4.

Boxplot de REPEAT x PV1MATH: Con este gráfico podemos observar que la mediana del puntaje de matemáticas se encuentra más alta en el grupo de estudiantes que no repite curso; la dispersión en ambos grupos es muy parecida, siendo un poco más elevada en el grupo de estudiantes que nunca han repetido un curso. Por último, cabe resaltar que hay valores atípicos en ambos grupos; mirando los datos atípicos más altos, se puede apreciar que son más altos en el grupo de estudiantes que no han repetido curso.

Boxplot de REPEAT x PV1READ: Para el caso del puntaje de lectura pasa algo relativamente similar que con el puntaje de matemáticas. La mediana para estudiantes que nunca han repetido un curso es mayor a los que sí han repetido al menos un nivel; estas medianas están cerca de 410 puntos. La dispersión es parecida en ambos grupos, siendo un poco mayor en el grupo de 0. Ambos cuentan con valores atípicos en ambos extremos, siendo más elevados en el grupo de estudiantes que no han perdido curso.

par(mfrow = c(1,3), mai = c(0.5,0.7,0.4,0.1), las = 1)
for (v in cuantitativas[4:6]) {
  boxplot(pisa[[v]] ~ pisa$REPEAT,
          main = paste(v, "según REPEAT"),
          xlab = "REPEAT", ylab = v,
          col = c("lightblue", "lightpink"))
}

Boxplot de REPEAT x PV1SCIE:El caso de ciencias es parecido al puntaje de matemáticas y lectura. La mediana para estudiantes que nunca han repetido un curso es mayor a los que sí han repetido al menos un nivel, con un valor de más o menos 410. La dispersión es parecida en ambos grupos, siendo un poco mayor en el grupo de 0. Ambos cuentan con valores atípicos en ambos extremos, siendo más elevados en el grupo de estudiantes que no han perdido curso.

Boxplot de REPEAT x ESCS: Con este gráfico podemos observar que el índice socioeconómico de los estudiantes es más alto en el grupo de estudiantes que no repite curso; la dispersión en ambos grupos es muy parecida, siendo un poco más elevada en el grupo de estudiantes que nunca han repetido un curso. Por último, cabe resaltar que hay valores atípicos en ambos grupos.

Boxplot de REPEAT x ICTRES: En el índice ICTRES podemos ver que la mediana en ambos grupos es menor que 0, es decir, que se tienen más casos de estudiantes que no tienen tantas ayudas tecnológicas en casa; ambos cuentan con una dispersión muy parecida. Por último, ambos presentan outliers; sin embargo, los estudiantes que no han perdido cursos tienen estos valores más altos.

par(mfrow = c(1,3), mai = c(0.5,0.7,0.4,0.1), las = 1)
for (v in cuantitativas[7:9]) {
  boxplot(pisa[[v]] ~ pisa$REPEAT,
          main = paste(v, "según REPEAT"),
          xlab = "REPEAT", ylab = v,
          col = c("lightblue", "lightpink"))
}

Boxplot de REPEAT x BELONG:Se puede concluir que la mediana del sentido de pertenencia entre ambos grupos es un poco menor a 0; sin embargo, sugiere que los estudiantes que nunca han perdido un curso tienen un poco más de sentido de pertenencia en comparación con los que sí han perdido al menos un curso. Cuentan con una dispersión parecida en ambos grupos. En ambos grupos se tienen estudiantes con mayor y con menor sentido de pertenencia (outliers).

Boxplot de REPEAT x FEELSAFE: Se puede apreciar que, en ambos casos, los estudiantes de ambos grupos se suelen sentir seguros; sin embargo, los estudiantes que han repetido más cursos se sienten más seguros que los que no, por eso la dispersión aquí para el grupo de repitentes es ligeramente mayor.

Boxplot de REPEAT x ANXMAT: También tenemos un boxplot con el puntaje de ansiedad de matemáticas por ambos grupos, en donde la mediana se encuentra alrededor de 0.5. Hay una dispersión muy similar en ambos grupos e incluso los valores atípicos de ambos son parecidos. Esto quiere mostrar que no hay visualmente diferencias significativas entre ambos grupos en relación con el puntaje de ansiedad en matemáticas.

par(mfrow = c(1,2), mai = c(0.5,0.7,0.4,0.1), las = 1)
for (v in cuantitativas[10]) {
  boxplot(pisa[[v]] ~ pisa$REPEAT,
          main = paste(v, "según REPEAT"),
          xlab = "REPEAT", ylab = v,
          col = c("lightblue", "lightpink"))
}

Boxplot de REPEAT x MATHEFF:La mediana para el grupo de no repitentes es ligeramente más alta que el grupo de estudiantes que sí ha repetido al menos una vez un curso. La dispersión es un poco mayor en el grupo 1 en comparación con el grupo 0. Ambos cuentan con valores atípicos; sin embargo, el grupo de estudiantes que nunca ha repetido un curso cuenta con más de estos valores.

Podemos proseguir a observar la razón de correlaciones entre la variable REPEAT y las variables cuantitativas. Usaremos el paquete de FactoClass que cuenta con la función Centroides, esta función tiene algunos problemas con los valores que son NA, para eso primero mostraremos la cantidad de datos que son NA por variables cuantitativas

# NA por cada variable cuantitativa
sapply(pisa[, cuantitativas], function(x) sum(is.na(x)))
     AGE  PV1MATH  PV1READ  PV1SCIE     ESCS   ICTRES   BELONG FEELSAFE 
       0        0        0        0      709      821     1714     1534 
  ANXMAT  MATHEFF 
    5726     5197 

Miremos que porcentaje de datos se tienen

# NA por variable en porcentaje
round(sapply(pisa[, cuantitativas], function(x) mean(is.na(x))) * 100, 2)
     AGE  PV1MATH  PV1READ  PV1SCIE     ESCS   ICTRES   BELONG FEELSAFE 
    0.00     0.00     0.00     0.00     3.67     4.25     8.87     7.94 
  ANXMAT  MATHEFF 
   29.64    26.91 

Podemos ver que hay variables que tienen un porcentaje alto de NA, eliminar estos datos es un error, primero los quitaremos y usaremos la funcion Centroides (sin embargo imputar una gran cantidad de datos es algo incorrecto en la préctica)

pisa_imp <- na.omit(pisa[, c(cuantitativas, "REPEAT")])
FactoClass::centroids(pisa_imp[, cuantitativas], pisa_imp$REPEAT)$cr * 100
        AGE PV1MATH PV1READ PV1SCIE ESCS ICTRES BELONG FEELSAFE  ANXMAT MATHEFF
[1,] 0.1511   6.893     6.5   4.734 2.42  1.707 0.1563  0.00172 0.01936  0.4648

Sin embargo, hay variables que no tienen muchos valores NA o incluso no tienen NA, por lo que para estos casos podemos imputar esta pequeña cantidad de datos y poder hacer esta razón de correlación

#Usamos la función centroides para hallar la razón de correlación en porcentaje
vars_sin_na <- c("AGE", "PV1MATH", "PV1READ", "PV1SCIE")
FactoClass::centroids(pisa[, vars_sin_na], pisa$REPEAT)$cr * 100
         AGE PV1MATH PV1READ PV1SCIE
[1,] 0.07338   8.273   7.799    6.31

Por último, veremos la asociasión que tienen la variable REPEAT por grupo con respecto a las variables cuantitativas

FactoClass::cluster.carac(pisa[, cuantitativas], pisa$REPEAT,
              tipo.v = "co", v.lim = 2, dn = 2, dm = 2, neg = TRUE)
class: No repitió
        Test.Value Class.Mean Frequency Global.Mean
PV1MATH      43.12     398.12     13672      383.28
PV1READ      41.67     426.29     13672      408.39
PV1SCIE      37.99     424.24     13672      408.86
AGE          -3.49      15.85     13672       15.85
------------------------------------------------------------ 
class: Repitió
        Test.Value Class.Mean Frequency Global.Mean
AGE           3.75      15.86      4692       15.85
PV1SCIE     -32.44     372.78      4692      408.86
PV1READ     -36.33     365.48      4692      408.39
PV1MATH     -37.32     347.99      4692      383.28

Con esta tabla podemos observar que ocurre con cada grupo de la variable REPEAT. Primero veamos el grupo 0, es decir, estudiantes que no repiten curso, tienen un valor de Test.value de 43,12 en PV1MATH, 41,67 PV1READ y 37,99 en PV1SCIE, esto muestra que los estudiantes que no han repetido un curso tienen un rendimiento superior significativo al promedio en matemáticas, lectura y ciencias. Por el lado de la edad, se puede evidenciar que es un valor de -3,49, es decir, que la edad promedio de los estudiantes es ligeremente menor que la media global. Por otro lado, el grupo de repitentes ocurre lo contrario al grupo anterior, por lo general la edad promedio esta ligeramente encima del promedio global; y por los índices de matemáticas, lectura y ciencias, vemos que hay una relación complemente inversa, esto dice que, los estudiantes que repiten curso tienen un rendimientos significativamente inferior al promedio de estas áreas evaluadas.

5.3 Variable cuantitativa

5.3.1 Análisis de variable Cuantitativa ESCS

Al principio se denotó que se usaría una variable cuantitativa para hacer un análisis parecido al que acabamos de hacer. Para esto tomaremos la variable ESCS (índice económico y cultural de los estudiantes) y la contrastaremos con las demás variables.

Análisis bivariado entre ESCS y Variables Cualitativas

Lo primero que realizaremos, igual que en el caso anterior, es un gráfico boxplot, pues este gráfico nos muestra bien la relación de dispersión que tienen las variables.

par(mfrow = c(1,3), mai = c(0.5,0.7,0.4,0.1), las = 1)
for (v in cualitativas[1:3]) {
  boxplot(pisa$ESCS ~ pisa[[v]],
          main = paste(v, "según ESCS"),
          xlab = "v", ylab = "ESCS",
          col = c("lightblue", "lightgreen", "lightpink"))
}

Boxplot de ESCS x CNT: Este gráfico nos muestra que la mediana del nivel socioeconómico en los tres países es menor a 0, en donde se puede apreciar que la mediana de Panamá está un poco más por encima de Colombia y seguida de Perú. Las dispersiones son relativamente parecidas y, para los tres países, se tienen valores atípicos de niveles socioeconómicos más allá de -4.

Boxplot de ESCS x ST004D01T: Por sexo, se puede concluir que la mediana del nivel socioeconómico de los hombres está un poco más arriba que la de las mujeres; ambos grupos tienen esta mediana entre 0 y -2. Para ambos géneros se tienen valores atípicos con índices de niveles socioeconómicos más bajos.

Boxplot de ESCS x IMMIG: Con respecto al estado migratorio, habíamos mostrado que se tenía un sesgo debido a que había más estudiantes nativos que en los otros dos grupos, por mucha diferencia. Con este gráfico vemos que la mediana más alta es la de los estudiantes nativos con padres extranjeros, seguida de la de los completamente extranjeros y, por último, la de los nativos. Se puede apreciar que los estudiantes nativos son los que más dispersión presentan y, además, el grupo con más valores atípicos.

par(mfrow = c(1,2), mai = c(0.5,0.7,0.4,0.1), las = 1)
for (v in cualitativas[4:5]) {
  boxplot(pisa$ESCS ~ pisa[[v]],
          main = paste(v, "según ESCS"),
          xlab = "v", ylab = "ESCS",
          col = c("lightblue", "lightgreen", "lightpink"))
}

Boxplot de ESCS x GRADE:Con el boxplot podemos observar que la mediana más alta entre las categroías de Grade es la de el grupo de estudiantes que estan un nivel más alto al previsto, seguido de los que estan en el grado “correcto”. Podemos ver que esa mediana disminuye a medida que se baja el nivel previsto del estudiante. Podemos observar que se tienen valores atípicos, en donde la categoría 0, es la que más acumulación de estos tienen.

Boxplot de ESCS x REPEAT: Para los estudiantes que nunca han repetido un curso, se puede apreciar que tienen un índice económico más alto que los que sí repitieron al menos un curso; esto debido a que la mediana es un poco más alta. Ambos grupos presentan outliers significativos.

boxplot(ESCS ~ ISCEDP, data = pisa,
        main = "ESCS según ISCEDP",
        xlab = "País", ylab = "ESCS",
        col = c("lightblue", "lightgreen", "lightpink"))

Boxplot de ESCS x ISCEDP: Para la variable de nivel educativo según ISCEDP se había mencionado que la mayoría pertenecía al 344 y que el grupo de 254 tenía muy pocos estudiantes. Con este gráfico se puede ver que la mediana del grupo 254 es la más alta a comparación de los otros grupos, seguida de 344, 354 y, por último, 244. Los grupos que presentan valores atípicos con respecto al índice económico son el 244 y 344. Por último, el grupo 344 es el que más dispersión presenta en sus individuos.

boxplot(ESCS ~ LANGN, data = pisa,
        main = "ESCS según LANGN",
        xlab = "País", ylab = "ESCS",
        col = c("lightblue", "lightgreen", "lightpink"))

Boxplot de ESCS x LANGN: Para la lengua se tenía la mayor concentración de datos en la lengua español (156); acá se puede evidenciar que la mediana está por debajo de 0 y que, además, se presenta una gran concentración de valores atípicos en valores negativos, es decir, que se tienen índices socioeconómicos más bajos en lengua español.

par(mfrow = c(1,2), mai = c(0.5,0.7,0.4,0.1), las = 1)
for (v in cualitativas[8:9]) {
  boxplot(pisa$ESCS ~ pisa[[v]],
          main = paste(v, "según ESCS"),
          xlab = "v", ylab = "ESCS",
          col = c("lightblue", "lightgreen", "lightpink"))
}

Boxplot de ESCS x EXPECEDU:Con este gráfico podemos observar que la cateogría con una mediana más alta del índice económico es la cateogría 8 (estudiantes que preveen un nivel de maestría), seguido de estudiantes que esperan un dotorado. La dispersión entre grupos es muy parecida y todos los grupos, exceptuando la categoría 3, contienen datos atípicos en sus observaciones.

Boxplot de ESCS x WORKPAY:De este boxplot se puede notar que las medianas entre grupos son muy similares, sobresaliendo la mediana de estudiantes que no trabajan ni un solo día, se puede observar que los grupos son muy homogéneos entre sí. Casí todos los grupos presentan valores atípicos en cuento a nivel socioeconómico, siendo también el grupo de estudiantes que no trabajan el de mayor concentración de estos valores.

par(mfrow = c(1,2), mai = c(0.5,0.7,0.4,0.1), las = 1)
for (v in cualitativas[10:11]) {
  boxplot(pisa$ESCS ~ pisa[[v]],
          main = paste(v, "según ESCS"),
          xlab = "v", ylab = "ESCS",
          col = c("lightblue", "lightgreen", "lightpink"))
}

Boxplot de ESCS x WORKHOME: Los grupos son muy similares entre sí, las medianas por grupo no se sacan mucha diferencia y la que tiene un valor más alto en su mediana, son los estudiantes que realizan 4 trabajos en casa por semana. En cuanto a outliers podemos apreciar que el grupo que más valores de este tipo contiene son el grupo de individuos que hace 10 o más trabajos en casa.

Boxplot de ESCS x DURECEC:Por último, tenemos el gráfico de tiempo en primera infancia y nivel socioeconómico, en donde se puede ver que algunos grupos son homogéneos entre sí, mientras que otros pueden ser un poco diferentes. El grupo con la media más alta en los datos son el 7, cabe resaltar que para este caso se tenían más estudiantes en los grupos 1, 2 y 3; para estos tres grupos podemos observar que son las categorías que más valores atípicos en relación a nivel socioeconómico tienen.

5.4 Razón de Correlación entre ESCS y cada variable cualitativa

library(dplyr)
razones_cor <- sapply(cualitativas, function(v) {
  datos_sin_na <- na.omit(pisa[, c("ESCS", v)])
  FactoClass::centroids(datos_sin_na[, "ESCS", drop = FALSE], datos_sin_na[[v]])$cr * 100
})

tabla_cor <- data.frame(
  Variable = names(razones_cor),
  `Razon_Correlacion_PCT` = round(as.numeric(razones_cor), 2)
) %>%
  arrange(desc(Razon_Correlacion_PCT))

knitr::kable(
  tabla_cor,
  col.names = c("Variable Cualitativa", "Razón de Correlación (%)"),
  align = c("l", "c"),
  caption = "Razón de Correlación entre ESCS y cada variable cualitativa"
)
Razón de Correlación entre ESCS y cada variable cualitativa
Variable Cualitativa Razón de Correlación (%)
EXPECEDU 3.45
LANGN 2.99
GRADE 2.89
ISCEDP 2.84
DURECEC 2.80
WORKPAY 2.39
REPEAT 2.35
WORKHOME 0.47
CNT 0.38
ST004D01T 0.19
IMMIG 0.13

Con la tabla de razones de correlaciones podemos observar que hay variables que se relacionan, sin embargo, es una relación débil. Podemos ver que en las variables cualitativas la que mejor se relaciona con el índice Socioeconómico es EXPECEDU correspondiente al nivel educativo de los padres, seguido de la lengua con un porcentaje de 2,99% y el grado con un 2,89%. Vemos que las variables que menos relacionan con el índice ESCS son las veces que hace trabajos domésticos, el genero y el estado migratorio. Que estas asociasiones sean débiles pueden ser algo normal, como bien sabemos el ESCS se forma a partir de la combinación de varias variables, es decir, una sola variable por si sola no va a explicar mucho de este componente. Toca resaltar que se hizo uso de la función na.omit, en la práctica esta función imputa NA, cosa que ya se dijo que no es práctico por la cantidad de datos qeu se pueden borrar.

Ahora miremos la asociasión que tiene nuestra variable continua ESCS y las demás cualitativas, aquí usaremos el paquete FactoClass que contiene la función cluster.carac()

asoci_cuali <- na.omit(pisa[, c("ESCS", "CNT")])

FactoClass::cluster.carac(
  asoci_cuali[, "ESCS", drop = FALSE],
  cla = as.factor(asoci_cuali$CNT),
  tipo.v = "co",
  v.lim = 2,
  dn = 2,
  dm = 2,
  neg = TRUE
)
class: Colombia
     Test.Value Class.Mean Frequency Global.Mean
ESCS       5.16      -0.97      7459       -1.02
------------------------------------------------------------ 
class: Panamá
     Test.Value Class.Mean Frequency Global.Mean
ESCS       3.68      -0.96      4225       -1.02
------------------------------------------------------------ 
class: Perú
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -8.43      -1.12      6923       -1.02

Podemos visualizar que el valor del test es significativamente alto en todos los países con valores de 5.16, 3.68 y -8.43, sin embargo, si analizamos la media global y la comparamos con cada una de los países, todos estan muy cerca entre sí, el rango que tiene la media más alta -0.96 y -0,12 es de solamente 0.16 puntos.

asoci_cuali <- na.omit(pisa[, c("ESCS", "ST004D01T")])

FactoClass::cluster.carac(
  asoci_cuali[, "ESCS", drop = FALSE],
  cla = as.factor(asoci_cuali$ST004D01T),
  tipo.v = "co",
  v.lim = 2,
  dn = 2,
  dm = 2,
  neg = TRUE
)
class: Mujer
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -5.93      -1.08      9367       -1.02
------------------------------------------------------------ 
class: Hombre
     Test.Value Class.Mean Frequency Global.Mean
ESCS       5.93      -0.97      9240       -1.02

En el genero ocurre lo mismo, el valor del test es siginifativo en ambos generos (-5.93 para mujeres y 5.93 para hombres),lo que indica que cada grupo difiere significativamente de la media global del ESCS, sin embargo, la diferencia de medias entre los dos generos es de 0.11 puntos, es un rango mínimo. Además ambos grupos estan muy cerca a la media global, estando los hombres un poco más arriba con -0.97 y las mujeres un poco más abajo con -1.08.

asoci_cuali <- na.omit(pisa[, c("ESCS", "IMMIG")])

FactoClass::cluster.carac(
  asoci_cuali[, "ESCS", drop = FALSE],
  cla = as.factor(asoci_cuali$IMMIG),
  tipo.v = "co",
  v.lim = 2,
  dn = 2,
  dm = 2,
  neg = TRUE
)
class: Nativo
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -4.51      -1.01     17319          -1
------------------------------------------------------------ 
class: 2da generación
     Test.Value Class.Mean Frequency Global.Mean
ESCS       3.46      -0.56        90          -1
------------------------------------------------------------ 
class: 1ra generación
     Test.Value Class.Mean Frequency Global.Mean
ESCS        3.3       -0.8       370          -1

Respecto al estatus migratorio, se observaron diferencias estadísticamente significativas los estudiantes nativos presentaron una media de ESCS de -1.01, significativamente inferior a la media global, pues su valor del test fue -4.51, mientras que los estudiantes de primera generación y de segunda generación mostraron medias superiores con índices de -0.80 y -0.56 respectivamente y valores de test 3.30 y 3.46. El rango entre grupos fue de 0.45 puntos de ESCS. Es decir, que es posible que estudiantes migrantes o de papás migrantes pueden tener un poco más de cápital que estudiantes completamente nativos. Podemos resaltar que las razones de correlación fue de 0.13 revela que esta diferencia explica una porción mínima de la varianza total. De igual forma sabemos que para esta variable sabemos que hay un desbalanceo de las clases.

asoci_cuali <- na.omit(pisa[, c("ESCS", "GRADE")])

FactoClass::cluster.carac(
  asoci_cuali[, "ESCS", drop = FALSE],
  cla = as.factor(asoci_cuali$GRADE),
  tipo.v = "co",
  v.lim = 2,
  dn = 2,
  dm = 2,
  neg = TRUE
)
class: 3 grados por debajo
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -9.93      -1.62       408       -1.02
------------------------------------------------------------ 
class: 2 grados por debajo
     Test.Value Class.Mean Frequency Global.Mean
ESCS     -11.56      -1.42      1199       -1.02
------------------------------------------------------------ 
class: 1 grado por debajo
     Test.Value Class.Mean Frequency Global.Mean
ESCS     -14.51       -1.3      3450       -1.02
------------------------------------------------------------ 
class: Grado de referencia
     Test.Value Class.Mean Frequency Global.Mean
ESCS      15.11      -0.91     11317       -1.02
------------------------------------------------------------ 
class: 1 grado por encima
     Test.Value Class.Mean Frequency Global.Mean
ESCS       7.88      -0.83      2225       -1.02

Con esta prueba podemos observar que los valores del test muestran que todos los grupos tienen una media por grupo con diferencia significativa a la media global. Para la categoría 0, que es la clase con más estudiantes, aunque la media sea cercana a la global, el valor del test muestra quesa diferencia es importante. Otro aspecto es que la media por grupo cuando se ve prevee un curso menor, la media va disminuyendo y teniendo un mayor rango con respeto a la media glabla, en donde ya la cateogoría de estar 3 cursos por debajo al previsto es de -1.62 con test -9.93. Por otro lado el grupo con estudiantes por encima de un curso tiene una media de -0.83, lo cual indica que esta por encima de la media global.

asoci_cuali <- na.omit(pisa[, c("ESCS", "REPEAT")])

FactoClass::cluster.carac(
  asoci_cuali[, "ESCS", drop = FALSE],
  cla = as.factor(asoci_cuali$REPEAT),
  tipo.v = "co",
  v.lim = 2,
  dn = 2,
  dm = 2,
  neg = TRUE
)
class: No repitió
     Test.Value Class.Mean Frequency Global.Mean
ESCS      20.75      -0.91     13648       -1.02
------------------------------------------------------------ 
class: Repitió
     Test.Value Class.Mean Frequency Global.Mean
ESCS     -20.75      -1.34      4677       -1.02

Los estudiantes que nunca repitieron presentaron una media de ESCS de -0.91, significativamente superior a la media global, mientras que los estudiantes que sí repitieron mostraron una media de -1.34, significativamente inferior. La diferencia entre grupos fue de 0.43 puntos de ESCS, y el coeficiente anteriormente mencionado era de 2.35%.

asoci_cuali <- na.omit(pisa[, c("ESCS", "ISCEDP")])

FactoClass::cluster.carac(
  asoci_cuali[, "ESCS", drop = FALSE],
  cla = as.factor(asoci_cuali$ISCEDP),
  tipo.v = "co",
  v.lim = 2,
  dn = 2,
  dm = 2,
  neg = TRUE
)
class: 244 Sec. baja general
     Test.Value Class.Mean Frequency Global.Mean
ESCS     -22.34      -1.35      5057       -1.02
------------------------------------------------------------ 
class: 254 Sec. baja vocacional
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)
------------------------------------------------------------ 
class: 344 Sec. alta general
     Test.Value Class.Mean Frequency Global.Mean
ESCS      21.91      -0.88     12370       -1.02
------------------------------------------------------------ 
class: 354 Sec. alta vocacional
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)

Los estudiantes cuyos padres tienen educación secundaria baja (244) presentaron un ESCS promedio de -1.35, significativamente inferior a la media global con un test de-22.34, mientras que los estudiantes cuyos padres tienen educación terciaria (344) mostraron un ESCS de -0.88, significativamente superior con un test de 21.91. La diferencia entre ambos grupos fue de 0.47 puntos de ESCS. El nivel educativo de los padres es uno de los componentes con los que PISA construye el índice ESCS, por lo que existe una asociación esperada, como vimos anteriormente por la razon de correlación con unvalor del 2.84%. En los estudiantes analizados solo estuvieron presentes las categorías 244 y 344, por lo que el análisis se reduce a la comparación entre dos niveles educativos parentales.

asoci_cuali <- na.omit(pisa[, c("ESCS", "LANGN")])

FactoClass::cluster.carac(
  asoci_cuali[, "ESCS", drop = FALSE],
  cla = as.factor(asoci_cuali$LANGN),
  tipo.v = "co",
  v.lim = 2,
  dn = 2,
  dm = 2,
  neg = TRUE
)
class: Español
     Test.Value Class.Mean Frequency Global.Mean
ESCS      14.43      -0.99     17564       -1.02
------------------------------------------------------------ 
class: Inglés
     Test.Value Class.Mean Frequency Global.Mean
ESCS       6.39      -0.45       187       -1.02
------------------------------------------------------------ 
class: Quechua
     Test.Value Class.Mean Frequency Global.Mean
ESCS     -17.19      -2.44       220       -1.02
------------------------------------------------------------ 
class: 415
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)
------------------------------------------------------------ 
class: 527
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)
------------------------------------------------------------ 
class: Ngäbe
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -9.73      -1.93       171       -1.02
------------------------------------------------------------ 
class: 562
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -4.67      -1.81        53       -1.02
------------------------------------------------------------ 
class: 563
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)
------------------------------------------------------------ 
class: 565
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -3.54      -2.33        11       -1.02
------------------------------------------------------------ 
class: 566
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)
------------------------------------------------------------ 
class: 567
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -2.36      -3.07         2       -1.02
------------------------------------------------------------ 
class: 631
     Test.Value Class.Mean Frequency Global.Mean
ESCS       -2.3      -1.51        33       -1.02
------------------------------------------------------------ 
class: 641
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)
------------------------------------------------------------ 
class: 673
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -5.59      -1.87        65       -1.02
------------------------------------------------------------ 
class: 674
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)
------------------------------------------------------------ 
class: 810
     Test.Value Class.Mean Frequency Global.Mean
ESCS       -2.1      -1.74        13       -1.02
------------------------------------------------------------ 
class: 841
     Test.Value Class.Mean Frequency Global.Mean
ESCS       2.48      -0.56        44       -1.02
------------------------------------------------------------ 
class: 890
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)
------------------------------------------------------------ 
class: Sin dato (999)
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -5.13      -1.52       159       -1.02

El 94% de la muestra, como ya habíamos vistos, se concentra en la categoría 156 (español), con un ESCS prácticamente idéntico a la media global, lo que por sí solo explica poca varianza. Las categorías minoritarias, en contraste, mostraron sistemáticamente valores inferiores de ESCS, siendo las más destacadas 358 com media -2.44 y valor de test -17.19 y 561 con media -1.93 y valor de test -9.73. Estos resultados sugieren que los estudiantes que hablan en casa una lengua distinta a la lengua de la prueba tienden a provenir de hogares con menor nivel socioeconómico. Sin ambargo, volvemos a tener un problema de desbalanceo entre clases, muchas de las categorías minoritarias cuentan con tamaños muestrales muy reducidos.

asoci_cuali <- na.omit(pisa[, c("ESCS", "EXPECEDU")])

FactoClass::cluster.carac(
  asoci_cuali[, "ESCS", drop = FALSE],
  cla = as.factor(asoci_cuali$EXPECEDU),
  tipo.v = "co",
  v.lim = 2,
  dn = 2,
  dm = 2,
  neg = TRUE
)
class: ISCED 2
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -8.53      -1.44       268       -0.83
------------------------------------------------------------ 
class: ISCED 3.3
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -6.47      -1.34       221       -0.83
------------------------------------------------------------ 
class: ISCED 3.4
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -8.15      -1.23       550       -0.83
------------------------------------------------------------ 
class: ISCED 4
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -5.19      -1.23       236       -0.83
------------------------------------------------------------ 
class: ISCED 5
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -6.09      -1.15       494       -0.83
------------------------------------------------------------ 
class: ISCED 6
     Test.Value Class.Mean Frequency Global.Mean
ESCS       -5.8      -0.98      1818       -0.83
------------------------------------------------------------ 
class: ISCED 7
     Test.Value Class.Mean Frequency Global.Mean
ESCS       10.8      -0.52      1505       -0.83
------------------------------------------------------------ 
class: ISCED 8
     Test.Value Class.Mean Frequency Global.Mean
ESCS       8.74      -0.74      6538       -0.83

Se peude observar que conforme aumenta la expectativa educativa, el nivel socioeconómico promedio también se incrementa. Los estudiantes que esperan alcanzar solo educación secundaria baja (clase 2) presentaron el ESCS más bajo con media de -1.44, mientras que quienes esperan alcanzar un doctorado (clase 8) presentaron el ESCS más alto de -0.52. La diferencia entre ambos extremos es de 0.92 puntos de ESCS. En conjunto, los resultados indican que la expectativa educativa del estudiante es el factor individual esta asociado con su nivel socioeconómico de los estudiantes.

asoci_cuali <- na.omit(pisa[, c("ESCS", "WORKPAY")])

FactoClass::cluster.carac(
  asoci_cuali[, "ESCS", drop = FALSE],
  cla = as.factor(asoci_cuali$WORKPAY),
  tipo.v = "co",
  v.lim = 2,
  dn = 2,
  dm = 2,
  neg = TRUE
)
class: 0
     Test.Value Class.Mean Frequency Global.Mean
ESCS      19.75      -0.79      7776       -0.99
------------------------------------------------------------ 
class: 1
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -4.29      -1.16       872       -0.99
------------------------------------------------------------ 
class: 2
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -4.59      -1.12      1751       -0.99
------------------------------------------------------------ 
class: 3
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -4.04      -1.16       791       -0.99
------------------------------------------------------------ 
class: 4
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -3.69      -1.11      1337       -0.99
------------------------------------------------------------ 
class: 5
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -4.82      -1.17      1024       -0.99
------------------------------------------------------------ 
class: 6
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)
------------------------------------------------------------ 
class: 7
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -4.93      -1.26       474       -0.99
------------------------------------------------------------ 
class: 8
     Test.Value Class.Mean Frequency Global.Mean
ESCS       -4.5       -1.2       655       -0.99
------------------------------------------------------------ 
class: 9
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -4.03      -1.28       279       -0.99
------------------------------------------------------------ 
class: 10 o más
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -7.57      -1.22      1459       -0.99

Aquí podemos notar que estudiantes que no trabajan por un pago presentaron un ESCS promedio de -0.79, significativamente superior a la media global con un test de 19.75, mientras estudiantes que trabajan 10 veces o más a la semana por un pago mostraron valores de ESCS sistemáticamente inferiores entre -1.22 con test de -3.69. La diferencia entre ambos grupos es de aproximadamente 0.43 puntos de índice socioeconómico. Esto genera que una mayor prevalencia de trabajo remunerado entre estudiantes sugiere un menor nivel socioeconómico.

asoci_cuali <- na.omit(pisa[, c("ESCS", "WORKHOME")])

FactoClass::cluster.carac(
  asoci_cuali[, "ESCS", drop = FALSE],
  cla = as.factor(asoci_cuali$WORKHOME),
  tipo.v = "co",
  v.lim = 2,
  dn = 2,
  dm = 2,
  neg = TRUE
)
class: 0
     Test.Value Class.Mean Frequency Global.Mean
ESCS       -4.4      -1.11      1979       -0.99
------------------------------------------------------------ 
class: 1
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)
------------------------------------------------------------ 
class: 2
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)
------------------------------------------------------------ 
class: 3
     Test.Value Class.Mean Frequency Global.Mean
ESCS          5       -0.8       969       -0.99
------------------------------------------------------------ 
class: 4
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)
------------------------------------------------------------ 
class: 5
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)
------------------------------------------------------------ 
class: 6
     Test.Value Class.Mean Frequency Global.Mean
ESCS       3.25       -0.9      1544       -0.99
------------------------------------------------------------ 
class: 7
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)
------------------------------------------------------------ 
class: 8
     Test.Value Class.Mean Frequency Global.Mean
ESCS        2.9       -0.9      1341       -0.99
------------------------------------------------------------ 
class: 9
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)
------------------------------------------------------------ 
class: 10 o más
     Test.Value Class.Mean Frequency Global.Mean
ESCS      -5.18      -1.07      5013       -0.99

Para esta comparación podemos ver que solo cinco categorías estuvieron presentes en la submuestra (0, 3, 6, 8 y 10), con las categorías 1, 2, 4, 5, 7 y 9 completamente vacías. Las clases 3, 6 y 8 presentaron medias de ESCS ligeramente superiores a la media global -0.80, -0.90 y -0.90 respectivamente, mientras que las clases 0 y 10 mostraron medias inferiores -1.11 y -1.07. En conjunto, la evidencia indica que el trabajo en el hogar no constituye un factor relevante en la distribución del nivel socioeconómico enlos estudiantes analizados.

asoci_cuali <- na.omit(pisa[, c("ESCS", "DURECEC")])

FactoClass::cluster.carac(
  asoci_cuali[, "ESCS", drop = FALSE],
  cla = as.factor(asoci_cuali$DURECEC),
  tipo.v = "co",
  v.lim = 2,
  dn = 2,
  dm = 2,
  neg = TRUE
)
class: <1 año
     Test.Value Class.Mean Frequency Global.Mean
ESCS     -10.88      -1.47       848       -1.02
------------------------------------------------------------ 
class: 1 a <2
     Test.Value Class.Mean Frequency Global.Mean
ESCS     -14.79      -1.23      5014       -1.02
------------------------------------------------------------ 
class: 2 a <3
     Test.Value Class.Mean Frequency Global.Mean
ESCS       7.07      -0.89      3619       -1.02
------------------------------------------------------------ 
class: 3 a <4
     Test.Value Class.Mean Frequency Global.Mean
ESCS       7.32      -0.89      3886       -1.02
------------------------------------------------------------ 
class: 4 a <5
     Test.Value Class.Mean Frequency Global.Mean
ESCS       8.45      -0.76      1441       -1.02
------------------------------------------------------------ 
class: 5 a <6
     Test.Value Class.Mean Frequency Global.Mean
ESCS       5.21      -0.68       359       -1.02
------------------------------------------------------------ 
class: 6 a <7
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)
------------------------------------------------------------ 
class: 7 a <8
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)
------------------------------------------------------------ 
class: 8 o más
[1] Test.Value  Class.Mean  Frequency   Global.Mean
<0 rows> (or 0-length row.names)

Podemos concluir que los estudiantes que no asistieron a educación infantil (0) presentaron el ESCS más bajo de -1.47 con valor de test -10.88, seguidos por quienes asistieron menos de un año (1) con media de ESCS de 1.23 y valor de test -14.79. A partir de allí, el ESCS se incrementa de forma sostenida: quienes asistieron 1-2 años (2) y 2-3 años (3) mostraron un ESCS de -0.89, mientras que los que asistieron 3-4 años (4) y 4 o más años (5) alcanzaron -0.76 y -0.68 respectivamente. La diferencia entre los extremos (no asistió y estudiantes que asistieron más de 4 años) es de 0.79 puntos de ESCS. Estos muestran que hogares de mayor nivel socioeconómico acceden a ECEC desde edades más tempranas y por periodos más prolongados.

5.4.1 Variable ESCS y Variables Continuas

Ahora analizamos nuestra variable cuantitativa ESCS con las demás variables continuas; para esto tomaremos las variables cuantitativas sin nuestra variable de interés.

cuanti_otras <- setdiff(cuantitativas, "ESCS")

Ahora, de la matriz de correlaciones entre las variables cuantitativas, tomemos la fila de nuestra variable de interés y comparemos con las demás.

knitr::kable(cor(pisa[, c("ESCS", cuanti_otras)], use = "complete.obs"),
      digits = 2,
      caption = "Correlaciones de ESCS con las demás cuantitativas")
Correlaciones de ESCS con las demás cuantitativas
ESCS AGE PV1MATH PV1READ PV1SCIE ICTRES BELONG FEELSAFE ANXMAT MATHEFF
ESCS 1.00 -0.04 0.40 0.39 0.39 0.73 0.09 0.07 -0.03 0.17
AGE -0.04 1.00 0.02 0.02 0.03 -0.03 0.00 -0.01 0.00 0.03
PV1MATH 0.40 0.02 1.00 0.79 0.84 0.37 0.13 -0.01 -0.17 0.31
PV1READ 0.39 0.02 0.79 1.00 0.77 0.37 0.11 -0.03 -0.06 0.22
PV1SCIE 0.39 0.03 0.84 0.77 1.00 0.37 0.12 -0.01 -0.12 0.26
ICTRES 0.73 -0.03 0.37 0.37 0.37 1.00 0.11 0.07 -0.03 0.15
BELONG 0.09 0.00 0.13 0.11 0.12 0.11 1.00 0.29 -0.10 0.16
FEELSAFE 0.07 -0.01 -0.01 -0.03 -0.01 0.07 0.29 1.00 -0.06 0.11
ANXMAT -0.03 0.00 -0.17 -0.06 -0.12 -0.03 -0.10 -0.06 1.00 -0.30
MATHEFF 0.17 0.03 0.31 0.22 0.26 0.15 0.16 0.11 -0.30 1.00

Con esta matriz de correlaciones podemos observar que el índice cultural y económico tiene una relación “directa” con la variable ICTRES, con un valor de 0.73, que es una relación moderada; variables como el puntaje de matemáticas, lectura y ciencia también alcanzan a sustentar una relación con ESCS. Por otra parte, hay variables que se correlacionan de manera negativa y, además, es una relación débil; variables como la edad y el nivel de ansiedad en matemáticas.

knitr::kable(var(pisa[, cuantitativas], use = "complete.obs"),
      digits = 2,
      caption = "Matriz de varianzas y covarianzas muestrales")
Matriz de varianzas y covarianzas muestrales
AGE PV1MATH PV1READ PV1SCIE ESCS ICTRES BELONG FEELSAFE ANXMAT MATHEFF
AGE 0.08 0.48 0.61 0.81 -0.01 -0.01 0.00 0.00 0.00 0.01
PV1MATH 0.48 5418.17 5311.45 5378.75 35.28 35.80 8.52 -0.46 -12.05 24.95
PV1READ 0.61 5311.45 8241.30 6034.46 42.56 43.83 9.00 -2.79 -5.39 21.91
PV1SCIE 0.81 5378.75 6034.46 7548.84 40.90 41.43 9.17 -0.45 -10.63 24.80
ESCS -0.01 35.28 42.56 40.90 1.43 1.13 0.10 0.08 -0.03 0.22
ICTRES -0.01 35.80 43.83 41.43 1.13 1.69 0.13 0.09 -0.04 0.21
BELONG 0.00 8.52 9.00 9.17 0.10 0.13 0.83 0.26 -0.09 0.16
FEELSAFE 0.00 -0.46 -2.79 -0.45 0.08 0.09 0.26 0.99 -0.06 0.12
ANXMAT 0.00 -12.05 -5.39 -10.63 -0.03 -0.04 -0.09 -0.06 0.98 -0.32
MATHEFF 0.01 24.95 21.91 24.80 0.22 0.21 0.16 0.12 -0.32 1.17

Lo primero a mencionar es que la varianza de nuestra variable ESCS, que está estandarizada (con media 0 y desviación estándar 1, según la OCDE), es de 1.43, lo que indica que hay buena dispersión en el nivel socioeconómico de los estudiantes. Ya con las otras variables, se puede concluir que los puntajes en matemáticas, lectura y ciencia son elevados, lo que respalda la relación que habíamos visto anteriormente. Anteriormente vimos que la variable que más se relaciona es ICTRES; acá observamos que la varianza y covarianza es de 1.13. Se encuentran algunas relaciones inversas con la misma edad y ansiedad matemática que se había ya mostrado. Para este punto es necesario mencionar que esta matriz de covarianzas puede verse afectada por unidades de medida, por lo que es mejor analizar la matriz de correlaciones.

n <- nrow(na.omit(pisa[, cuantitativas]))
knitr::kable(var(pisa[, cuantitativas], use = "complete.obs") * (n-1)/n,
      digits = 2,
      caption = "Matriz de varianzas y covarianzas poblacionales")
Matriz de varianzas y covarianzas poblacionales
AGE PV1MATH PV1READ PV1SCIE ESCS ICTRES BELONG FEELSAFE ANXMAT MATHEFF
AGE 0.08 0.48 0.61 0.81 -0.01 -0.01 0.00 0.00 0.00 0.01
PV1MATH 0.48 5417.76 5311.04 5378.34 35.28 35.80 8.52 -0.46 -12.05 24.95
PV1READ 0.61 5311.04 8240.67 6034.00 42.56 43.83 9.00 -2.79 -5.39 21.91
PV1SCIE 0.81 5378.34 6034.00 7548.26 40.90 41.43 9.17 -0.45 -10.63 24.80
ESCS -0.01 35.28 42.56 40.90 1.43 1.13 0.10 0.08 -0.03 0.22
ICTRES -0.01 35.80 43.83 41.43 1.13 1.69 0.13 0.09 -0.04 0.21
BELONG 0.00 8.52 9.00 9.17 0.10 0.13 0.83 0.26 -0.09 0.16
FEELSAFE 0.00 -0.46 -2.79 -0.45 0.08 0.09 0.26 0.99 -0.06 0.12
ANXMAT 0.00 -12.05 -5.39 -10.63 -0.03 -0.04 -0.09 -0.06 0.98 -0.32
MATHEFF 0.01 24.95 21.91 24.80 0.22 0.21 0.16 0.12 -0.32 1.17

Con esta matriz podemos ver que el índice ESCS presentó covarianzas positivas moderadas con las tres competencias matmáticas con covarianza 35.29, 42.56 con lectura y 40,92 con ciencias, lo que confirma la asociación esperada entre nivel socioeconómico y rendimiento académico. En contraste, las covarianzas de ESCS con variables socioemocionales fueron prácticamente nulas: BELONG (0.10), FEELSAFE (0.08), ANXMAT (-0.03), lo que sugiere que el bienestar emocional y la ansiedad matemática no están linealmente asociados con el nivel socioeconómico dentro de los estudiantes. Cabe resaltar que, al estar las variables en escalas distintas, las covarianzas no son directamente comparables entre pares.

6 Referencias

Adrogué, Cecilia, and María Eugenia Orlicki. 2025. “Desigualdad de Aprendizajes En América Latina. Un Análisis Con Datos de PISA 2022.” Asociación Argentina de Economía Política. https://aaep.org.ar/works/works2025/4825.pdf.
Icfes. 2024. “Programa Para La Evaluación Internacional de Alumnos (PISA). Informe Nacional de Resultados Para Colombia 2022.” Icfes. https://www.mineducacion.gov.co/1780/articles-421217_recurso_03.pdf.
Laboratorio de Economía de la Educación (LEE). 2025. “Entre Pantallas y Aprendizajes: Uso de Dispositivos Digitales En Colombia Según PISA 2022.” 121. Pontificia Universidad Javeriana. https://www.javeriana.edu.co/recursosdb/d/lee/inf121-uso-de-dispositivos-pisa-lee-2025.
Mateauda, Joaquín, and Gilbert Valverde. 2026. “Trascendiendo El Mundo Cognitivo de PISA: Habilidades Socioemocionales y Rendimiento Matemático En Uruguay (PISA 2022).” In Gobernanza y Liderazgo Para La Justicia Global, edited by A. Tejera Techera and J. Gairín Sallán, 51–67. CRIEDO-UAB. https://dialnet.unirioja.es/servlet/articulo?codigo=10832224.
OCDE. 2023. PISA 2022 Results (Volume i): The State of Learning and Equity in Education. OECD Publishing. https://doi.org/10.1787/53f23881-en.
———. 2024. PISA 2022 Technical Report. OECD Publishing. https://doi.org/10.1787/01820d6d-en.