lunes, 23 de noviembre de 2015

Representar datos de Eyetracker Parte 2


Introducción

Tras muchas semanas de retraso debido a una serie de contratiempos ¡Por fin tenemos la segunda parte de este tema!
He encontrado varios problemas para publicar este artículo:
  1. La gripe, tres días en cama no ayudan a escribir esto. 
  2. Github desktop  no está funcionando en mi laptop. Esto es un problema porque quería intentar hacer un repositorio útil para este artículo, en cambio sigo usando Github de manera pedestre. Bueno, poco a poco.
  3. Mi obsesión por que los script se puedan ejecutar copiando y pegando. Odio cuando alguien cuelga un script que no funciona. (Igual dentro de unos meses este script deja de funcionar. Si eso pasase avísadme)
La parte buena de mi retraso es que este blog iba a ser dividido en varias partes, por lo que este post será especialmente largo para compensar la sequía.

Una vez más me gustaría agradecer a Álex Estudillo por los datos proporcionados (medias y desviaciones) y las imágenes.

Los datos los he generado basándome en unos datos de Alex tomando medias y desviaciones. Luego he simulado la matriz por sujetos con distribuciones normales.

La imagen sobre la que trabajaremos es la siguiente. Que por cierto, es propiedad intelectual de Álex, así que está aquí solo con fines de reproducción del ejemplo. Aun así por si acaso he modificado la imagen con GIMP.


Tratamiento de datos y descarga

Lo primero será leer los datos que es lo que hacemos en este script:

Solución 1

La primera solución es muy parecida a lo que hice en el post anterior, lo único que aporta
coord_fixed() es que nos fija las imágenes para que no tengamos problemas con el reescalamiento.
Las órdenes de dibujo que definen el objeto ggplot vienen de la librería ggplot2.







Solución 2

Aquí solo aporto una función para controlar los colores del heatmap, función que será utilizada durante todo el resto del ejercicio al quedar los colores bastante más aparentes. Ver lineas: 3 y 23.
colorRamp viene de la librería grDevices



Solución 3


Los heatmaps con distribuciones están muy bien de cara a representar, pero lo que buscamos es mas bien un histograma sobre el plano que nos cuente el número de ocurrencias por punto. Para  este fin podemos definir zonas de interés mediante hexágonos y de esta manera generamos el heatmap-histograma. Lo malo de esta solución es que es difícil generar los hexágonos de manera que queden exactamente en las ROIs que queremos y por tanto es una solución poco útil de cara al análisis.


stat_binhex nos permite crear tantos hexágonos como queramos para definir ROIs. El parámetro de bins nos da el número de hexágonos que caben en el eje x.


Como veis el resultado es muy similar, pero ahora ya hemos definido algo aproximado a una zona de interés.


Solución 4


Ahora vamos a definir unas zonas de interés con cuadrados. Es la misma lógica que tienen los hexágonos sólo que los cuadrados tendrán mucho más juego al poderse elegir más fácilmente donde los colocamos.

stat_bin2d La orden utilizada será ésta y tiene un uso similar a la que tiene la orden  stat_binhex, aunque como veremos en el último apartado es mucho más flexible.



Solución 5


Esta solución consiste en crear la matriz de frecuencias a mano y representárla con la orden surface3d del paquete rgl. Lo bueno de esta solución es que ya tenemos la matriz de frecuencias lista para el análisis y que además nos da un dibujo en 3D que se puede mover. Esta solución es bonita  pero poco útil.



Solución 6


Basándonos en la matriz de frecuencias de la solución 5 podemos intentar hacer otro tipo de dibujo. Sólo que ahora aproximaremos por polinomios a una forma que se ajuste a los valores dados. El heatnap queda aparente y nos da una visión más general de a dónde han ido las miradas, pero no nos permite hacer un análisis lo suficientemente bueno.



Analisis final

Ahora vamos a utilizar la solución 4, que es la que más me gustó, para terminar el análisis. Pero vamos a elegir las ROI de manera manual y no de manera automática. Para ello definiremos los cuadrados con unos vectores para generar las distintos ROIs.
 stat_bin2d(breaks = list( x= seq(from = 0, to = 1000, by = 50),
                                        y = seq(from = 0, to = 800, by = 50) )



Por último analizaremos las frecuencias con un test de proporciones. Los pasos son los siguientes:
  1. Lo primero con ggplot_build hemos sacado la estructura de la matriz que genera el plot. Mucho más sencillo que como lo hemos hecho en las soluciones 5 y 6 (línea4)
  2. Luego nos hemos fijado en los cuadrantes donde los sujetos se fijaron más de 500 veces.
    1. Se observa el cuadrante (250,300] (350,400] Ojo izquierdo de la cara izquierda (línea 10)
    2.  También podemos ver el cuadrante (700,750] (350,400] que es el ojo derecho de la cara de la derecha. Ambos cuadrantes son los más calientes.
  3. Por último vamos a comparar si los sujetos en general se han fijado más en un cuadrante o en el otro. Para ello hacemos un test de proporciones en el que nos da un p valor menor que 0.05 (línea 24), con lo que podemos concluir que efectivamente se han fijado más en un cuadrante que en otro.


Reflexiones


  1. No me termina de hacer chiste cómo están representados los datos. Ese ajuste que tuve que hacer en la solución uno (líneas 10 y 11 de la solución 1) y que he arrastrado todo el post me hace sospechar que algo no del todo bueno a pasado entre los datos y la representación.
  2. Por si acaso advierto que en un estudio real no miraríamos lo que he mirado. En un análisis haríamos comparaciones entre cuadrante y sujetos (grupos, condiciones) con un glm y así ver qué diferencias ha habido según una hipótesis.
  3. Los cuadrantes han de ser definidos con cuidado para definir las áreas de interés en zonas claves según la literatura. Aún así, como definimos los cuadrantes de manera manual, siempre tiene un punto arbitrario y peligroso. Mi recomendación es definir las ROIs antes de hacer los análisis para evitar sesgos o tentaciones
  4. Tengo total desconocimiento sobre las ROIs en este tipo de estudios y por tanto cualquier análisis más complejo que hiciese no podría ser tomado en serio.
  5. Todo esto ha costado de hacer, pero estoy bastante contento con los resultados. Espero que la currada haya merecido la espera. Gracias por seguirme.


Bibliografía
  1.  Ideas 1[1]
  2. Ideas 2[2]
  3. Guia para descargase csv de Dropbox [3]
  4. Crear lineas en html [4]

martes, 17 de noviembre de 2015

Retrasos, retrasos....

Modificado: El post será publicado el 23-11-2015 a las 06:00 am

Hola a todo el mundo, imagino que esta entrada tiene poco valor.
Yo hoy quería publicar  una nueva entrada después de dos semanas. Tenía planeado hablar sobre datos en el eye tracker. Pero una seríe de problemillas con el github y Windows 10 me están complicando dicha labor.

De todas maneras, me gustaría explicar el retraso con las publicaciones. Estas semanas han sido muy convulsas en cuanto a mi vida profesional y de estudiante.
Por un lado una de las personas que más admiro de mi grupo nos ha abanado por un trabajo mejor. Esto me ha dejado con menos tiempo del habitual, con nuevas responsabilidades que incluían viajes inesperados. Por suerte esto ha sido una oportunidad y hemos ganado un premio muy importante dentro de mi empresa. Así que bueno, no hay mal que por bien no venga.

Por otro lado, estas semanas he tenido que mover y sigo moviendo, el tema de mi cambio de director de tesis y del tema que esta trata. Esto es un proceso muy lento que a veces me consume el poco tiempo que tengo.

Por otro lado mi vida personal ha sido intensa. Así que bueno, de ahí se explica este retraso.

Esta semana intentaré sin falta publicar el tema del eye tracker.
Un saludo y a ver si puedo comentarlo todo de la manera más correcta posible para que el código se fácil de seguir. Mejor publicarlo tarde y bien comentado que pronto y con lagunas.

Un abrazo

Javier

lunes, 26 de octubre de 2015

Borrar caracteres no ingleses de una BD



Esta semana quería seguir con el tema del Eyetracker, pero las respuestas que he encontrado me han llevado a nuevas preguntas y aún está demasiado flojo el tema como para dar una respuesta a esta duda. Así que lo dejamos ( esperemos) para la semana que viene. Os diré que casi he conseguido evitar los diagramas de densidad y dibujar frecuencias como algunos de vosotros pedíais. Lo único es que me gustaría estructurarlo, porque la verdad es que he encontrado unas 5 soluciones que  espero que os gusten. Así, volvernos a una vieja entrada que es va de como limpiar datos que nuca está de más.

Hace ya tiempo que me vi obligado a tratar una serie de BD portuguesas para hacer un analisis de su liga (Está todavía muy en primeros pasos, pero me gustaría en el futuro mostraros algo). Esto causaba multiples problemas en el trato de caracteres sobre todo al guardar en .RData y cambiar de sistema operativo. Ahora os ofrezco una solución con un poquito de scrapeo de webs fáciles como Wikipedia gracias a librería rvest. El script es el siguiente y lo podeis ejecutar sin problemas sobre vuestra consola R.

Un saludo a todos y muchas gracias por las visitas de esta semana que han sido una gran recompensa para el trabajo que he hecho.

lunes, 19 de octubre de 2015

Plotear datos de Eye Tracker

Hoy vamos a comentar algo más cercnao, al fin a la neurociencia. Gracias a un colega eRRero ( Álex Estudillo)  como yo hace unas semanas se me planteo un duda. ¿Cómo representar unos datos de eyetracker en R?. La verdad es que nunca lo había hecho, aunque si que había hecho varias representaciones sobre mapas. Así que me puse a ello

Lo primero es elegir unas imagenes donde representar los datos que serán las siguientes:



Si quereis runear este código deberiais de descargaros estas imagenes en el directorio base ( ver linea 19 del siguiente script).

Una vez hecho esto ahora vamos a simular unos datos de mirada sobre ellas (Esto causa problemas en la representación, espero solucionarlos en posts posteriores).



Una vez generados los datos llega la hora de representarlos. En este post lo vamos a hacer por la lógica de una función de densidad.
Lo siguiente será plotear y explicar las ordenes que sirven para esto:

 ggplot(a, aes(x = x, y =y)) Dibuja los puntos en las coordenadas x e y de la BD y con nombres de columnas x e y
annotation_custom(g, # Image
                    xmin= -0.15, # Coordinates to represent the image
                    xmax= 1.25,
                    ymin= -0.25,
                    ymax= 1.25)
Nos dibuja la imagen g intentando fijar los puntos más cercanos posible a las esquinas definidas ( Este es el problema de simular datos, lo tengo solucinar en futuros posts)
stat_density2d(data= a, aes(x= x, y=y, fill = ..level.., alpha = ..level..), size= 10, bins= 50, geom='polygon') Dibuja la densidad. Size y bins sirven para hacer más visibles o menos el mapa de densidad.
geom_point(data= a, aes(x=x, y=y),  
             color="black",

             position=position_jitter(w=0.01,h=0.01),
             alpha=0.5)
  Dibuja los puntos desviados gracias a la función jitter y se hacen más o menos transparentes con alpha.
scale_fill_gradient( low = "green",  
                       high = "red",
                       limits = c(0, 15) ,

                       breaks = c(0, 3, 5, 10) 
  ) Esta orden define como rellenamos el dibujo de densidad. Loe nos dice el datos inferior, High nos dice cual es el color superior,  limits( a nivel leyenda) nos dice los limites de nuestra escala y finalmente breks ( a nivel leyenda) nos dice los putnos de corte para la escala, Guide es booleano que nos deice si se muestra la leyenda o no.
Las siguientes ordenes solo definen el nivel de transparencia (scale_alpha_continuous) con la misma lógica que lo anterior y los límites del plot(xlim e ylim).



Este es el código :


Siguiendo esta lógica dibujaremos y simularemos otros ejemplo:


También podemos modificar como rellenas la escala, como por ejemplo por rangos


El problema que tiene simular datos es que tengo problemas para fijar el gráfico. En futuros post intentaré solventar esto. Todos eso gracias a mi colega Alex que me ha ayudado mucho en este post y al cual le quiero agredecer desde aquí su colaboración. Una respuesta no es nada si un una buena pregunta.

lunes, 12 de octubre de 2015

Code Combat una manera divertida de aprender.

Hace unas semanas llegó a mí un divertido juego para aprender a programar en distintos lenguajes de programación. Lo cierto es que aprender a programar jugando es una gran idea y ojalá pronto añadan nuevos lenguajes (como por ejemplo R). La verdad es que esta iniciativa tiene mucha salida en el mundo docente ¿qué mejor manera de motivar a los alumnos que un videojuego? Por lo menos a los más nerds de la clase. También es útil para los que no sepáis programar y queráis una aproximación a este mundo. La única faena es que no se pueda jugar offline. A continuación os dejo un video para que disfrutéis de un friki game play.


domingo, 4 de octubre de 2015

Computar diferencias entre fechas con R

Como cientifico de datos muchas veces te encuentras el problema de que a varias fechas le quieres restar una fecha concreta. Aquí os muestro una función para autoamtizar este proceso.