# itan

    library(itan)

# Análisis de Ítems de Pruebas Objetivas

## Introducción

El paquete itan tiene como finalidad ayudar a profesores a corregir, calificar y analizar pruebas objetivas. Para ello, este paquete incluye funciones que permiten calcular el puntaje y calificación obtenido por estudiantes; así como también, funciones para analizar los ítems del test. Entre estas últimas destaca el análisis gráfico de ítems que permite visualizar las características técnicas del ítem y determinar rápidamente su calidad.

## Datos de ejemplo

El paquete itan incluye dos archivos de ejemplo. El archivo datos.csv contiene las respuestas de 39 estudiantes a una prueba de 50 ítems y el archivo clave.csv contiene las respuestas correctas a cada ítem.

Los siguientes comandos cargan estos archivos en el entorno global.

    datos.csv <- system.file("extdata", "datos.csv", package = "itan", mustWork = TRUE)
    datos <- read.csv(datos.csv, na = c("*"))

    clave.csv <- system.file("extdata", "clave.csv", package = "itan", mustWork = TRUE)
    clave <- read.csv(clave.csv)

Como se puede apreciar, `datos` corresponde a un data frame con 39 observaciones y 51 variables. La primera variable correponde al identificador de cada estudiante. El resto de las columnas corresponde a los ítems de la prueba. Las alternativas posibles a cada ítem son A, B, C, D y E. Las preguntas omitidas se indican mediante un “*”. Nótese que al momento de importar los datos se usa el parámetro `na = c("*")` para transformar estas respuestas a valores `NA`. Esto es importante para evitar errores y distorsiones en las funciones que analizan los ítems.

    head(datos)
    #>          id  i01  i02  i03  i04  i05  i06  i07  i08 i09 i10 i11 i12  i13  i14
    #> 1 200040629    E    D    C    B    A    C    C    D   E   B   E   A    C    A
    #> 2 210047876    C    D    C    B    C    B    B    D   D   B   E   D    E    B
    #> 3 210047897    E    D    C    B    A    C    B    D   E   C   D   A    E    B
    #> 4 210040939    E    D    A    B    A    C    C    E   B   A   A   D <NA> <NA>
    #> 5 200035827 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>   B   C   D   A    C <NA>
    #> 6 200039332    E    D    C    D    A    C    C    D   C   C   D   A    E    B
    #>    i15  i16  i17  i18  i19  i20  i21  i22  i23  i24  i25  i26  i27 i28 i29  i30
    #> 1    D    C    B    E    B    C    E    B    E    E    E    E    E   B   A    A
    #> 2    B    C    D    E    B    E    B    C    E    C    B    E    C   D   E    B
    #> 3    D    C    C    E    B    E    D    D    E    D    E    D    E   B   A    D
    #> 4 <NA> <NA> <NA> <NA>    B    A    E    B    E    C <NA>    E <NA>   B   A <NA>
    #> 5 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>    A   A   A    B
    #> 6    B    C    A    D    C    E    B    B    D    D    B    D    C   B   A    B
    #>    i31 i32 i33 i34 i35  i36 i37 i38 i39 i40 i41 i42 i43 i44 i45  i46  i47  i48
    #> 1    C   C   B   C   A    C   B   D   A   B   A   D   D   E   C    A    A    E
    #> 2    C   C   C   D   A    C   E   C   A   D   D   B   C   E   C    A    C    D
    #> 3    E   C   A   C   A    E   B   D   A   B   A   C   C   E   C    D    E    D
    #> 4 <NA>   C   B   C   A <NA>   B   C   A   B   A   D   C   E   C <NA>    C    E
    #> 5    C   C   B   C   A    C   B   C   A   B   A   B   C   D   D    D <NA> <NA>
    #> 6    B   C   B   A   A    B   C   D   A   C   D   D   A   C   D    B    B    B
    #>    i49  i50
    #> 1    A    D
    #> 2    C    C
    #> 3    C    D
    #> 4    A    D
    #> 5 <NA> <NA>
    #> 6    B    D

Por otra parte, clave también es un data frame, pero contiene una sola observación y 50 variables. Corresponde a las respuestas correctas a cada pregunta de la prueba.

    clave
    #>   i01 i02 i03 i04 i05 i06 i07 i08 i09 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19
    #> 1   E   D   C   B   A   C   C   E   B   C   D   A   C   A   D   C   B   E   B
    #>   i20 i21 i22 i23 i24 i25 i26 i27 i28 i29 i30 i31 i32 i33 i34 i35 i36 i37 i38
    #> 1   C   E   B   A   C   E   D   E   A   A   D   C   C   B   C   A   C   B   C
    #>   i39 i40 i41 i42 i43 i44 i45 i46 i47 i48 i49 i50
    #> 1   A   B   A   D   C   E   C   D   C   E   A   D

## Corrección de respuestas

Para corregir las respuestas de los estudiantes es necesario en primer lugar quitar la columna de identificación. El data frame con las respuestas sin el id del estudiante, junto con la clave de corrección, pueden ingresarse como argumentos en la función corregirRespuestas para obtener un data frame con unos y ceros. El 1 significa que el estudiante seleccionó la respuesta correcta, mientras que el 0 significa que seleccionó la respuesta incorrecta u omitió esta pregunta.

    respuestas <- datos[,-1]
    respuestasCorregidas <- corregirRespuestas(respuestas, clave)
    head(respuestasCorregidas)
    #>   i01 i02 i03 i04 i05 i06 i07 i08 i09 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19
    #> 1   1   1   1   1   1   1   1   0   0   0   0   1   1   1   1   1   1   1   1
    #> 2   0   1   1   1   0   0   0   0   0   0   0   0   0   0   0   1   0   1   1
    #> 3   1   1   1   1   1   1   0   0   0   1   1   1   0   0   1   1   0   1   1
    #> 4   1   1   0   1   1   1   1   1   1   0   0   0   0   0   0   0   0   0   1
    #> 5   0   0   0   0   0   0   0   0   1   1   1   1   1   0   0   0   0   0   0
    #> 6   1   1   1   0   1   1   1   0   0   1   1   1   0   0   0   1   0   0   0
    #>   i20 i21 i22 i23 i24 i25 i26 i27 i28 i29 i30 i31 i32 i33 i34 i35 i36 i37 i38
    #> 1   1   1   1   0   0   1   0   1   0   1   0   1   1   1   1   1   1   1   0
    #> 2   0   0   0   0   1   0   0   0   0   0   0   1   1   0   0   1   1   0   1
    #> 3   0   0   0   0   0   1   1   1   0   1   1   0   1   0   1   1   0   1   0
    #> 4   0   1   1   0   1   0   0   0   0   1   0   0   1   1   1   1   0   1   1
    #> 5   0   0   0   0   0   0   0   0   1   1   0   1   1   1   1   1   1   1   1
    #> 6   0   0   1   0   0   0   1   0   0   1   0   0   1   1   0   1   0   0   0
    #>   i39 i40 i41 i42 i43 i44 i45 i46 i47 i48 i49 i50
    #> 1   1   1   1   1   0   1   1   0   0   1   1   1
    #> 2   1   0   0   0   1   1   1   0   1   0   0   0
    #> 3   1   1   1   0   1   1   1   1   0   0   0   1
    #> 4   1   1   1   1   1   1   1   0   1   1   1   1
    #> 5   1   1   1   0   1   0   0   1   0   0   0   0
    #> 6   1   0   0   1   0   0   0   0   0   0   0   1

## Cálculo de puntajes y notas

Las respuestas corregidas pueden usarse para calcular el puntaje obtenido por cada estudiante y, posteriormente, calcular la nota correspondiente.

    puntaje <- calcularPuntajes(respuestasCorregidas)
    nota <- calcularNotas(puntaje)
    resultados <- cbind(id=datos$id, puntaje, nota)
    resultados <- resultados[order(resultados[,3], decreasing = TRUE),]
    head(resultados)
    #>           id puntaje nota
    #> 19 190019730      43  7.0
    #> 7  200040360      38  6.1
    #> 12 210047900      38  6.1
    #> 1  200040629      37  6.0
    #> 8  210047865      33  5.3
    #> 11 200032766      33  5.3
    summary(nota)
    #>    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
    #>   1.600   2.900   3.300   3.654   4.400   7.000

## Análisis de ítems

El paquete itan posee funciones que permiten analizar los ítems de pruebas objetivas. Es posible calcular el índice de dificultad, la frecuencia de cada alternativa, índices de discriminación tipo 1 y tipo2, y realizar un análisis gráfico de los ítems.

### Índice de dificultad

El índice de dificultad de un ítem muestra la proporción de aciertos. Sus valores van de 0 a 1, siendo 0 un ítem muy difícil y 1 un ítem muy fácil.

Para su cálculo pueden considerarse las respuestas de todos los estudiantes, o solo las de los estudiantes con mejor y peor desempeño. Esto se indica como argumento del parámetro proporcion en la función calcularIndiceDificultad:

    p <- calcularIndiceDificultad(respuestasCorregidas, proporcion = 0.25)
    p
    #>  i01  i02  i03  i04  i05  i06  i07  i08  i09  i10  i11  i12  i13  i14  i15  i16
    #> 0.75 0.95 0.60 0.60 0.55 0.70 0.55 0.35 0.35 0.55 0.20 0.70 0.45 0.40 0.50 0.60
    #>  i17  i18  i19  i20  i21  i22  i23  i24  i25  i26  i27  i28  i29  i30  i31  i32
    #> 0.50 0.45 0.50 0.25 0.45 0.50 0.30 0.45 0.15 0.25 0.30 0.15 0.65 0.15 0.45 0.65
    #>  i33  i34  i35  i36  i37  i38  i39  i40  i41  i42  i43  i44  i45  i46  i47  i48
    #> 0.45 0.55 0.75 0.20 0.70 0.10 0.55 0.50 0.60 0.40 0.60 0.55 0.60 0.30 0.10 0.25
    #>  i49  i50
    #> 0.35 0.60

En el ejemplo anterior se calcula el índice de dificultad considerando el 25% de los estudiantes con menores puntajes y el 25% con mejores puntuaciones. Una proporción de 0.5 indica que se toman todos los resultados.

### Índices de discriminación

Los índices de discriminación expresan en qué medida una pregunta diferencia entre estudiantes con mejor y peor desempeño. Existen distintas maneras de calcular este indicador. Estas se muestran a continuación.

#### Índice de discriminación tipo 1

Corresponde a la diferencia entre la proporción de aciertos del grupo superior, menos la proporción de aciertos en el grupo inferior. Como ambos grupos son de igual tamaño, su cálculo puede obtenerse mediante la siguiente ecuación.

\[ dc1 = \frac{A_s - A_i}{N} \]

A mayor diferencia entre los aciertos del grupo superior e inferior, mayor es poder de discriminación del ítem. Los valores máximos de este índice son -1 y 1. Un índice de 1 significa que todos los estudiantes del grupo superior acertaron esta pregunta, mientras que nadie del grupo inferior lo hizo. En otras palabras, el ítem discrimina muy bien entre estudiantes que saben y los que no. Un índice -1 indica todo lo contrario; todos los estudiantes del grupo inferior acertaron, mientras que nadie del grupo superior respondió correctamente este ítem. Las preguntas con índices negativos deben ser revisadas ya que es probable que éstas estén mal formuladas, sean ambiguas o que la la clave de corrección sea incorrecta.

    # Se toma el 27% de los estudiantes con mejor y peor desempeño
    # para conformar los grupos superior e inferior.
    dc1 <- calcularIndiceDiscriminacion(respuestasCorregidas, tipo = "dc1", proporcion = 0.25)
    dc1
    #>  i01  i02  i03  i04  i05  i06  i07  i08  i09  i10  i11  i12  i13  i14  i15  i16
    #>  0.3 -0.1  0.0  0.6  0.7  0.2  0.5  0.5  0.3  0.5  0.2  0.2  0.3  0.4  0.6  0.6
    #>  i17  i18  i19  i20  i21  i22  i23  i24  i25  i26  i27  i28  i29  i30  i31  i32
    #>  0.4  0.9  0.8 -0.3  0.7  0.6  0.0  0.5  0.3 -0.1  0.2 -0.3  0.7  0.3  0.5  0.7
    #>  i33  i34  i35  i36  i37  i38  i39  i40  i41  i42  i43  i44  i45  i46  i47  i48
    #>  0.9  0.9  0.5  0.4  0.6  0.0  0.7  0.8  0.8  0.8  0.6  0.9  0.8  0.6  0.0  0.5
    #>  i49  i50
    #>  0.7  0.4

Este índice depende del nivel de dificultad de la pregunta. Si la pregunta es muy fácil (ambos grupos la responden bien) o muy difícil (ambos grupos la responden mal) el índice tiene un valor de 0. Esto no indica que la pregunta esté mal formulada, solo indica que no discrimina. Por esta razón, se recomienda complementar este índice con el índice de discriminación tipo 2.

#### Índice de discriminación tipo 2

Este índice indica la proporción de aciertos en el grupo superior con respecto al número total de aciertos. Puede considerarse satisfactoria si es al menos superior a 0.50; es decir, más de la mitad de los aciertos pertenecen a los estudiantes del grupo superior.

\[ dc2 = \frac{A_s}{A_s + A_i} \]

Para calcular este segundo índice, se debe indicar como argumento en la función calcularIndiceDiscriminación:

    dc2 <- calcularIndiceDiscriminacion(respuestasCorregidas, tipo = "dc2", proporcion = 0.25)
    dc2
    #>  i01  i02  i03  i04  i05  i06  i07  i08  i09  i10  i11  i12  i13  i14  i15  i16
    #> 0.60 0.47 0.50 0.75 0.82 0.57 0.73 0.86 0.71 0.73 0.75 0.57 0.67 0.75 0.80 0.75
    #>  i17  i18  i19  i20  i21  i22  i23  i24  i25  i26  i27  i28  i29  i30  i31  i32
    #> 0.70 1.00 0.90 0.20 0.89 0.80 0.50 0.78 1.00 0.40 0.67 0.00 0.77 1.00 0.78 0.77
    #>  i33  i34  i35  i36  i37  i38  i39  i40  i41  i42  i43  i44  i45  i46  i47  i48
    #> 1.00 0.91 0.67 1.00 0.71 0.50 0.82 0.90 0.83 1.00 0.75 0.91 0.83 1.00 0.50 1.00
    #>  i49  i50
    #> 1.00 0.67

Como se mencionó anteriormente, este índice muestra cuánto discrimina un ítem independientemente si es muy fácil o muy difícil.

Por ejemplo, si los grupos superior e inferior están conformados por 10 estudiantes y los 10 estudiantes del grupo superior respondieron correctamente, mientras que 9 del grupo inferior acertaron, esto indica que es ítem es muy fácil. Sus índices de discriminación dc1 y dc2 son, respectivamente, 0.1 y 0.53. En base a lo anterior, podemos afirmar que este ítem discrimina poco (recordar que el dc2 debe ser mayor o igual a 0.5 para indicar discriminación).

En el otro extremo, si suponemos un ítem muy difícil en el que solo 2 de los 10 estudiantes del grupo superior acertaron y ninguno del grupo inferior lo hizo, nos dan unos índices de discriminación dc1 = 0.2 y dc2 = 1.0. Este ítem claramente discrimina bien, ya que solo estudiantes del grupo superior lo respondieron correctamente. Sin embargo, el dc1 no lo refleja por la dificultad de esta pregunta.

Por las razones indicadas anteriormente, se recomienda considerar los índices de discriminación en conjunto con el de dificultad.

    indices <- cbind(p, dc1, dc2)
    head(indices)
    #>        p  dc1  dc2
    #> i01 0.75  0.3 0.60
    #> i02 0.95 -0.1 0.47
    #> i03 0.60  0.0 0.50
    #> i04 0.60  0.6 0.75
    #> i05 0.55  0.7 0.82
    #> i06 0.70  0.2 0.57

### Correlación Biserial Puntual

El coeficiente de correlación biserial puntual entre una alternativa y el puntaje total de la prueba permite determinar el nivel de asociación entre seleccionar una alternativa con el puntaje total de la prueba.

Para su cálculo se utiliza la siguiente función:

\[ r_{bp} = \frac{\overline{X_{p}}-\overline{X_{q}}}{\sigma_{X}}\sqrt{p \cdot q} \]

Donde

- \(p\) es la proporción de estudiantes que respondió la alternativa examinada,

- \(q\) es la proporción de estudiantes que seleccionó una alternativa diferente a la alternativa examinada

- \(\overline{X_{p}}\) es el promedio del puntaje obtenido en la prueba por los estudiantes que seleccionaron la alternativa examinada.

- \(\overline{X_{q}}\) es el promedio del puntaje obtenido en la prueba por los estudiantes que no seleccionaron la alternativa en cuestión.

- \(\sigma_X\) es la desviación estándar del puntaje obtenido en la prueba de todos los estudiantes. Para su fórmula se utiliza la ecuación simplificada de la desviación estándar poblacional: \[ \sigma_X = \sqrt{\sum_{i=1}^{N}\frac{X_i^2}{N} - \overline{X}^2} \]

Los resultados de este coeficiente permiten clasificar las preguntas en las siguientes categorías: excelente, si el valor que se obtiene es igual o superior a 0,40; buena, cuando el valor del índice es igual o superior a 0,30 pero inferior 0,40; regular, si el valor del índice es igual o superior a 0,20 pero no llega a 0,30; pobre, si el valor está comprendido entre 0 y 0,20, y pésimo, si el valor es inferior a 0.

Cuanto mayor sea su valor, mayor será la relación entre la obtención de una puntuación alta en el test y el haber contestado correctamente la pregunta.

    alternativas <- LETTERS[1:5]
    pb <- pBis(respuestas, clave, alternativas)
    head(pb)
    #>   item     A     B     C     D     E KEY
    #> 1  i01 -0.23 -0.09 -0.14 -0.03  0.25   E
    #> 2  i02   NaN -0.10  0.09 -0.10   NaN   D
    #> 3  i03  0.02 -0.15 -0.05 -0.12   NaN   C
    #> 4  i04 -0.34  0.34   NaN -0.13 -0.16   B
    #> 5  i05  0.55 -0.36 -0.39   NaN -0.12   A
    #> 6  i06 -0.19  0.01  0.16 -0.17 -0.10   C

### Frecuencia de alternativas

Para conocer la frecuencia en que cada alternativa fue seleccionada por los estudiantes se puede usar la función calcularFrecuenciaDistractores como se muestra en el siguiente ejemplo:

    alternativas <- LETTERS[1:5]
    fa <- calcularFrecuenciaAlternativas(respuestas, alternativas, clave, frecuencia = FALSE)
    head(fa)
    #>   item  A  B  C  D  E NA KEY
    #> 1  i01  6  4  4  2 21  2   E
    #> 2  i02  0  1  4 33  0  1   D
    #> 3  i03  6  4 26  1  0  2   C
    #> 4  i04 13 22  0  2  1  1   B
    #> 5  i05 17  8  6  0  7  1   A
    #> 6  i06  2  6 25  3  1  2   C

Las columna `NA` de la tabla anterior representa las respuestas omitidas.

### Gráfico frecuencia alternativas

El análisis anterior también puede mostrarse de manera gráfica con la función graficarFrecuenciaAlternativas.

    g <- graficarFrecuenciaAlternativas(respuestas, alternativas, clave)
    g$i01
    g$i02
    g$i03
    g$i04

### Análisis de distractores

Tabular la frecuencia en que cada alternativa es seleccionada por los estudiantes con mejor y peor desempeño es un tipo de análisis sencillo y fácil de interpretar.

Para realizar este análisis primero hay que en ordenar a los estudiantes por el puntaje obtenido en la prueba. A continuación se seleccionan un porcentaje de estudiantes con la puntuación más baja y más alta. Suele usarse el 25% en cada caso. Otros valores razonables son 27% y 33%. Por último, se tabulan las respuestas seleccionadas por el grupo superior e inferior.

    ad <- analizarAlternativas(respuestas, clave, alternativas, proporcion = 0.25)
    ad$i01
    #>      A B C D *E
    #> gSup 0 0 0 1  9
    #> gInf 1 0 1 1  6
    ad$i25
    #>      A B C D *E
    #> gSup 0 1 3 1  3
    #> gInf 4 2 1 0  0
    ad$i50
    #>      A B C *D E
    #> gSup 1 0 0  8 1
    #> gInf 0 1 0  4 1

Con esta tabulación es posible determinar buenos y malos distractores, así como también el poder de discriminación de un ítem.

## Análisis gráfico de ítems

El análisis gráfico de ítems consiste en mostrar visualmente, mediante una gráfica de líneas, la relación entre la puntuación total de la prueba y la proporción de respuestas de los examinados que eligieron cada alternativa. Este análisis proporciona información esencial y fácilmente interpretable acerca de las características técnicas del ítem: dificultad, discriminación.

Para realizar este análisis primero se clasifica a los estudiantes en 4 grupos según su puntaje obtenido en la prueba. El grupo 1 corresponde a los estudiantes con menores puntuaciones, mientras que el grupo 4, a los de mayores puntajes. En el gráfico se representa la proporción de estudiantes de cada grupo que seleccionó una alternativa dada.

    item <- agi(respuestas, clave, alternativas)

    item$i01$datos
    #>         grupo    A    B    C    D   *E
    #> 1 (4.96,14.5] 0.12 0.00 0.00 0.12 0.62
    #> 2   (14.5,24] 0.26 0.21 0.16 0.00 0.32
    #> 3   (24,33.5] 0.00 0.00 0.12 0.12 0.75
    #> 4   (33.5,43] 0.00 0.00 0.00 0.00 1.00
    item$i25$datos
    #>         grupo    A    B    C    D   *E
    #> 1 (4.96,14.5] 0.38 0.25 0.00 0.00 0.00
    #> 2   (14.5,24] 0.11 0.37 0.26 0.11 0.11
    #> 3   (24,33.5] 0.00 0.12 0.25 0.12 0.25
    #> 4   (33.5,43] 0.00 0.25 0.25 0.25 0.25
    item$i50$datos
    #>         grupo    A    B    C   *D    E
    #> 1 (4.96,14.5] 0.00 0.12 0.00 0.25 0.12
    #> 2   (14.5,24] 0.00 0.16 0.26 0.42 0.11
    #> 3   (24,33.5] 0.25 0.00 0.00 0.62 0.12
    #> 4   (33.5,43] 0.00 0.00 0.00 1.00 0.00

    item$i01$plot
    item$i25$plot
    item$i50$plot

Un ítem de buena calidad debería mostrar una proporción creciente de estudiantes de cada grupo que elije la alternativa correcta y una proporción decreciente en el caso de los distractores.

## Referencias

- Morales, P. (2009). Análisis de ítem en las pruebas objetivas. Madrid. Recuperado de análisis de ítems

- Guadalupe de los Santos (2010). Manual para el análisis gráfico de ítems. Universidad Autónoma de Baja California. Recuperado de manual_pagi.pdf