III Seminario Análisis de datos avanzados en Ciencias de la Salud, Facultad de Ciencias de la Salud de la Universidad Rey Juan Carlos, Campus de Alcorcón.

Sesión impartida por Emilio López Cano, 23 de mayo de 2019

Las diapositivas del seminario se encuentran en: https://emilopezcano.github.io/seminario_urjc_2019/slides.html

Más ejemplos y explicaciones en mi libro de apuntes Análisis de datos con R (licencia CC).

Todo el material en: https://emilopezcano.github.io/seminario_urjc_2019/

Preparando el entorno

En los ordenadores del aula el software ya está instalado, así como los paquetes de R que vamos a usar. Si utilizas tu portátil, descarga e instala R y RStudio en tu sistema, y en ese orden. Puedes encontrar las instrucciones y los archivos de instalación en las siguientes direcciones:

En cuanto a los paquetes, si al ejecutar alguna expresión que contenga la función library obtienes un error, debes instalar el paquete que se intenta cargar con la función install.packages, o bien con el instalador de paquetes de RStudio.

Después de instalar R y RStudio, crea un proyecto de RStudio. A continuación descarga el fichero de datos y el fichero de código. Puedes hacerlo automáticamente con el siguiente código desde RStudio:

Comprueba que tienes un fichero con extensión .R y otro con extensión .rds en el directorio de trabajo. Abre el fichero codigo_seminario.R. Puedes ir ejecutando el código línea a línea a medida que se avance en la sesión.

Análisis exploratorio

El fichero de datos que vamos a utilizar se encuentra en formato “rds”, que es propio de R. Para importarlo al espacio de trabajo, utilizamos la función readRDS, y lo asignamos al nombre de objeto ansiedad (es arbitrario, se puede poner cualquiera y luego utilizarlo siempre).

Este fichero contiene los resultados de una encuesta de la escala de ansiedad matemática aplicada a 20 estudiantes de un curso de estadística. Los datos se encuentran también en el paquete likert de R, y están descritos en:

Bai, H., Wang, L., Pan, W., & Frey, M. (2009). Measuring mathematics anxiety: Psychometric analysis of a bidimensional affective scale. Journal of | Instructional Psychology, 36 (3), 185- 193.

Podemos ver en el explorador del environment que consta de 20 observaciones y 15 variables. Estas variables son 14 respuestas a preguntas en escala likert y una variable más para el sexo.

Podemos obtener tablas de frecuencias individuales y de doble entrada con la función table. Esta función espera vectores de datos, por lo que le pasamos las columnas de la tabla.


Female   Male 
    14      6 
                   
                    Female Male
  Strongly Disagree      2    0
  Disagree               2    1
  Neutral                2    0
  Agree                  5    2
  Strongly Agree         3    3

Gráficamente, podemos representar las tablas de frecuencias de un atributo con gráficos de barras. En general, lo gráficos de sectores circulares no son aconsejables a menos que se incluyan las cifras exactas, ya que el ojo humano no distingue las diferencias de ángulos con la misma facilidad que la diferencia de alturas.

Para más de un atributo, tenemos los gráficos de mosaico (más de un atributo), en los cuales el área de los rectángulos es proporcional a las frecuencias. En este caso utilizamos la sintaxis de fórmula, a la izquierda del símbolo ~ la variable del eje vertical, y a la derecha la variable del eje horizontal.

Otra representación, un poco más completa, la conseguimos con el paquete gplots. La función balloonplot que realiza esta representación, requiere que le pasemos directamente la tabla de frecuencias, por lo que primero la guardamos en el espacio de trabajo.

Existen varias opciones para añadir las frecuencias, marginales, etc.

Una vez explorados los datos, podemos realizar pruebas de asociación para los atributos. El método más usual es el test de la Chi-cuadrado. La función chisq.test hace este trabajo en R. Podemos pasarle a la función tanto la tabla de frecuencias, como los vectores de datos originales.

Warning in chisq.test(freqs): Chi-squared approximation may be incorrect

    Pearson's Chi-squared test

data:  freqs
X-squared = 22.825, df = 16, p-value = 0.1185
Warning in chisq.test(ansiedad$`I get uptight during math tests.`,
ansiedad$Gender): Chi-squared approximation may be incorrect

    Pearson's Chi-squared test

data:  ansiedad$`I get uptight during math tests.` and ansiedad$Gender
X-squared = 14.048, df = 4, p-value = 0.007145

Nótese que se obtiene una advertencia debido a que hay muchos ceros en la tabla. Para que el test sea válido, deberíamos tener al menos una frecuencia de 5 en cada cruce. En ocasiones esto se consigue uniendo categorías (por ejemplo, reducir de cinco a tres). En principio, podemos ver que la rigidez y el sexo están relacionados.

Modelo de análisis de correspondencias y datos obtenidos

La instalación base de R tiene una función para realizar análisis de correpondencias (ca). No obstante, vamos a utilizar directamente el paquete FactoMineR, ya que ofrece muchas más posibilidades. Sobre todo, combinado con funciones de visualización del paquete factoextra.

La función CA puede recibir como primer argumento el data frame con todos los datos, o la tabla de frecuencias de los dos atributos para los que queremos realizar el análisis. La función admite otros argumentos, como ncp (por defecto 5, dimensiones que se mantienen), si queremos obtener el gráfico (graph), los pesos de cada observación (row.w, muy útil cuando trabajamos con metadatos o encuestas ya cocinadas). Por otra parte, se le pueden proporcionar variables suplementarias, tanto cualitativas como cuantitativas.

Vamos a hacer el análisis para dos atributos. Guardamos el resultado en el objeto analisis, indicando que no devuelva el gráfico ya que utilizaremos para ello otro paquete.

**Results of the Correspondence Analysis (CA)**
The row variable has  5  categories; the column variable has 5 categories
The chi square of independence between the two variables is equal to 30.52143 (p-value =  0.01547891 ).
*The results are available in the following objects:

   name              description                   
1  "$eig"            "eigenvalues"                 
2  "$col"            "results for the columns"     
3  "$col$coord"      "coord. for the columns"      
4  "$col$cos2"       "cos2 for the columns"        
5  "$col$contrib"    "contributions of the columns"
6  "$row"            "results for the rows"        
7  "$row$coord"      "coord. for the rows"         
8  "$row$cos2"       "cos2 for the rows"           
9  "$row$contrib"    "contributions of the rows"   
10 "$call"           "summary called parameters"   
11 "$call$marge.col" "weights of the columns"      
12 "$call$marge.row" "weights of the rows"         

Como vemos, la salida del objeto solamente nos indica la estructura del objeto. Es una lista de 12 elementos, que realmente son 5, tres de ellos a su vez son listas. Podremos acceder a cualquiera de estos elementos con posterioridad, por ejemplo para hacer gráficos más avanzados. Para ver los resultados del análisis, utilizamos la función summary:


Call:
CA(X = ansiedad.1, graph = FALSE) 

The chi square of independence between the two variables is equal to 30.52143 (p-value =  0.01547891 ).

Eigenvalues
                       Dim.1   Dim.2   Dim.3   Dim.4
Variance               0.746   0.594   0.144   0.042
% of var.             48.900  38.909   9.441   2.749
Cumulative % of var.  48.900  87.809  97.251 100.000

Rows
                    Iner*1000     Dim.1     ctr    cos2     Dim.2     ctr
Strongly Disagree |   125.000 |   0.078   0.081   0.005 |   0.963  15.627
Disagree          |   398.214 |  -0.865  20.030   0.375 |   1.097  40.502
Neutral           |   333.333 |   1.167  36.501   0.817 |  -0.015   0.007
Agree             |   205.238 |   0.656  14.438   0.525 |  -0.265   2.960
Strongly Agree    |   464.286 |  -0.930  28.950   0.465 |  -0.986  40.903
                     cos2     Dim.3     ctr    cos2  
Strongly Disagree   0.742 |  -0.078   0.426   0.005 |
Disagree            0.604 |   0.024   0.077   0.000 |
Neutral             0.000 |   0.549  41.761   0.181 |
Agree               0.086 |  -0.561  54.590   0.383 |
Strongly Agree      0.523 |   0.135   3.145   0.010 |

Columns
                    Iner*1000     Dim.1     ctr    cos2     Dim.2     ctr
Strongly Disagree |   428.571 |  -0.803  30.245   0.527 |  -0.760  34.003
Disagree          |   200.000 |   0.957  18.407   0.687 |  -0.236   1.404
Neutral           |   210.000 |   0.862  24.913   0.885 |   0.105   0.462
Agree             |   487.500 |  -0.728  14.206   0.217 |   1.380  64.128
Strongly Agree    |   200.000 |   1.351  12.228   0.456 |  -0.019   0.003
                     cos2     Dim.3     ctr    cos2  
Strongly Disagree   0.471 |   0.051   0.634   0.002 |
Disagree            0.042 |  -0.503  26.389   0.190 |
Neutral             0.013 |  -0.054   0.513   0.004 |
Agree               0.781 |  -0.005   0.004   0.000 |
Strongly Agree      0.000 |   1.445  72.460   0.522 |

Vemos que lo primero que nos devuelve el análisis, es la prueba chi-cuadrado, por lo que podríamos ir directamente a este análisis sin hacer el anterior. Vemos que el p-valor es moderadamente pequeño (entre 0.01 y 0.05), por lo que puede haber asociación. Siempre con las reservas de que son muy pocos datos.

A continuación se muestran los autovalores de la matriz de discrepancias, que es la herramienta matemática que utilizamos para determinar las dimensiones finales. La idea del análisis de correspondencias, es reducir un espacio multidimensional en otro, idealmente, bidimensional. Vemos que de un total de 4 posibles dimensiones, con las dos primeras se explica un 87.8% de la varianza, que es bastante aceptable. No obstante veremos un método gráfico a más adelante. Estos autovalores se corresponden con la inercia total de la dimensión.

A continuación, para las tres primeras dimensiones (por defecto) se muestran los datos para cada categoría fila y columna:

Visualización de resultados

Como hemos dicho, vamos a utilizar el paquete factoextra que produce gráficos más elegantes.

Gráficos de diagnóstico

En primer lugar, podemos obtener un gráfico de sedimentación para ver si dos componentes son suficientes para explicar los datos.

Un criterio para decidir qué dimensiones son adecuadas, es considerar aquellas que contribuyan más que si la varianza se repartiera de forma unirorme, es decir, para cuatro posibles dimensiones, le correspondería 1/4 = 25% a cada una. Podemos añadir una línea al gráfico para visualizarlo.

Con lo que vemos que las dos primeras dimensiones son adecuadas.

Análisis de las categorías “fila”

Vamos a visualizar los distintos componentes que mostraba el summary del análisis y a interpretar los gráficos. La medida cos2 nos indica la calidad de la representación. Aquí debemos fijarnos en que si hay valores con dicho valor para las dos primeras componentes muy bajo, debemos tomar con cautela su posición con respecto al resto de categorías. la función fviz_cos2 nos sirve para este cometido

Si queremos ver por separado para cada dimensión, podemos utilizar la función corrplot del paquete homónimo.

Vemos cómo no hay ninguna categoría mal representada en el conjunto de las dos primeras dimensiones. La que menos, en todo caso, “Agree”. Del mismo modo, podemos visualizar las contribuciones de cada categoría a cada dimensión.

Esta información también la podemos visualizar con gráficos de barras, incluso con un umbral para intentar darle significado a las dimensiones, según las categorías que más contribuyan.

Fnalmente, podemos realizar un gráfico de dispersión a lo largo de las dimensiones obtenidas, tanto de la contribución como de cos2, con un gradiente de color representando la magnitud de una de estas métricas, y una transparencia para la otra. También se pueden hacer por separado (por color para cos2 y por color para contrib).

La opción gradient.cols nos sirve para definir la escala de colores, mientras que repel indica si las etiquetas deben “repelerse” para que no se oculten unas a otras. Esta opción puede resultar muy costosa computancionalmente.

Análisis de las categorías columnas

El análisis es análogo, por lo que se muestran a continuación el código y los gráficos para comentar en el aula. Nótese como hay que canbiar en cada caso, o el nombre de la función, o algún argumento utilizado en la misma, para referirnos a columnas en vez de filas.

Calidad de representación:

Contribución:

Mapa perceptual

Por último, y aunque muchas veces es lo primero que se hace, el principal resultado gráfico del análisis de correspondencias es el biplot o mapa perceptual, donde representamos conjuntamente las categorías de los dos atributos que estamos analizando.

El color azul representa las categorías fila, y el rojo, las categorías columna. Recordemos que las filas son las categorías para “I get uptight during math tests” y las columnas para “Math is one of my favorite subjects” Algunos patrones parecen claros (y lógicos). No obstante, en este gráfico cada atributo está representado en su propia dimensión. Para poder interpretar las distancias entre atributos, hay que visualizar el biplot “asimétrico”, mediante el argumento map. El siguiente código crea el biplot asimétrico en la escala de las filas con las típicas flechas en vez de puntos.

Si el ángulo entre dos flechas de distinto atributo es muy agudo, hay una asociación fuerte entre la categoría fila y columna. Podemos obtener un resumen de las coordenadas para intentar describir las dimensiones con la función dimdesc.

$`Dim 1`
$`Dim 1`$row
                        coord
Strongly Agree    -0.92959878
Disagree          -0.86450516
Strongly Disagree  0.07772507
Agree              0.65648687
Neutral            1.16703251

$`Dim 1`$col
                       coord
Strongly Disagree -0.8030427
Agree             -0.7280670
Neutral            0.8623541
Disagree           0.9569482
Strongly Agree     1.3509518


$`Dim 2`
$`Dim 2`$row
                        coord
Strongly Agree    -0.98564854
Agree             -0.26514211
Neutral           -0.01472721
Strongly Disagree  0.96328556
Disagree           1.09657274

$`Dim 2`$col
                        coord
Strongly Disagree -0.75951270
Disagree          -0.23576069
Strongly Agree    -0.01911206
Neutral            0.10473964
Agree              1.37982121

Elementos suplementarios

Podemos incluir en las visualizaciones elementos suplementarios no utilizados en la generación de las dimensiones. Por ejemplo, podemos situar las categorías del atributo “sexo” en las dimensiones creadas por los dos atributos que hemos analizado. Esto nos daría una especie de predicción de dónde se situaría una persona de un sexo determinado. Para ello, tenemos que tener una tabla de frecuencias ampliada, añadiendo por ejemplo nuevas columnas con las frecuencias de las categorías suplementarias. Por ejenplo unimos la tabla de frecuencias que teníamos con la tabla de frecuencias del primer atributo con el sexo:

                   
                    Strongly Disagree Disagree Neutral Agree
  Strongly Disagree                 0        0       1     1
  Disagree                          1        0       0     3
  Neutral                           0        1       2     0
  Agree                             1        2       2     0
  Strongly Agree                    5        0       0     0
                   
                    Strongly Agree
  Strongly Disagree              0
  Disagree                       0
  Neutral                        1
  Agree                          0
  Strongly Agree                 0

Ahora podemos indicar en el análisis de correspondencias, que las dos últimas columnas son categorías suplementarias:

Y ahora podemos obtener la representación de este nuevo atributo en los gráficos de dispersión de filas y en los biplot:

¿Quién lo tiene más claro?

De manera análoga se podría hacer con categorías suplementarias en filas.

Análisis de correspondencias múltiples

En los apartados anteriores, hemos seleccionado dos de los atributos para estudiar su relación. Es lo que llamamos análisis de correspondencias simple. El análisis de correspondencias múltiples nos permite estudiar la relación entre múltiples atributos. A medida que aumentamos el número de atributos, aumenta la complejidad, y la interpretación se complica. No obstante, el método es similar. Además, la visualización de muchos niveles de atributos se hace a veces complicado (o imposible), por lo que hay primero que adaptar las etiquetas para que se puedan leer en los gráficos. Vamos a realizar el análisis de correspondencias múltiples para nuestros datos. Primero transformamos los nombres de atributos (preguntas) y niveles (respuestas) para que sean más cortos.

Ahora ajustamos el modelo con la función MCA.

**Results of the Multiple Correspondence Analysis (MCA)**
The analysis was performed on 20 individuals, described by 15 variables
*The results are available in the following objects:

   name              description                       
1  "$eig"            "eigenvalues"                     
2  "$var"            "results for the variables"       
3  "$var$coord"      "coord. of the categories"        
4  "$var$cos2"       "cos2 for the categories"         
5  "$var$contrib"    "contributions of the categories" 
6  "$var$v.test"     "v-test for the categories"       
7  "$ind"            "results for the individuals"     
8  "$ind$coord"      "coord. for the individuals"      
9  "$ind$cos2"       "cos2 for the individuals"        
10 "$ind$contrib"    "contributions of the individuals"
11 "$call"           "intermediate results"            
12 "$call$marge.col" "weights of columns"              
13 "$call$marge.li"  "weights of rows"                 

Vemos que el objeto tiene los mismos elementos que el análisis simple.


Call:
MCA(X = ansiedad, graph = FALSE) 


Eigenvalues
                       Dim.1   Dim.2   Dim.3   Dim.4   Dim.5   Dim.6
Variance               0.691   0.494   0.337   0.313   0.258   0.233
% of var.             18.848  13.469   9.197   8.546   7.035   6.356
Cumulative % of var.  18.848  32.317  41.514  50.060  57.095  63.451
                       Dim.7   Dim.8   Dim.9  Dim.10  Dim.11  Dim.12
Variance               0.203   0.163   0.145   0.135   0.125   0.097
% of var.              5.530   4.454   3.952   3.688   3.409   2.654
Cumulative % of var.  68.980  73.434  77.386  81.074  84.483  87.138
                      Dim.13  Dim.14  Dim.15  Dim.16  Dim.17  Dim.18
Variance               0.095   0.084   0.079   0.069   0.059   0.048
% of var.              2.589   2.296   2.166   1.871   1.613   1.314
Cumulative % of var.  89.727  92.022  94.188  96.059  97.671  98.985
                      Dim.19
Variance               0.037
% of var.              1.015
Cumulative % of var. 100.000

Individuals (the 10 first)
                 Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3
1             |  1.029  7.667  0.287 |  0.498  2.506  0.067 | -0.123
2             | -1.092  8.634  0.271 |  0.866  7.588  0.171 | -0.705
3             | -0.762  4.198  0.150 | -0.463  2.166  0.055 |  1.039
4             | -0.312  0.706  0.031 | -0.786  6.252  0.196 |  0.475
5             |  0.656  3.118  0.145 | -0.541  2.967  0.099 | -0.633
6             | -0.803  4.668  0.208 |  0.575  3.346  0.107 | -0.439
7             | -0.899  5.852  0.264 |  0.372  1.404  0.045 | -0.423
8             |  0.396  1.132  0.052 | -0.558  3.151  0.103 | -0.177
9             |  0.114  0.095  0.005 | -0.502  2.556  0.105 |  0.324
10            |  1.526 16.843  0.408 |  1.411 20.145  0.349 |  0.609
                 ctr   cos2  
1              0.225  0.004 |
2              7.364  0.113 |
3             16.000  0.279 |
4              3.338  0.071 |
5              5.938  0.135 |
6              2.862  0.062 |
7              2.648  0.058 |
8              0.467  0.010 |
9              1.555  0.044 |
10             5.503  0.065 |

Categories (the 10 first)
                 Dim.1    ctr   cos2 v.test    Dim.2    ctr   cos2 v.test
F             |  0.343  0.792  0.274  2.281 |  0.021  0.004  0.001  0.138
M             | -0.799  1.849  0.274 -2.281 | -0.048  0.009  0.001 -0.138
interesting_1 |  1.693  2.765  0.318  2.460 |  1.892  4.832  0.398  2.749
interesting_2 |  0.703  0.714  0.087  1.287 | -0.338  0.232  0.020 -0.619
interesting_3 |  0.794  0.609  0.070  1.154 | -0.519  0.364  0.030 -0.754
interesting_4 | -0.236  0.189  0.030 -0.756 | -0.449  0.951  0.108 -1.435
interesting_5 | -0.905  2.369  0.351 -2.582 |  0.235  0.223  0.024  0.670
uptight_1     | -1.115  1.200  0.138 -1.620 |  0.287  0.111  0.009  0.417
uptight_2     | -0.677  0.884  0.115 -1.475 |  0.518  0.724  0.067  1.129
uptight_3     | -0.629  0.763  0.099 -1.371 | -0.210  0.119  0.011 -0.458
                 Dim.3    ctr   cos2 v.test  
F             | -0.303  1.267  0.214 -2.015 |
M             |  0.706  2.956  0.214  2.015 |
interesting_1 |  0.899  1.596  0.090  1.306 |
interesting_2 | -0.403  0.482  0.029 -0.739 |
interesting_3 | -0.354  0.248  0.014 -0.515 |
interesting_4 | -0.323  0.722  0.056 -1.033 |
interesting_5 |  0.397  0.935  0.068  1.133 |
uptight_1     |  0.288  0.164  0.009  0.418 |
uptight_2     | -0.907  3.250  0.205 -1.976 |
uptight_3     |  0.959  3.638  0.230  2.091 |

Categorical variables (eta2)
                Dim.1 Dim.2 Dim.3  
G             | 0.274 0.001 0.214 |
interesting   | 0.689 0.489 0.201 |
uptight       | 0.705 0.418 0.377 |
future        | 0.460 0.172 0.071 |
blank         | 0.807 0.472 0.174 |
life          | 0.586 0.380 0.344 |
worry         | 0.839 0.456 0.356 |
sink          | 0.598 0.792 0.423 |
challenging   | 0.553 0.608 0.143 |
nervous       | 0.952 0.782 0.491 |

Sin embargo es muy raro que se consiga explicar mucha varianza solo con dos dimensiones.

Nótese cómo por defecto para este análisis se muestran también las posiciones de los individuos (en azul).

Podemos visualizar solo los individuos:

Podemos visualizar solamente las variables para ver su proximidad.

A partir de los datos almacenados en el objeto, podemos realizar cualquier visualización utilizando las herramientas gráficas de R.

Visualización impactante y dinámica

Para terminar, vamos a representar los datos del análisis creando un gráfico interactivo con el paquete plotly. Estos gráficos se generan en formato html y son adecuados para publicar en web, pero también se pueden incorporar a presentaciones html para mostrar resultados en congresos, presentaciones de trabajos académicos, etc. Primero tenemos que preparar los datos.

Si dispusiéramos de datos longitudinales, con el gráfico anterior podríamos crear una animación fácilmente, al estilo de la siguiente: https://plot.ly/r/animations/#mulitple-trace-animations.

Por ejemplo, imaginemos que esta encuesta se pasa en cada edición del curso al que hace referencia. Podríamos ver la evolución de las relaciones con el tiempo. Tendríamos que agrupar todos los análisis en un dataframe, y tener una variable con el año.

Algunas cuestiones finales: