Castor Guisande González Catedrático del Área de Ecología Universidad de Vigo. España
Antonio Vaamonde Liste Catedrático del Área de Estadística e investigación Operativa Universidad de Vigo. España
Gráficos estadísticos y mapas con R
ERRNVPHGLFRVRUJ
©Cástor Guisande González, Antonio Vaamonde Liste, 2012 (Versión papel) ©Cástor Guisande González, Antonio Vaamonde Liste, 2013 (Versión electrónica)
Reservados todos los derechos. Queda prohibida, salvo excepción prevista en la ley ,cualquier forma de reproducción, distribución, comunicación pública y transformación de esta obra sin contar con la autorización de los titulares de propiedad intelectual. La infracción de los derechos mencionados puede ser constitutiva de delito contra la propiedad intelectual (art.270 y siguientes del Código Penal). El Centro Español de Derechos Reprográficos (CEDRO) vela por el respeto de los citados derechos. EdicionesDíazdeSantos Email:
[email protected] www.editdiazdesantos.com
ISBN: 978-84-9969-610-2 (Libro electrónico) ISBN:978-84-9969-211-1(Libro en papel)
ÍNDICE PRÓLOGO Y AGRADECIMIENTOS.............................................
XI
I. PROGRAMACIÓN DE GRÁFICOS CON R............................... I.1. PRIMEROS PASOS CON R..................................................... I.1.1. Instalación........................................................................... I.1.2. Interfaz................................................................................ I.1.3. Seleccionar directorio de trabajo........................................ I.1.4. Paquetes gráficos................................................................ I.1.5. Scripts y archivos que se usan en el libro........................... I.2. COMPLEMENTOS GRÁFICOS............................................... I.3. ARGUMENTOS GENERALES................................................ I.4. COLORES.................................................................................. I.5. FÓRMULAS MATEMÁTICAS Y CARACTERES ESPECIALES................................................................................... I.6. DISPOSITIVOS PARA GRÁFICOS.........................................
1 1 1 1 2 3 6 6 11 20
II. GRÁFICOS BÁSICOS.................................................................. II.1. GRÁFICOS DE DISPERSIÓN................................................ II.2. GRÁFICOS CON BARRAS DE DESVIACIONES................ II.3. MODELOS Y GRÁFICOS EN PANELES.............................. II.4. DIAGRAMA DE CAJAS......................................................... II.5. BEANPLOTS............................................................................. II.6. CURVAS DE AJUSTE............................................................. II.7. HISTOGRAMAS...................................................................... II.8. DIAGRAMA DE TALLO Y HOJAS....................................... II.9. GRÁFICOS DE BARRAS........................................................ II.10. GRÁFICOS CIRCULARES................................................... II.11. GRÁFICOS DE PUNTOS...................................................... II.12. GRÁFICOS TERNARIOS..................................................... II.13. GRÁFICOS DE CONTORNOS Y SUPERFICIES................ II.14. GRÁFICOS TRIDIMENSIONALES..................................... II.15. CONFIGURACIÓN DE MÁRGENES Y EJES ADICIONALES............................................................................... II.16. FORMAS ESPECIALES........................................................ II.17. GRÁFICOS COMBINADOS................................................. VII
32 34 39 39 46 48 49 52 58 59 64 65 73 77 78 83 87 94 96 99
VIII
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
II.18. GRÁFICOS DENTRO DE GRÁFICOS................................. II.19. AMPLIACIÓN DE UN ÁREA DENTRO DE UN GRÁFICO......................................................................................... II.20. GRÁFICOS CON INTERVALOS EN LOS EJES................. II.21. PAQUETES QUE PERMITEN REALIZAR VARIOS TIPOS DE GRÁFICOS BÁSICOS.................................................. II.21.1. R Commander.................................................................. II.21.2. GrapheR........................................................................... II.22. REPRESENTACIONES INTERACTIVAS PARA PÁGINAS WEB............................................................................... II.22.1. Gráficos........................................................................... II.22.2. Tablas.............................................................................. II.22.3. Combinación de representaciones................................... III. GRÁFICOS AVANZADOS......................................................... III.1. GRÁFICOS DEMOGRÁFICOS............................................. III.2. GRÁFICOS DE BURBUJAS.................................................. III.3. GRÁFICOS DE ESCALERA.................................................. III.4. DIAGRAMAS DE FLUJO...................................................... III.5. GRÁFICOS DE TELARAÑAS.............................................. III.6. DIAGRAMA DE EVENTOS.................................................. III.7. MATRICES DE GRÁFICOS….............................................. III.8. GRÁFICOS DE MATRICES DE CORRELACIONES.......... III.9. DIAGRAMA DE VENN Y EULER....................................... III.10. GRÁFICOS DE VARIABLES CUALITATIVAS EN FUNCIÓN DE VARIABLES CUANTITATIVAS................... III.11. DISTRIBUCIONES DE VARIABLES CUALITATIVAS.. III.12. GRÁFICOS PARA TABLAS DE CONTINGENCIA.......... III.13. GRÁFICOS PARA GRANDES CONJUNTOS DE DATOS............................................................................................. III.13.1. Dispersión...................................................................... III.13.2. Matrices de gráficos....................................................... III.13.3. Espectros........................................................................ III.13.4. Gráficos polares............................................................. III.14. GRÁFICOS PARA PRUEBAS ALEATORIAS................... III.15. DIAGRAMA DE TAYLOR.................................................. III.16. CURVAS DE SUPERVIVENCIA Y REGRESIÓN DE COX.................................................................................................. III.17. ANÁLISIS DE VARIANZA................................................. III.18. GRÁFICOS DE DIAGNÓSTICO EN MODELOS LINEALES.......................................................................................
100 103 104 106 106 112 117 117 120 121 123 123 125 128 129 131 133 139 147 152 153 158 161 165 166 167 169 171 173 177 180 182 186
ÍNDICE
III.19. GRÁFICOS DE MEDIDAS DE RIESGO DE EXTINCIÓN..................................................................................... III.20. GRÁFICOS PARA ANÁLISIS MULTIVARIANTE........... III.20.1. Biplot.............................................................................. III.20.2. Análisis Discriminante................................................... III.20.3. GGE Biplot..................................................................... III.20.4. Gráficos combinando Análisis de Componentes Principales y Análisis Discriminante........................................... III.21. MODELO DE EFECTOS PRINCIPALES ADITIVOS E INTERACCIÓN MULTIPLICATIVA (AMMI).......................... III.22. GRÁFICOS DE INFERENCIA EN COSTE/EFICACIA..... III.23. META-ANÁLISIS................................................................ III.23.1. Diagrama de bosque....................................................... III.23.2. Gráfico de L'Abbé.......................................................... III.23.3. Diagrama de embudo..................................................... III.23.4. Diagrama de análisis de sensibilidad............................. III.23.5. Diagrama de meta-análisis acumulativo........................ III.24. GRÁFICOS DE CLASIFICACIÓN...................................... III.24.1. Clasificación jerárquica (dendrograma)......................... III.24.2. Clasificación de k-medias.............................................. III.24.3. Árbol de consenso.......................................................... III.24.4. Árboles de Clasificación y Regresión: CARTs.............. III.24.5. Árboles de Clasificación y Regresión (CARTs) y Análisis de Componentes Principales.......................................... III.24.6. Árboles de Inferencia..................................................... III.25. DIAGRAMAS PALEOECOLÓGICOS................................ III.26. GRÁFICOS CLIMÁTICOS.................................................. III.26.1. Rosa de vientos.............................................................. III.26.2. Diagrama de Walter-Lieth............................................. III.27. CONTROL DE CALIDAD................................................... III.27.1. Definir............................................................................ III.27.1.1. Diagrama de Ishikawa........................................... III.27.1.2. Diagrama de Pareto............................................... III.27.2. Medir.............................................................................. III.27.2.1. MSA tipo I............................................................... III.27.2.2. MSA tipo II............................................................. III.27.3. Analizar.......................................................................... III.27.4. Mejorar........................................................................... III.27.4.1. Diseño factorial...................................................... III.27.4.2. Diseño con mezclas................................................ III.27.4.3. Diseños Taguchi.....................................................
IX
188 190 190 192 199 212 216 219 224 225 232 234 236 237 239 239 242 247 249 255 260 271 274 274 276 278 279 279 280 282 282 284 288 290 291 296 299
X
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
III.27.5. Controlar........................................................................ III.27.5.1. Variables................................................................ III.27.5.2. Atributos................................................................. III.28. MINERÍA DE DATOS.......................................................... III.28.1. Cargar datos................................................................... III.28.2. Explorar.......................................................................... III.28.3. Pruebas........................................................................... III.28.4. Modelos..........................................................................
302 303 307 309 310 312 315 316
IV. MAPAS.......................................................................................... IV.1. ÁREAS ADMINISTRATIVAS.............................................. IV.2. GRÁFICOS DENTRO DE MAPAS....................................... IV.3. MAPAS CON INFORMACIÓN ADICIONAL..................... IV.4. MAPAS DE VECTORES....................................................... IV.5. MAPAS INTERACTIVOS..................................................... IV.6. MAPAS HIDROLÓGICOS....................................................
319 319 327 328 338 340 341
BIBLIOGRAFÍA.................................................................................
347
ÍNDICE DE PAQUETES, FUNCIONES Y ARGUMENTOS........
355
PRÓLOGO Y AGRADECIMIENTOS Los estadísticos han utilizado siempre gráficos para mostrar los resultados de forma que pudieran ser interpretados por diferentes tipos de lectores, incluyendo aquellos con escasos o nulos conocimientos de estadística. Los gráficos ayudan a entender mejor las conclusiones obtenidas en la aplicación de diferentes métodos estadísticos, y generalmente se busca con la representación reforzar visualmente los aspectos más destacables de los datos y los resultados. Algunos gráficos estadísticos aparecen con frecuencia en la prensa o en los distintos medios de comunicación, ya que son necesarios para entender mejor la realidad que nos rodea. Un conocimiento elemental de los gráficos más comunes forma parte hoy en día de la cultura general de los ciudadanos, y es habitual encontrarlos, junto con otros conceptos estadísticos elementales, en los planes de estudios de la enseñanza obligatoria de cualquier país moderno. Existen centenares de tipos distintos de gráficos y múltiples variantes de cada uno de ellos. Los programas estadísticos generalmente han prestado mucha atención a la construcción de gráficos, que suele ser un apartado importante del menú de usuario. A menudo se busca la construcción automática del gráfico, liberando al usuario del esfuerzo y la incomodidad de definir tamaños, escalas, líneas, colores, leyendas, o complementos diversos. Existen programas no estadísticos de uso general, como por ejemplo hojas de cálculo, sistemas de gestión de bases de datos, entornos de programación, programas de edición o de diseño de páginas web, que incluyen también herramientas para la construcción de gráficos estadísticos, ya que la presentación de la información de una forma adecuada es un elemento esencial que ha superado hace mucho tiempo el estricto ámbito de la Estadística para convertirse en una necesidad transversal de aplicación prácticamente universal. Algunos gráficos son fácilmente interpretables, sin requerir una formación previa, ya que son intuitivos y asequibles a todos. Otros requieren un conocimiento adicional sobre el significado exacto de los distintos elementos representados. Por último, existe una tercera categoría de gráficos, en número creciente, cuya complejidad interpretativa requiere un conocimiento experto de la técnica estadística que lo emplea. No es posible interpretar adecuadamente esos gráficos sin haber comprendido suficientemente un método estadístico concreto, siendo el gráfico en esos casos una parte importante del mismo. Muchos métodos estadísticos conducen a un gráfico de interpretación no trivial, por ejemplo el escalamiento multidimensional, árboles de clasificación, algunas técnicas de control de calidad, análisis de series temporales, meta-análisis, etc. Muchos gráficos nacieron históricamente como herramientas meramente descriptivas, como una alternativa o un complemento a las tablas y medidas numéricas. Sin embargo, desde antiguo se conocen las posibilidades analíticas y explicativas de algunos gráficos, y actualmente existen gráficos que constituyen potentes instrumentos de análisis y decisión.
XI
XII
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
R se ha convertido durante la última década en el programa estadístico de uso general más potente, con mucha diferencia sobre los restantes, y también el más versátil. No solo es el preferido por la comunidad estadística, que ha apostado sin reservas por su desarrollo mediante un esfuerzo colectivo generoso y desinteresado sino que, además, quizás en parte por su carácter de programa totalmente gratuito, empieza a ser utilizado cada vez más por investigadores y técnicos de cualquier ámbito de conocimiento, hasta el punto de que actualmente es posible encontrar sin dificultad aplicaciones, desarrolladas en R, de interés para usuarios con necesidades estadísticas especializadas, en campos tan distintos como ecología, medicina, ingeniería, biología, economía, lingüística, sociología, o –como no- estadística. R es por añadidura el programa estadístico con mayor capacidad y flexibilidad para la construcción de gráficos, y ese es el objeto de este libro, mostrar las enormes posibilidades que R brinda en este aspecto, y enseñar a los usuarios interesados como construir los gráficos que necesitan. La filosofía de R no coincide con la mayoría de los programas estadísticos alternativos. No se busca tanto la rapidez y comodidad del usuario mediante la construcción automática de un gráfico único y cerrado sino, por el contrario, la flexibilidad y el control de los distintos elementos del gráfico, que el usuario puede diseñar a su medida. Este planteamiento, que hace posible obtener gráficos personalizados, obliga por otra parte a un mayor esfuerzo de programación y a un mayor nivel de conocimientos, pero el esfuerzo obtiene su recompensa en un resultado en general mucho más satisfactorio. Por otra parte existen muchos procedimientos de R que permiten obtener gráficos de forma rápida y sencilla si se desea, aplicando condiciones estándar y opciones por defecto, que no requieren un esfuerzo para el usuario mucho mayor del que exigen otros programas estadísticos. En la primera parte del libro se presentan las técnicas generales para la construcción de gráficos con R: paquetes, funciones, argumentos y opciones, con numerosos ejemplos de aplicación reales que permitirán al lector utilizar las funciones básicas con soltura para la construcción de la mayoría de los gráficos más comunes. Un buen conocimiento de estas técnicas básicas será útil también para la construcción y modificación de otros gráficos más complejos. El objetivo es el manejo de los distintos parámetros que controlan el tamaño y aspecto, escalas, ejes, líneas, puntos, colores, textos y leyendas, símbolos y otros elementos gráficos, así como las utilidades que permiten combinar distintos gráficos, añadir elementos nuevos a un gráfico, y otras más avanzadas. En la segunda parte del libro se revisan de forma sistemática los principales gráficos, desde los más básicos y habituales (histograma, diagrama de barras, de sectores, de cajas, de dispersión, etc.) hasta los más complejos (biplot, curvas de nivel, gráficos de control, etc.), incluyendo algunos gráficos de reciente aparición asociados a técnicas estadísticas novedosas. No se pretende elaborar un catálogo de todos los gráficos existentes sino solamente describir los más usuales o los más útiles para el lector general, entre otras cosas porque el mundo de R está vivo y tiene una gran vitalidad, de modo que constantemente aparecen nuevas propuestas, nuevas técnicas, nuevos paquetes y nuevos gráficos, así como mejoras en los ya existentes. Para cada uno de los gráficos descritos en el libro se presentan con detalle los procedimientos para la construcción y las principales claves de interpretación, de modo que puedan ser utilizados por usuarios no expertos o sin conocimientos estadísticos avanzados.
PRÓLOGO Y AGRADECIMIENTOS
XIII
Para todos los gráficos se muestra con ejemplos la construcción paso a paso, de tal forma que sea sencillo reproducir el resultado con cualquier otro conjunto de datos. Se explican las características del gráfico, el significado de los diferentes argumentos de cada una de las funciones, y el ámbito de aplicación. También se lleva a cabo una interpretación de los resultados para la aplicación concreta y el ejemplo utilizado en cada caso. Esta interpretación es quizás el aspecto más difícil, sobre todo en algunos gráficos relacionados con técnicas estadísticas complejas, ya que depende siempre de los resultados, que pueden ser distintos en cada aplicación. Aunque se intenta explicar las claves principales de interpretación, lo cierto es que solamente un conocimiento profundo de los aspectos teóricos y prácticos relacionados con la técnica estadística involucrada garantizará una interpretación correcta de todos los resultados gráficos obtenidos, por lo que recomendamos vivamente a los lectores interesados que no se detengan en la realización práctica de los gráficos, sino que intenten comprender los diferentes elementos teóricos (propios del campo de aplicación) y estadísticos que subyacen en los resultados a interpretar, y consulten con un experto estadístico sus dudas cuando sea necesario. Dado el carácter abierto y libre de R, los paquetes -y los datos contenidos en ellos- pueden ser modificados o incluso suprimidos por sus autores cuando lo consideren oportuno. En ese caso algunos ejemplos citados en este libro podrían dar lugar a resultados diferentes de los indicados, o requerir datos e instrucciones distintas de las que se citan. Los autores del libro no se hacen responsables de estos hipotéticos cambios ajenos a su voluntad. Por último, agradecemos a Aldo Barreiro Felpeto su ayuda con alguno de los scripts que se muestran en el libro.
CAPÍTULO I PROGRAMACIÓN DE GRÁFICOS CON R
I.1. Primeros pasos con R I.1.1. INSTALACIÓN El programa está en la dirección http://cran.r-project.org/. Allí veremos, en la parte superior, un enlace para la instalación de R en Linux, MacOS y Windows. Para Windows debemos seguir el enlace al subdirectorio base. En el caso de MacOS, el enlace nos lleva a una página donde podemos encontrar el archivo de instalación con la última versión. Hay varias formas de instalar R en distribuciones de Linux; de forma general, primero es necesario añadir «CRAN» a la lista de repositorios, configurar el nuevo repositorio adecuadamente e instalar el r-base.
I.1.2. INTERFAZ Existen diferentes entornos gráficos que facilitan la interacción con el usuario (llamados GUI, del inglés Graphical Users Interface). Entre los más populares se encuentran RGui (disponible para Windows), Tinn-R (Windows, MacOS), R Commander (Windows, MacOS, Linux), Emacs (Windows, MacOS, Linux), RKward (Linux), pero existen muchos otros. En este libro hemos elaborado la mayoría de los ejemplos con RGui en Windows, y algunos con R Commander. La siguiente pantalla muestra el aspecto de la interfaz RGui, disponible para Windows:
1
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
2
RGui se instala de forma automática con el paquete base de Windows. El resto de GUIs es necesario instalarlas específicamente. Se encuentran gratuitamente en internet. Estas GUIs, para facilitar la interacción con el usuario, disponen de una serie de menús desplegables, cuya complejidad puede ir desde solamente algunas sencillas posibilidades de edición, apertura de ficheros, guardar datos, cargar paquetes, actualizar, etc. como podría ser el caso de RGui, hasta corrección de sintaxis de instrucciones, menús desplegables para importar/exportar datos, gráficos y múltiples técnicas estadísticas, como es el caso de R Commander y RKward.
I.1.3. SELECCIONAR DIRECTORIO DE TRABAJO Si disponemos de alguno de los múltiples tipos de interfaz gráfica, además de la consola, podemos usar el correspondiente icono de acceso directo para abrir el programa R. Una vez dentro del programa, es muy importante seleccionar el directorio o carpeta de trabajo. Este directorio es el que estará disponible de forma automática para cargar archivos de datos, abrir archivos para incluir instrucciones (scripts), guardar áreas de trabajo y archivos de salida, etc. Si no seleccionamos un directorio de trabajo específico utilizará el que tiene por defecto, que depende de la instalación que se haya hecho. El directorio de trabajo se selecciona con la siguiente instrucción:
¾
setwd(“C:/Documents and Settings/All Users/ArchivosR”)
La función «setwd()» permite seleccionar el directorio deseado escribiendo como argumento toda la ruta de directorios entrecomillada, con las barras separadoras orientadas hacia la derecha. Si queremos saber cuál es el directorio de trabajo actual, debemos escribir la siguiente instrucción:
¾
getwd()
Aquí tenemos un ejemplo de cómo establecer un directorio de trabajo mediante instrucciones y después preguntar cual es el directorio de trabajo actual:
¾ setwd("C:/Archivos de programa") ¾ getwd()
La mayoría de las GUIs disponen de una opción a través de menú para establecer el directorio de trabajo. En RGui, que como se mencionó anteriormente es el entorno que se usará en la mayoría de los ejemplos en este libro, se encuentra en el menú «Archivo» Ö «Cambiar dir…». Tras pulsar en esta opción surge un cuadro de diálogo en el que seleccionaremos nuestro directorio.
PROGRAMACIÓN DE GRÁFICOS CON R
3
Para salir de R es suficiente con teclear «q()» en la línea de instrucciones. Si trabajamos con cualquiera de los GUIs, suele haber además un menú con la opción «Salir» (como se observa en la anterior ventana). Cualquiera que sea la forma que escojamos para salir, se nos preguntará si queremos guardar o no el área de trabajo. En el área de trabajo se guardan objetos que hayamos creado y que quedan disponibles hasta la próxima vez que deseemos utilizarlos abriendo el archivo. Se guarda como un archivo con extensión Rdata. Es posible tener abiertas simultáneamente varias áreas de trabajo. También es posible guardar la serie de instrucciones que hayamos escrito, como archivo Rhistory. No obstante, para esto es más interesante la opción de editarlos creando un script, como veremos a continuación.
I.1.4. PAQUETES GRÁFICOS Para realizar cualquier aplicación con R se usa un paquete, que es un archivo con el código que contiene las funciones que nos interesa utilizar. Estos paquetes son programados por usuarios que los ponen a disposición pública en los repositorios de «CRAN». Una librería es un directorio donde se instala un determinado grupo de paquetes. Hay un listado con todos los paquetes disponibles, incluyendo también todos los paquetes gráficos, en la página web de R: http://cran.r-project.org/web/packages/available_packages_by_name.html# available-packages-L. Para ver solamente los paquetes que incluyen funciones gráficas véase la página http://rgm2.lab.nig.ac.jp/RGM2/images.php?show=all donde, además de tener una lista de los paquetes, también se muestran los gráficos. Las diferentes instrucciones de R para realizar gráficos, que forman parte de los diferentes paquetes, se pueden dividir en: x x
Funciones gráficas. Permiten realizar diferentes tipos de gráficos y tienen sus propios argumentos específicos. Complementos gráficos. Son también funciones que permiten añadir a los gráficos líneas, textos, flechas, leyendas, etiquetas, etc., y también tienen sus propios argumentos específicos.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
4 x
Argumentos generales. Son argumentos que se pueden usar en las funciones y complementos gráficos anteriores, además de los argumentos específicos de cada una de ellas.
El siguiente esquema resume la estructura de los paquetes, con sus funciones, las cuales tienen argumentos específicos y también pueden usar argumentos generales que son de uso común para todas las funciones.
Paquetes
Funciones
Argumentos específicos
Argumentos generales
plot()
type=
xm ain=
contour()
nlevels=
triangle. plot()
addm ean=
text() graphics
ade4
xlim it=
El modo más elemental de instalar un paquete es ejecutando la siguiente instrucción:
¾
install.packages("nombre del paquete", dep=TRUE)
El nombre del paquete se escribe entre comillas, y después de la coma es muy recomendable incluir el argumento «dep=TRUE», que indica que se instalen también las dependencias de ese paquete. Las dependencias son otros paquetes que contienen elementos necesarios para que funcionen todas las aplicaciones que hay en el paquete que queramos instalar. Sin esas dependencias, algunas aplicaciones de nuestro paquete podrían no funcionar. Los GUIs suelen incluir algún tipo de menú para instalar paquetes. Por ejemplo, en RGui se encuentra en «Paquetes» Ö «Instalar paquetes(s)…», y ya instala por defecto todas las dependencias.
PROGRAMACIÓN DE GRÁFICOS CON R
5
Inmediatamente después de la anterior instrucción, aparece una ventana en la que se nos pide que seleccionemos un servidor “espejo” desde el que podamos descargar el paquete. Suele escogerse por proximidad geográfica. Todos los europeos funcionan bien. Después de seleccionar el servidor, elegimos el paquete en la lista alfabética, y se descargará de forma automática, quedando instalado en ese ordenador de forma permanente.
Cuando se instala un paquete se instalan las funciones que contiene y, en muchos casos, también se instalan datos que se utilizan para ilustrar los ejemplos de uso de las funciones. Para acceder a una lista completa de todas las funciones dentro de un paquete, teclearíamos la siguiente instrucción:
¾ library(help="graphics") La mejor forma de consultar la lista de argumentos disponibles de cada función es cargando el paquete y luego ver el menú ayuda de la función:
¾ library(vcd) ¾ help(assoc) Existen demos que nos muestran buenos ejemplos de gráficos con su correspondiente código:
¾ demo(graphics)
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
6 ¾ demo(image)
Las funciones gráficas que permiten hacer los distintos tipos de gráficos se explicarán en el siguiente capítulo. Como los complementos gráficos y los argumentos generales son importantes cuando se realiza cualquier tipo de gráfico, se explicarán antes de pasar a ver todas las funciones gráficas disponibles en R.
I.1.5. SCRIPTS Y ARCHIVOS QUE SE USAN EN EL LIBRO Todos los scripts y archivos con los datos utilizados en los ejemplos de este libro se pueden descargar de la página web http://www.ipez.es/GRAFICOS_ ESTADISTICOS_Y_MAPAS_CON_R.rar.
I.2. Complementos gráficos Como se mencionó anteriormente, los complementos gráficos son también funciones que sirven para añadir a los gráficos líneas, textos, cuadros, flechas, leyendas, etiquetas, etc. Por lo tanto sirven para complementar los gráficos que se realizan con las funciones gráficas que veremos en el siguiente capítulo. En el esquema que sigue se muestra en primer lugar cada función y la página de este libro donde se puede encontrar un ejemplo de utilización. Después se explica para que sirve, el paquete al que pertenece, y los argumentos específicos que tiene, junto con sus valores por defecto, indicados con el símbolo ‘*’ en la descripción de los argumentos. a y b: intersección y pendiente de la recta h: valor de y en una línea horizontal v: valor de x en una línea vertical
abline pág. 41
Añade líneas: Paquete graphics abline(a = NULL, b = NULL, h = NULL, v = NULL, reg = NULL, coef = NULL, untf = FALSE,....)
reg: un vector del tipo c(a,b) con la intersección y pendiente de la regresión coef: Se especifica una regresión, por ejemplo coef (lm c(x~y)) untf: FALSE* o TRUE. Si un eje tiene transformación log y se pone TRUE, representa la línea sin transformar
PROGRAMACIÓN DE GRÁFICOS CON R
7
x0 e y0: coordenadas de origen
arrows pág. 97
Representa flechas: Paquete graphics arrows(x0, y0, x1, y1, length = 0,25, angle = 30, code = 2, col, lty, lwd,....)
x1 e y 1 : finales
coordenadas
length: longitud en pulgadas de la punta de flecha angle: ángulo de punta de la flecha
la
code: tipo de flecha
side: 1 eje inferior, 2 eje izquierdo, 3 eje superior y 4 eje derecho at: variable con los valores donde se pondrán las divisiones del eje. En caso de no ponerla se calculan automáticamente
axis pág. 95
Añade ejes: Paquete graphics axis(side, at = NULL, labels = TRUE, tick = TRUE, line = NA, pos = NA, outer = FALSE,font = NA, lty = "solid", lwd = 1, lwd.ticks = lwd, col = NULL, col.ticks = NULL, hadj = NA, padj = NA.....)
labels: TRUE*, FALSE, variable con las etiquetas de los intervalos, un carácter o un vector tick: valor lógico (TRUE* o FALSE) que indica si se representan los intervalos line: número de líneas de separación con el eje pos: coordenada donde se pondrá el eje outer: valor lógico (TRUE o FALSE*) que define si el eje se representa fuera o dentro de los márgenes del gráfico hadj y padj: ajustes horizontales y verticales en una escala de 0 a 1
8
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
box pág.95
Pinta un marco en el gráfico: Paquete graphics box(which = "plot", lty,....)
grid pág. 48
Representa una cuadrícula: Paquete graphics grid(nx = NULL, ny = nx, col = "lightgray", lty = "dotted", lwd = par("lwd"),....)
which: indica donde representar el marco y puede ser "plot", "figure", "inner" o "outer"
nx y ny: número de celdas en las direcciones x e y. Por defecto utiliza las divisiones de los ejes
x e y: coordenadas de la leyenda legend: texto de la leyenda
legend pág. 42
Añade una leyenda: Paquete graphics legend(xx, y = NULL, legend, fill = NULL, col = par("col"), border="black", lty, lwd,pch, angle = 45, density = NULL, bty = "o", bg = par("bg"), box.lwd = par("lwd"), box.lty = par("lty"), box.col = par("fg"), pt.bg = NA, cex = 1, pt.cex = cex, pt.lwd = lwd, xjust = 0, yjust = 1, x.intersp = 1, y.intersp = 1, adj = c(0, 0.5), text.width = NULL, text.col = par("col"), merge = do.lines && has.pch, trace = FALSE, plot = TRUE, ncol = 1, horiz = FALSE, title = NULL, inset = 0, xpd, title.col = text.col, title.adj = 0.5, seg.len = 2
fill: color de relleno ncol: número de columnas horiz: si es TRUE los textos son horizontales
La posición de la leyenda se especifica con coordenadas o con palabras clave: "bottomright", "bottom", "bottomleft", "topleft", "left", "top", "topright", "right" o "center" bty: define el marco de la leyenda: "o" con marco y "n" sin marco
lines pág. 58
Añade líneas o une los puntos con líneas: Paquete graphics lines(x = NULL, y = NULL, type = "l",....)
x, y: coordenadas de los puntos a unir mediante líneas type: véase la función «plot()» para ver los distintos tipos de línea
PROGRAMACIÓN DE GRÁFICOS CON R
locator pág. 42
Permite definir con el ratón la posición de objetos en el panel gráfico y devuelve las coordenadas: Paquete graphics locator(n = 512, type = "n",....)
9
n: el número máximo de objetos que se desea ubicar type: Con "n" ubica cualquier objeto, con "p" representa símbolos y con "l" pinta líneas uniendo los puntos, para lo cual n debe ser mayor que 1 text: texto side: eje donde se ubicará el texto; abajo (1), izquierda (2), arriba (3), y derecha (4) line: valor numérico con la distancia, en líneas, desde el eje outer: si es TRUE utiliza los márgenes exteriores si están disponibles
mtext pág. 46
Permite añadir textos en el margen del gráfico: Paquete graphics mtext(text, side = 3, line = 0, outer = FALSE, at = NA, adj = NA, padj = NA, cex, col, font,...)
at: posición en el gráfico donde se quiere escribir el texto adj: ajuste del texto en el sentido de la dirección de lectura. Para los textos paralelos a los ejes, adj = 0 significa alineación hacia la izquierda o abajo, y adj = 1 significa alineación derecha o arriba. padj: ajuste del texto perpendicular a la dirección de lectura (que es controlada por adj). Para los textos paralelos a los ejes, padj = 0 significa alineación derecha o arriba, y padj = 1 significa alineación hacia la izquierda o abajo.
10
points pág. 42
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Permite representar símbolos en la coordenadas especificadas: Paquete graphics points(x, y, type = "p",....)
x e y: coordenadas de los puntos type: véase la función «plot()» para ver los distintos tipos de gráficos x e y: coordenadas de los vértices del polígono
polygon pág. 44
Representa polígonos: Paquete graphics polygon (c(x1,x2), c(y1,y2), density = NULL, angle = 45, border = NULL, col, lty,....)
density: densidad sombreado
del
angle: ángulo de las líneas del sombreado border: color del borde, NA es sin borde y NULL* con el color por defecto (negro) xleft, ybottom, xright, ytop: extremos del rectángulo
rect pág. 58
Pinta un rectángulo: Paquete graphics rect(xleft, ybottom, xright, ytop, density = NULL, angle = 45, col = NA, border = TRUE, lty, lwd,...)
density: densidad sombreado
del
angle: ángulo de líneas de sombreado
las
border: si es TRUE se pinta un borde y NA sin bordes
rug pág. 95
segments pág. 58
Añade al gráfico una “alfombra”, con pequeños trazos verticales en cada punto z del eje horizontal: Paquete graphics rug(z, ticksize = 0.03, side = 1, lwd = 0.5, col,....)
Dibuja segmentos entre puntos: Paquete graphics segments(x0, y0, x1, y1, col, lty, lwd,....)
z: posición en el eje x ticksize: longitud de los trazos verticales side: lado en el que dibujará la alfombra: 1 inferior, 3 superior
x0, y0, x1, y1: coordenadas de origen y final de la línea
PROGRAMACIÓN DE GRÁFICOS CON R
11
x o y: coordenadas donde se ubicará el texto
text pág. 44
Permite añadir etiquetas a las coordenadas de un gráfico: Paquete graphics text(x, y = NULL, labels, adj = NULL, srt, offset = 0.5, pos = NULL, cex = 1, col = NULL, font = NULL, ...)
labels: texto que se quiere escribir o variable con las etiquetas del texto de los puntos srt: ángulo del texto offset: posición del texto en el eje vertical respecto a la coordenada pos: eje donde se ubicará el texto; abajo (1), izquierda (2), arriba (3), y derecha (4) main: texto del título del gráfico sub: subtítulo
title pág. 40
Añade texto en títulos o leyendas: Paquete graphics title(main = NULL, sub = NULL, xlab = NULL, ylab = NULL, line = NA, outer = FALSE, ...)
xlab: leyenda del eje x ylab: leyenda del eje y line: valor numérico que define la separación del texto con respecto al gráfico outer: si es TRUE utiliza los márgenes exteriores si están disponibles
I.3. Argumentos generales En la sección anterior se mostraron los complementos gráficos. A continuación se resumen los argumentos gráficos generales, es decir, aquellos que se pueden usar en la mayoría de las funciones y complementos gráficos. La estructura de los esquemas consiste en mostrar en primer lugar el argumento y la página donde se da un ejemplo del mismo, después se explica para que sirve y, por último, los diferentes valores que tiene (el símbolo * indica cual es la opción por defecto que tiene el argumento). La abreviación A.L. indica que son argumentos solamente de lectura.
12
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Los siguientes argumentos solamente se usan con la función «par()»: «fig», «fin», «mai», «mar», «mex», «mfcol», «mfrow», «new», «oma», «omd», «omi», «pin», «plt», «ps», «pty», «xlog» e «ylog». El resto de argumentos con la mayoría de funciones gráficas, además de la función «par()».
add pág. 46
Si se selecciona TRUE añade el gráfico a uno ya creado. Es igual al argumento «new», pero este último solamente se usa con la función «par()». No se puede usar con todas las funciones gráficas
FALSE* TRUE
0 (texto a la izquierda)
adj pág. 95
Especifica la alineación de los textos en los gráficos y también sirve para las funciones «text», «mtext» y «title»
0.5 (texto centrado)* 1 (texto a la derecha) Puede tomar cualquier valor entre 0 y 1, y algunas funciones permiten valores mayores
ann pág. 95
ask pág. 174
asp pág. 40
axes
Si se selecciona FALSE elimina las leyendas de los ejes y los títulos de los gráficos cuando se usa con la función «plot.default»
TRUE* FALSE TRUE
Si es TRUE se pregunta antes de añadir un nuevo gráfico
Define la proporción de escala o relación de aspecto de los ejes: una unidad en x tiene la misma longitud que asp unidades en y
FALSE*
Cualquier valor numérico positivo: 1*
TRUE*
pág. 99
Especifica si se representan los ejes del gráfico
bg pág. 42
Define el color de fondo de la ventana donde se ubicarán los gráficos
FALSE La función «colors()» informa de los 657 colores disponibles
PROGRAMACIÓN DE GRÁFICOS CON R
bg en «plot.default» y «points» pág. 42
En la función «plot.default» indica el relleno de los símbolos que son transparentes y en «points» indica el relleno de los símbolos pch = 21 a 25
13
La función «colors()» informa de los 657 colores disponibles
"o" (marco completo)* "n" (sin marco en la función «legend») "c" (no se representa el borde derecho)
bty pág. 42
Permite definir el tipo de marco de los gráficos. En el caso de la función «legend» solamente admite los valores "o" (con marco ) y "n" (sin marco)
"u" (no se representa el borde superior) "l" (no se representan los bordes superior y derecho) "7" (no se representan los bordes inferior e izquierdo)
"]" (no se representa el borde izquierdo)
cex.axis (rótulos de los ejes)
cex pág. 40
Valor numérico que define el tamaño de los textos. Se puede combinar con alguno de los siguientes subargumentos para especificar el tipo de texto
cex.lab (leyendas de los ejes) cex.main (título del gráfico) cex.sub (subtítulo del gráfico)
14
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
col.axis (rótulos de los ejes)
col pág. 42
col.lab (leyendas de los ejes) Define el color col.main (título del gráfico) col.sub (subtítulo del gráfico)
cra pág. 95
din pág. 95
Argumento de lectura que da información sobre el ancho y el alto de los caracteres en píxeles
A.L.
Argumento de lectura que da información sobre el ancho y el alto del gráfico en pulgadas
A.L.
"" (Utiliza el tipo de letra que existe por defecto)* family pág. 40
Especifica el tipo de letra de los textos. Se puede utilizar en «par()» y en «text()»
Otros tipos de letras como "serif", "sans", "mono", etc
fg pág. 83
Si se usa con la función «par()», se define el color del marco, líneas y texto del gráfico
La función «colors()» informa de los 657 colores disponibles
fig pág. 92
Define los límites del gráfico con el formato c(x1, x2, y1, y2). Si no se usa con el argumento «new= TRUE» crea un nuevo gráfico.
En una escala de 0 a1
fin pág. 92
Define el tamaño del gráfico en pulgadas con el formato c(ancho, alto). Si no se usa con el argumento «new=TRUE» crea un nuevo gráfico.
Cualquier valor numérico
PROGRAMACIÓN DE GRÁFICOS CON R
15 font.axis (rótulos de los ejes)
font pág. 40
Valor numérico que define la fuente de los textos. El valor 1 es la letra normal, 2 es negrita, 3 es itálica y 4 es itálica y negrita
font.lab (leyendas de los ejes) font.main (título del gráfico) font.sub (subtítulo del gráfico)
lab pág. 58
Valor numérico con el formato c(x,y,len) que define el número de divisiones de los ejes. El valor de «len» hay que especificarlo pero R no lo utiliza
Cualquier valor numérico (5,5,7)*
0* es paralelo al eje
las pág. 97
Define la posición de las etiquetas de los ejes
1 horizontal 2 perpendicular al eje 3 vertical
lend pág. 54
Define el estilo del final de la línea y se puede especificar con un número o letras
0 o "round" es un extremo redondeado* 1 o "butt" es un extremo grueso 2 o "square" es un extremo cuadrado
0 ó "blank" sin línea
lty pág. 48
Define el tipo de línea
1 o "solid" línea sólida*
1
2 ó "dashed" línea discontinua
2
3 ó "dotted" línea punteada
3
4 ó "dotdash" línea de puntos y rayas
4
5 ó "longdash" línea de guión largo
5
6 ó "twodash" línea de doble raya
6
16
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
lwd pág. 60
Define el grosor de línea
Cualquier valor numérico 1*
mai pág. 99
Un vector numérico con el formato c(abajo, izquierda, arriba, derecha) que define los márgenes de la figura en pulgadas
Cualquier valor numérico
main pág. 40
Permite poner títulos en los gráficos
Cualquier texto
mar pág. 99
Un vector numérico con el formato c(abajo, izquierda, arriba, derecha) que define el número de líneas de los márgenes de la figura
Cualquier valor numérico
mex pág. 94
Factor de expansión del tamaño de caracteres en los márgenes
Cualquier valor numérico
mfcol pág. 48
Vector con el formato c(nr, nc) que indica el número de figuras por fila (nr) y por columna (nc), rellenando primero columnas
Cualquier valor numérico
mfrow pág. 48
Igual que «mfcol» pero rellenando primero las filas
Cualquier valor numérico
mgp pág. 48
Vector numérico con el formato c(t,e,l) que especifica la posición de la leyenda de los ejes (t), el texto de las divisiones de los ejes (e) y la línea de los ejes (l). El valor por defecto es (3,1,0)
Cualquier valor numérico
new pág. 45
Indica que el nuevo gráfico se ponga en el panel que ya existe y no se borre, por tanto, el gráfico anterior
TRUE FALSE*
oma pág. 96
Un vector numérico con el formato c(abajo, izquierda, arriba, derecha) que define los márgenes del texto en el panel, en número de líneas
Cualquier valor numérico
omd pág. 100
Vector numérico con el formato c(x1,x2,y1,y2) que define los márgenes internos donde se ubicará el gráfico, en una escala de 0 a 1
Entre 0 y 1
omi pág. 100
Un vector numérico con el formato c(abajo, izquierda, arriba, derecha) que define los márgenes del panel en pulgadas
Cualquier valor numérico
PROGRAMACIÓN DE GRÁFICOS CON R
MARGEN EXTERNO
oma (3)
omi (3)
ÁREA DEL PANEL GRÁFICO mar (3)
mai (3)
17
ÁREA DE LA FIGURA oma (2)
mar (2)
mar (4)
oma (4)
omi (2)
mai (2)
mai (4)
omi (4)
omd (1)
mar (1)
mai (1) omd (4)
omd (2) omd (3) oma (1)
omi (1)
De 1 a 14 símbolos sin relleno negro
pch pág. 40
Valor numérico entre 1 y 25 que define el tipo de símbolo (el símbolo que corresponde a cada número se muestra en el siguiente cuadro). También se puede poner entre "" cualquier carácter, como se muestra a modo de ejemplo en el cuadro con a, *, !, ¡ y $
De 15 a 20 símbolos con relleno negro De 21 a 25 se puede poner el color que se quiera en el borde con el argumento «col» y de relleno con «bg» Cualquier carácter que se ponga entre ""
1 2 3 4 5 6 7 8 9 10 Ă
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25
a * ! ¡ $
18
ps pág. 39
pty pág. 83
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Tamaño del punto de texto (unidad de medida de los caracteres) en 1/72 pulgadas Carácter que indica si el gráfico es cuadrado o se alarga lateralmente cuando se amplía la ventana
Cualquier valor numérico Con "s" genera una figura cuadrada Con "m" el gráfico se amplia al máximo posible
srt pág. 44
Valor numérico que define el ángulo del texto. Solamente funciona con la función «text()»
Cualquier valor numérico
sub pág. 129
Permite poner gráficos
Cualquier texto
tck pág. 48
tcl pág. 48
xaxp pág. 60
xaxs pág. 95
subtítulos
en
los
Valor alfanumérico que define el tamaño de las marcas de los ejes, en proporción al área de la región de la figura. El valor 1 pone líneas interiores en el gráfico
Con tck=NA deja la marca por defecto*
Valor alfanumérico que define el tamaño de las marcas de los ejes. Se diferencia de «tck» en que las medidas son reales y no en proporción
Con tck=NA deja la marca por defecto*
Vector numérico con el formato c(x1, x2, n), donde x1 y x2 son los extremos de las marcas de eje x, y n el número de intervalos o marcas en el eje
Caracter que define como se calculan los intervalos en el eje x, donde el límite viene definido por «xlim» o los datos originales
Cualquier otro valor numérico
Cualquier otro valor numérico
Cualquier valor numérico
"r" (regular) extiende un 4% más de los límites dados en «xlim», y calcula el número de intervalos que mejor se ajustan a esos límites* "i" (interno) busca el número de intervalos más adecuado a los datos originales
xaxt pág. 96
Valor lógico que especifica si se representan los intervalos del eje x
"s"* "n"
PROGRAMACIÓN DE GRÁFICOS CON R
19
xlab pág. 40
Texto de la leyenda del eje x
Cualquier texto
xlim pág. 42
Vector numérico con el formato c(x0, x1), donde x0 y x1 son los límites del eje x
Cualquier valor numérico
xlog pág. 58
yaxp pág. 60
yaxs pág. 95
Valor lógico que especifica si se pone el eje x en escala logarítmica
Vector numérico con el formato c(y1, y2, n), donde y1 e y2 son los extremos de las marcas del eje y, y n el número de intervalos o marcas en el eje
Caracter que define como se calculan los intervalos en el eje y, donde el límite viene definido por «ylim» o los datos originales
FALSE* TRUE
Cualquier valor numérico
"r" (regular) extiende un 4% más de los límites dados en «ylim», y calcula el número de intervalos que mejor se ajustan a esos límites* "i" (interno) busca el número de intervalos más adecuado a los datos originales
yaxt pág. 96
Valor lógico que especifica si se representan los intervalos del eje y
"s"* "n"
ylab pág. 40
Texto de la leyenda del eje y
Cualquier texto
ylim pág. 42
Vector numérico con el formato c(y0, y1), donde y0 e y1 son los límites del eje y
Cualquier valor numérico
ylog pág. 58
Valor lógico que especifica si se pone el eje y en escala logarítmica
FALSE* TRUE
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
20 I.4. Colores
Con la función «colors()», que viene en el paquete básico, es posible obtener un listado de los 657 colores disponibles. "white" "antiquewhite1" "antiquewhite4" "aquamarine2" "azure" "azure3" "bisque" "bisque3" "blanchedalmond" "blue2" "blueviolet" "brown2" "burlywood" "burlywood3" "cadetblue1" "cadetblue4" "chartreuse2" "chocolate" "chocolate3" "coral1" "coral4" "cornsilk1" "cornsilk4" "cyan2" "darkblue" "darkgoldenrod1" "darkgoldenrod4" "darkgrey" "darkolivegreen" "darkolivegreen3" "darkorange1" "darkorange4" "darkorchid2" "darkred" "darkseagreen1" "darkseagreen4" "darkslategray1" "darkslategray4" "darkviolet" "deeppink2" "deepskyblue" "deepskyblue3" "dimgrey" "dodgerblue2" "firebrick" "firebrick3"
"aliceblue" "antiquewhite2" "aquamarine" "aquamarine3" "azure1" "azure4" "bisque1" "bisque4" "blue" "blue3" "brown" "brown3" "burlywood1" "burlywood4" "cadetblue2" "chartreuse" "chartreuse3" "chocolate1" "chocolate4" "coral2" "cornflowerblue" "cornsilk2" "cyan" "cyan3" "darkcyan" "darkgoldenrod2" "darkgray" "darkkhaki" "darkolivegreen1" "darkolivegreen4" "darkorange2" "darkorchid" "darkorchid3" "darksalmon" "darkseagreen2" "darkslateblue" "darkslategray2" "darkslategrey" "deeppink" "deeppink3" "deepskyblue1" "deepskyblue4" "dodgerblue" "dodgerblue3" "firebrick1" "firebrick4"
"antiquewhite" "antiquewhite3" "aquamarine1" "aquamarine4" "azure2" "beige" "bisque2" "black" "blue1" "blue4" "brown1" "brown4" "burlywood2" "cadetblue" "cadetblue3" "chartreuse1" "chartreuse4" "chocolate2" "coral" "coral3" "cornsilk" "cornsilk3" "cyan1" "cyan4" "darkgoldenrod" "darkgoldenrod3" "darkgreen" "darkmagenta" "darkolivegreen2" "darkorange" "darkorange3" "darkorchid1" "darkorchid4" "darkseagreen" "darkseagreen3" "darkslategray" "darkslategray3" "darkturquoise" "deeppink1" "deeppink4" "deepskyblue2" "dimgray" "dodgerblue1" "dodgerblue4" "firebrick2" "floralwhite"
PROGRAMACIÓN DE GRÁFICOS CON R "forestgreen" "gold" "gold3" "goldenrod1" "goldenrod4" "gray1" "gray4" "gray7" "gray10" "gray13" "gray16" "gray19" "gray22" "gray25" "gray28" "gray31" "gray34" "gray37" "gray40" "gray43" "gray46" "gray49" "gray52" "gray55" "gray58" "gray61" "gray64" "gray67" "gray70" "gray73" "gray76" "gray79" "gray82" "gray85" "gray88" "gray91" "gray94" "gray97" "gray100" "green2" "greenyellow" "grey1" "grey4" "grey7" "grey10" "grey13" "grey16" "grey19" "grey22" "grey25" "grey28" "grey31"
"gainsboro" "gold1" "gold4" "goldenrod2" "gray" "gray2" "gray5" "gray8" "gray11" "gray14" "gray17" "gray20" "gray23" "gray26" "gray29" "gray32" "gray35" "gray38" "gray41" "gray44" "gray47" "gray50" "gray53" "gray56" "gray59" "gray62" "gray65" "gray68" "gray71" "gray74" "gray77" "gray80" "gray83" "gray86" "gray89" "gray92" "gray95" "gray98" "green" "green3" "grey" "grey2" "grey5" "grey8" "grey11" "grey14" "grey17" "grey20" "grey23" "grey26" "grey29" "grey32"
"ghostwhite" "gold2" "goldenrod" "goldenrod3" "gray0" "gray3" "gray6" "gray9" "gray12" "gray15" "gray18" "gray21" "gray24" "gray27" "gray30" "gray33" "gray36" "gray39" "gray42" "gray45" "gray48" "gray51" "gray54" "gray57" "gray60" "gray63" "gray66" "gray69" "gray72" "gray75" "gray78" "gray81" "gray84" "gray87" "gray90" "gray93" "gray96" "gray99" "green1" "green4" "grey0" "grey3" "grey6" "grey9" "grey12" "grey15" "grey18" "grey21" "grey24" "grey27" "grey30" "grey33"
21
22
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R "grey34" "grey37" "grey40" "grey43" "grey46" "grey49" "grey52" "grey55" "grey58" "grey61" "grey64" "grey67" "grey70" "grey73" "grey76" "grey79" "grey82" "grey85" "grey88" "grey91" "grey94" "grey97" "grey100" "honeydew2" "hotpink" "hotpink3" "indianred1" "indianred4" "ivory2" "khaki" "khaki3" "lavenderblush" "lavenderblush3" "lemonchiffon" "lemonchiffon3" "lightblue1" "lightblue4" "lightcyan1" "lightcyan4" "lightgoldenrod2" "lightgoldenrodyellow" "lightgrey" "lightpink2" "lightsalmon" "lightsalmon3" "lightskyblue" "lightskyblue3" "lightslategray" "lightsteelblue1" "lightsteelblue4" "lightyellow2" "limegreen"
"grey35" "grey38" "grey41" "grey44" "grey47" "grey50" "grey53" "grey56" "grey59" "grey62" "grey65" "grey68" "grey71" "grey74" "grey77" "grey80" "grey83" "grey86" "grey89" "grey92" "grey95" "grey98" "honeydew" "honeydew3" "hotpink1" "hotpink4" "indianred2" "ivory" "ivory3" "khaki1" "khaki4" "lavenderblush1" "lavenderblush4" "lemonchiffon1" "lemonchiffon4" "lightblue2" "lightcoral" "lightcyan2" "lightgoldenrod" "lightgoldenrod3" "lightgray" "lightpink" "lightpink3" "lightsalmon1" "lightsalmon4" "lightskyblue1" "lightskyblue4" "lightslategrey" "lightsteelblue2" "lightyellow" "lightyellow3" "linen"
"grey36" "grey39" "grey42" "grey45" "grey48" "grey51" "grey54" "grey57" "grey60" "grey63" "grey66" "grey69" "grey72" "grey75" "grey78" "grey81" "grey84" "grey87" "grey90" "grey93" "grey96" "grey99" "honeydew1" "honeydew4" "hotpink2" "indianred" "indianred3" "ivory1" "ivory4" "khaki2" "lavender" "lavenderblush2" "lawngreen" "lemonchiffon2" "lightblue" "lightblue3" "lightcyan" "lightcyan3" "lightgoldenrod1" "lightgoldenrod4" "lightgreen" "lightpink1" "lightpink4" "lightsalmon2" "lightseagreen" "lightskyblue2" "lightslateblue" "lightsteelblue" "lightsteelblue3" "lightyellow1" "lightyellow4" "magenta"
PROGRAMACIÓN DE GRÁFICOS CON R "magenta1" "magenta4" "maroon2" "mediumaquamarine" "mediumorchid1" "mediumorchid4" "mediumpurple2" "mediumseagreen" "mediumturquoise" "mintcream" "mistyrose2" "moccasin" "navajowhite2" "navy" "olivedrab" "olivedrab3" "orange1" "orange4" "orangered2" "orchid" "orchid3" "palegreen" "palegreen3" "paleturquoise1" "paleturquoise4" "palevioletred2" "papayawhip" "peachpuff2" "peru" "pink2" "plum" "plum3" "purple" "purple3" "red1" "red4" "rosybrown2" "royalblue" "royalblue3" "salmon" "salmon3" "seagreen" "seagreen3" "seashell1" "seashell4" "sienna2" "skyblue" "skyblue3" "slateblue1" "slateblue4" "slategray2" "slategrey"
"magenta2" "maroon" "maroon3" "mediumblue" "mediumorchid2" "mediumpurple" "mediumpurple3" "mediumslateblue" "mediumvioletred" "mistyrose" "mistyrose3" "navajowhite" "navajowhite3" "navyblue" "olivedrab1" "olivedrab4" "orange2" "orangered" "orangered3" "orchid1" "orchid4" "palegreen1" "palegreen4" "paleturquoise2" "palevioletred" "palevioletred3" "peachpuff" "peachpuff3" "pink" "pink3" "plum1" "plum4" "purple1" "purple4" "red2" "rosybrown" "rosybrown3" "royalblue1" "royalblue4" "salmon1" "salmon4" "seagreen1" "seagreen4" "seashell2" "sienna" "sienna3" "skyblue1" "skyblue4" "slateblue2" "slategray" "slategray3" "snow"
"magenta3" "maroon1" "maroon4" "mediumorchid" "mediumorchid3" "mediumpurple1" "mediumpurple4" "mediumspringgreen" "midnightblue" "mistyrose1" "mistyrose4" "navajowhite1" "navajowhite4" "oldlace" "olivedrab2" "orange" "orange3" "orangered1" "orangered4" "orchid2" "palegoldenrod" "palegreen2" "paleturquoise" "paleturquoise3" "palevioletred1" "palevioletred4" "peachpuff1" "peachpuff4" "pink1" "pink4" "plum2" "powderblue" "purple2" "red" "red3" "rosybrown1" "rosybrown4" "royalblue2" "saddlebrown" "salmon2" "sandybrown" "seagreen2" "seashell" "seashell3" "sienna1" "sienna4" "skyblue2" "slateblue" "slateblue3" "slategray1" "slategray4" "snow1"
23
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
24
"snow2" "springgreen" "springgreen3" "steelblue1" "steelblue4" "tan2" "thistle" "thistle3" "tomato1" "tomato4" "turquoise2" "violet" "violetred2" "wheat" "wheat3" "yellow" "yellow3"
"snow3" "springgreen1" "springgreen4" "steelblue2" "tan" "tan3" "thistle1" "thistle4" "tomato2" "turquoise" "turquoise3" "violetred" "violetred3" "wheat1" "wheat4" "yellow1" "yellow4"
"snow4" "springgreen2" "steelblue" "steelblue3" "tan1" "tan4" "thistle2" "tomato" "tomato3" "turquoise1" "turquoise4" "violetred1" "violetred4" "wheat2" "whitesmoke" "yellow2" "yellowgreen"
La función «colorTable()» del paquete “fBasics” (Wuertz, 2011) permite ver los números de los diferentes tipos de colores.
¾ library(fBasics) ¾ colorTable(cex=1) 0
10
20
30
40
50
60
70
80
90
1
11
21
31
41
51
61
71
81
91
2
12
22
32
42
52
62
72
82
92
3
13
23
33
43
53
63
73
83
93
4
14
24
34
44
54
64
74
84
94
5
15
25
35
45
55
65
75
85
95
6
16
26
36
46
56
66
76
86
96
7
17
27
37
47
57
67
77
87
97
8
18
28
38
48
58
68
78
88
98
9
19
29
39
49
59
69
79
89
99
La función «show.colors()» del paquete “DAAG” (Maindonald, 2011) permite ver los nombres de los diferentes tipos de colores: "singles" son los colores que no tienen diferentes intensidades, "shades" son los que si tienen diferentes intensidades y "gray" es para ver la escala de grises.
PROGRAMACIÓN DE GRÁFICOS CON R
25
¾ library(DAAG) ¾ show.colors("singles") darkred
navy
darkmagenta
midnightblue
mediumvioletred
darkviolet
gainsboro
peru
darkslateblue
palegoldenrod
lightcoral
blueviolet
moccasin
darksalmon
dimgray
lavender
sandybrown
mediumslateblue
blanchedalmond
black
lightslateblue
papayawhip
darkgreen
lightslategray
linen
forestgreen
cornflowerblue
beige
mediumseagreen
lightseagreen
oldlace
limegreen
violet
aliceblue
darkkhaki
darkturquoise
lightgoldenrodyellow
mediumspringgreen
darkgray
ghostwhite
lawngreen
mediumturquoise
floralwhite
lightgreen
lightgray
mintcream
greenyellow
powderblue
white
¾ show.colors("shades") 1
2
3
4
1
2
3
4
1
2
3
4
red
darkgoldenrod
slateblue
magenta
lightpink
dodgerblue
deeppink
goldenrod
mediumorchid
lightblue
firebrick
gold
mediumpurple
bisque
orangered
burlywood
deepskyblue
darkslategray
maroon
green
orchid
wheat
brown
springgreen
steelblue
thistle
violetred
chartreuse
turquoise
mistyrose
tomato
seagreen
skyblue
paleturquoise
indianred
palegreen
pink
antiquewhite
coral
olivedrab
cyan
lavenderblush
darkorange
lightgoldenrod
plum
seashell
chocolate
darkolivegreen
rosybrown
lemonchiffon
hotpink
yellow
lightskyblue
cornsilk
sienna
darkseagreen
lightsteelblue
lightcyan
palevioletred
khaki
slategray
honeydew
salmon
blue
peachpuff
snow
orange
purple
aquamarine
azure
lightsalmon
darkorchid
navajowhite
lightyellow
tan
royalblue
cadetblue
ivory
1
2
3
4
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
26
¾ show.colors("gray") gray
gray25
gray51
gray1
gray26
gray52
gray76
gray2
gray27
gray53
gray77
gray3
gray28
gray54
gray78
gray4
gray29
gray55
gray79
gray5
gray30
gray56
gray80
gray6
gray31
gray57
gray81
gray7
gray32
gray58
gray82
gray8
gray33
gray59
gray83
gray9
gray34
gray60
gray84
gray10
gray35
gray61
gray85
gray11
gray36
gray62
gray86
gray12
gray37
gray63
gray87
gray13
gray38
gray64
gray88
gray14
gray39
gray65
gray89
gray15
gray40
gray66
gray90
gray16
gray42
gray67
gray91
gray17
gray43
gray68
gray92
gray18
gray44
gray69
gray93
gray19
gray45
gray70
gray94
gray20
gray46
gray71
gray95
gray21
gray47
gray72
gray96
gray22
gray48
gray73
gray97
gray23
gray49
gray74
gray98
gray24
gray50
gray75
gray99
En el script I.1.R se muestran las tres funciones más importantes que permiten representar colores. La función «rgb()» permite hacer múltiples combinaciones de colores, donde el primer número es para definir la intensidad del color rojo, el segundo para el verde y el tercero para el azul, en una escala de 0 a 255. El argumento «alpha» indica el grado de transparencia (rango de 0 a 255).
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
plot(0,0, type="n", xlim=c(-1,10), ylim=c(0,10), axes=F, xlab="", ylab="") text(-0.5,1.5,"rgb", cex=1.5) color<-rgb(255, 1, 1, alpha=255, maxColorValue=255) rect(0.5,1,2.5,2, col=color, border=NA) text(1.5,2.5, "255, 1, 1") color<-rgb(100, 255, 50, alpha=255, maxColorValue=255) rect(3.5,1,5.5,2, col=color, border=NA) text(4.5,2.5, "100, 255, 50") color<-rgb(1, 1, 255, alpha=255, maxColorValue=255) rect(6.5,1,8.5,2, col=color, border=NA) text(7.5,2.5, "1, 1, 255")
PROGRAMACIÓN DE GRÁFICOS CON R
27
La función «hcl()» también permite hacer diferentes colores, donde «h» define el color en un rango de 0 a 360, «c» es la intensidad de color (de 0 a 100) y «l» es la luminosidad (también de 0 a 100, valores más pequeños es más oscuro).
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
text(-0.5,4.5,"hcl", cex=1.5) color<-hcl(h = 188, c = 100, l =2, alpha=1) rect(0.5,4,2.5,5, col=color, border=NA) text(1.5,5.5, "188, 100, 2") color<-hcl(h = 120, c = 100, l = 88, alpha=1) rect(3.5,4,5.5,5, col=color, border=NA) text(4.5,5.5, "120, 100, 88") color<-hcl(h = 240, c = 100, l = 20, alpha=1) rect(6.5,4,8.5,5, col=color, border=NA) text(7.5,5.5, "240, 100, 20")
La última función es «hsv()», donde «h» define el color, «s» es la intensidad de color, y «v» es la luminosidad (cuanto más alto, más claro es el color). Los tres argumentos tienen un rango de 0 a 1.
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
text(-0.5,7.5,"hsv", cex=1.5) color<-hsv(h = 0, s = 1, v = 1, alpha=1) rect(0.5,7,2.5,8, col=color, border=NA) text(1.5,8.5, "0, 1, 1") color<-hsv(h = 0.24, s = 1, v = 1, alpha=1) rect(3.5,7,5.5,8, col=color, border=NA) text(4.5,8.5, "0.24, 1, 1") color<-hsv(h = 0.7, s = 1, v = 1, alpha=1) rect(6.5,7,8.5,8, col=color, border=NA) text(7.5,8.5, "0.7, 1, 1") 0, 1, 1
0.24, 1, 1
0.7, 1, 1
188, 100, 2
120, 100, 88
240, 100, 20
255, 1, 1
100, 255, 50
1, 1, 255
hsv
hcl
rgb Al final del script I.1.R se representa un diagrama de tarta con un bucle, para ver los cambios de color de la función «hcl()», a medida que cambian «h» y «l».
28
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
La función «color.scale()» del paquete “plotrix” (Lemon, 2012) permite utilizar algunas de las paletas mencionadas anteriormente, hcl, hsv y rgb, para poder hacer gradientes de colores. Las instrucciones están en el script I.2.R. En la primera parte del script se hace un gráfico sin ejes, para lo cual se usa el argumento «axes=FALSE», y luego se pone el eje y con la función «axis()», añadiendo etiquetas al eje. En la función «color.scale()», el argumento «x» define cual es el valor o rango de valores que tomarán los puntos. En este caso, como se representan 10 puntos, es una secuencia de 1 a 10. El argumento «alpha» indica el grado de transparencia (rango de 0 a 1). El argumento «na.color» especifica el color de los datos vacíos de la variable x. Los argumentos «cs1», «cs2», y «cs3» definen los tres parámetros de color, dependiendo del sistema utilizado. En rgb y hsv la escala es de 0 a 1 en los tres argumentos «cs1», «cs2» y «cs3». En hcl la escala es de 0 a 360 para «cs1», y de 0 a 100 para «cs2» y «cs3». En hsv y hcl, en los tres argumentos se puede poner un único valor o un vector con dos valores, que indicarían un rango. Por ejemplo, en hsv «cs1=0» indica que solo se pinta en color rojo, mientras que «cs1=c(0,0.5)» indica que varían los colores del rojo al azul.
¾ library(plotrix) ¾ plot(1:10,rep(1:3,length.out=10),axes=FALSE,type="n",xlim=c(0,11),ylim= c(0,18), main="Test de rgb, hsv y hcl",xlab="",ylab="Paletas de colores", cex.lab=1.7, cex.main=1.9) ¾ par(cex=0.8,font=2) ¾ axis(2,at=1:18,labels=c("rgb","","rgb","","rgb","","hcl","","hcl","","hcl",""," hsv","","hsv","","hsv","")) ¾ #rgb ¾ points(1:10,rep(1,10),pch=19,cex=7,col=color.scale(x=1:10,cs1=c(0,0.1,1), cs2=c(1,0.7,1),cs3=c(1,0.5,0),color.spec="rgb",alpha=1,na.color=NA)) ¾ points(1:10,rep(3,10),pch=19,cex=7,col=color.scale(x=1:10,cs1=c(0,1,1), cs2=c(1,1,0),cs3=0,color.spec="rgb",alpha=1,na.color=NA)) ¾ points(1:10,rep(5,10),pch=19,cex=7,col=color.scale(x=1:10,cs1=c(0,1,1), cs2=c(1,1,0),cs3=c(0,0.5,1),color.spec="rgb",alpha=1,na.color=NA)) ¾ #hcl ¾ points(1:10,rep(7,10), pch=19,cex=7, col=color.scale(x=1:10, cs1=c(0,100), cs2=c(25,55),cs3=c(85,25), color.spec="hcl",alpha=1,na.color=NA)) ¾ points(1:10,rep(9,10),pch=19,cex=7,col=color.scale(x=1:10,cs1=c(100,0), cs2=c(55,25),cs3=c(25,85), color.spec="hcl",alpha=1,na.color=NA)) ¾ points(1:10,rep(11,10),pch=19,cex=7,col=color.scale(x=1:10,cs1=c(200,0), cs2=c(55,85),cs3=c(55,85), color.spec="hcl",alpha=1,na.color=NA)) ¾ #hsv ¾ points(1:10,rep(13,10),pch=19,cex=7,col=color.scale(x=1:10,cs1=c(0.5,1), cs2=c(0.5,1),cs3=c(1,1),color.spec="hsv",alpha=1,na.color=NA)) ¾ points(1:10,rep(15,10),pch=19,cex=7,col=color.scale(x=1:10,cs1=c(0,1), cs2=c(0.8,1),cs3=c(0.5,1),color.spec="hsv",alpha=1,na.color=NA)) ¾ points(1:10,rep(17,10),pch=19,cex=7,col=color.scale(x=1:10,cs1=c(0.5,1), cs2=c(0.2,1),cs3=c(1,1),color.spec="hsv",alpha=1,na.color=NA))
PROGRAMACIÓN DE GRÁFICOS CON R
29
hcl hcl hcl rgb
rgb
rgb
Paletas de colores
hsv
hsv
hsv
Test de rgb, hsv y hcl
En el siguiente gráfico del script se muestra un ejemplo sencillo de cómo usar «color.scale()». En primer lugar se generan dos vectores y el color de los puntos en la función «color.scale()» lo define el valor de y. Con la función «par(oma=c(3,3,3,4))» se dejan más líneas en el eje y derecho para poder mostrar la leyenda de colores. La función «color.legend()» permite una barra de colores a modo de leyenda. Con los argumentos «xl», «yb», «xr» e «yt» se define la posición de la leyenda. Con «gradient» se especifica si el rango de colores cambia en el sentido del eje x o del y. Con el argumento «align» se especifica si las etiquetas de las leyendas se ponen por la izquierda (barra horizontal) o arriba (barra vertical) con «lt», o por la derecha (barra horizontal) o abajo (barra vertical) con «rb». Por último, en el argumento «rect.color» se debe poner la misma secuencia y tipo de colores utilizada en el gráfico.
¾ ¾ ¾ ¾
x<-c(1,20,35,46,57,50,7,18,29) y<-c(10,21,5,68,95,36,75,18,7) par(mar=c(3,3,3,4)) plot(x, y, col=color.scale(y, cs1=c(0,1,1), cs2=c(1,1,0), cs3=0, color.spec= "rgb"), pch=16,cex=3,xlab="",ylab="") ¾ color.legend(xl=61, yb=10, xr=64, yt=90, seq(1,100,by=20), gradient="y", align="rb", cex=1.2, rect.col=color.scale(seq(1,100,by=20), cs1=c(0,1,1), cs2= c(1,1,0), cs3=0, color.spec="rgb"))
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
30
80
81
60
61
40
41
20
21
1
0
10
20
30
40
50
También son muy útiles las paletas de colores que se pueden obtener con alguna de las funciones «gray.colors()», «rainbow()», «heat.colors()», «terrain.colors()», «topo.colors()» o «cm.colors()» del paquete “grDevices”, el cual se instala por defecto con R. A modo de ejemplo, las siguientes instrucciones representan un diagrama de tartas, en el cual el gradiente de colores se realiza con las funciones mencionadas anteriormente. Las instrucciones están en el script I.3.R. En todas las funciones el argumento «alpha» indica el grado de transparencia (rango de 0 a 1). En el caso de la función «rainbow()» con el argumento «s» se especifica el grado de saturación (rango de 0 a 1). Con «v» se puede oscurecer más o menos (rango de 0 a 1), donde 0 es negro y 1 es la máxima claridad. Los argumentos «start» (rango de 0 a 1) y «end» (rango de 0 a 1) son los colores corregidos donde comienza y finaliza el arco iris, respectivamente.
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
pie(rep(1,50), col=gray.colors(n=50)) text(0,1,"gray.colors()",font=2,cex=1.5) pie(rep(1,15), col=rainbow(n=15, s =1, v=1, start=0, end=0.9, alpha=1)) text(0,1,"rainbow()",font=2,cex=1.5) pie(rep(1,50), col=heat.colors(n=50)) text(0,1,"heat.colors()",font=2,cex=1.5) pie(rep(1,50), col=terrain.colors(n=50)) text(0,1,"terrain.colors()",font=2,cex=1.5) pie(rep(1,50), col=topo.colors(n=50)) text(0,1,"topo.colors()",font=2,cex=1.5) pie(rep(1,50), col=cm.colors(n=50)) text(0,1,"cm.colors()",font=2,cex=1.5)
PROGRAMACIÓN DE GRÁFICOS CON R gray.colors() 18
17
16
13 12 11
15 14
31
rainbow() 10
4
5
9
3
8
19 20 21 22 23
6
7 6
2
5 4
7 3 1
24
2
25
1
26
50
27
8
49
28 29 30 31 32
15
48 47 46 45
9 14
44 33
34
35 36 37 38
41 39 40
42
10
43
13 11
heat.colors() 18
17
16
terrain.colors()
13 12 11
15 14
12
10
9
8
19 20 21 22 23
18
7
17
16
15 14
13 12 11
10
9
8
19 20 21 22 23
6 5 4 3
7 6 5 4 3
24
2
24
2
25
1
25
1
26
50 26 49 27
27 28 29 30 31 32
48 47 46 45 44 33
34
35 36 37 38
41 39 40
42
50 49
28 29 30 31 32
43
48 47 46 45 44 33
34
35 36 37 38
18
17
16
13 12 11
10
43
cm.colors()
topo.colors() 15 14
41 39 40
42
9
18
8
19 20 21 22 23
17
16
15 14
13 12 11
10
9
8
19 20 21 22 23
7 6 5 4 3
7 6 5 4 3
24
2
24
2
25
1
25
1
26
50
26
50
27
49
27
49
28 29 30 31 32
48 47 46 45 44 33
34
35 36 37 38
41 39 40
42
43
28 29 30 31 32
48 47 46 45 44 33
34
35 36 37 38
41 39 40
42
43
32
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
I.5. Fórmulas matemáticas y caracteres especiales En muchas ocasiones a los gráficos hay que añadirles fórmulas matemáticas o texto con caracteres especiales, que se pueden realizar con la función «plotmath()» (Murrell y Ihaka, 2000), combinada con alguna de las funciones «expression()», «substitute()» y/o «paste()». A continuación se muestran algunos ejemplos, los cuales están en el script I.4.R, y en la tabla siguiente algunos códigos útiles de la función «plotmath()» para construir fórmulas y textos especiales. Para que estas instrucciones funcionen deben integrarse en los gráficos usando las funciones «mtext()», «title()» o «text()», como se mostrará en varios ejemplos en el próximo capítulo.
¾ expression(x^2==sum(sum(frac(((O[mc] - E[mc]) - frac(1,2))^2, E[mc]), c1, i), m-1, j)) ͳ ଶ ቀሺ୫ୡ െ ୫ୡ ሻ െ ቁ ʹ ଶ ൌ ୫ୡ ୨
୧
୫ିଵ ୡିଵ
¾ expression(L[t]==L[infinity](1-e^-k(t-t[0]))) ୲ ൌ ൫ͳ െ ି୩ሺ୲ି୲బ ሻ ൯ ¾ expression(a[i] == sqrt(b[i]^2 + c[i]^2)) ୧ ൌ ටଶ୧
୧ଶ ¾ expression("r"==paste(frac(paste(mu[max]*"S"), paste("K"[s]+"S")))) ൌ
Ɋ୫ୟ୶ ୱ
¾ expression(bar(x) == frac(sum(x[i], n, i==1), n)) n
ത ൌ
¦x
i
i 1
n
¾ expression(paste("Producción primaria en mg C m"^"-2","d"^"-1")) Producción primaria en mg C m-2 d-1 ¾ expression(bold(paste("Pigmentos de ", italic("Alexandrium minutum")))) Pigmentos de Alexandrium minutum
PROGRAMACIÓN DE GRÁFICOS CON R
33
Tabla I.1. Tabla de códigos para la construcción de fórmulas utilizando las funciones «plotmath()» y «expression()». n
ത Ö bar(x)
¦x
i
Ö sum(x[i], i==1, n)
f Ö infinity
i 1
ෑ ሺ ൌ ሻ Ö
ොÖ hat(x)
୶
prod(plain(P)(X==x), x) ୠ
ෞÖ widehat(xy)
ୟ ሺሻ Ö integral(f(x)*dx, a, b)
Ö alpha A Ö Alpha Ö beta B Ö Beta
୬
ራ ୧ Ö
Ö tilde(x)
୧ୀଵ
union(A[i], i==1, n)
Ö gamma Ö Gamma
୬
ሩ ୧ Ö
෦ Ö widetilde(xy)
୧ୀଵ
intersect(A[i], i==1, n) ሺሻÖ ՜Ͳ
ሶ Ö dot(x)
lim(f(x), x %->% 0) ሺሻÖ ୶வ
x Ö plain(x)
min(f(x), x > 0)
x Ö bold(x)
x y Ö x %subset% y
x Ö italic(x)
x y Ö x %subseteq% y
x Ö bolditalic(x)
x y Ö x %notsubset% y
୶ ୷
Ö frac(x,y)
x y Ö x %supset% y
୶୷ Öatop(x,y)
x y Ö x %supseteq% y
x2 Ö x^2
x y Ö x %in% y
x2 Ö x[2]
x y Ö x %notin% y
ξ Ö sqrt(x)
x
Ö displaystyle(x)
Ö delta Ö Delta Ö epsilon E Ö Epsilon Ö zeta Z Ö Zeta
Ö eta H Ö Eta Ö theta Ö Theta
Ö iota I Ö Iota Ö kappa K Ö Kappa Ö lambda Ö Lambda Ö mu M Ö Mu Ö nu N Ö Nu Ö xi Ö Xi
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
34 ౯
ξ Ö sqrt(x,y)
x Ö textstyle(x)
x r y Ö x %+-% y
x
Ö scriptstyle(x)
x / y Ö x %/% y
x
Ö scriptscriptstyle(x)
x * y Ö x %*% y
x
x d y Ö x <= y
x+ +y Ö x+phantom(0)+y
x t y Ö x >= y
x l y Ö x %<->% y
x | y Ö x %~~% y
x o y Ö x %->% y
x { y Ö x %==% y
x m y Ö x %<-% y
x # y Ö x %=~% y
x n y Ö x %up% y
x v y Ö x %prop% y
x p y Ö x %down% y
x y Ö x %<=>% y
x y Ö x %dbldown% y
x y Ö x %=>% y
x y Ö x %dblup% y
x y Ö x %<=% y
w Ö partialdiff
y Ö x ~~ y
Ö pi Ö Pi Ö rho P Ö Rho Ö sigma Ö Sigma Ö tau T Ö Tau Ö upsilon Y Ö Upsilon Ö phi Ö Phi Ö chi X Ö Chi Ö psi ! Ö Psi $ Ö omega & Ö Omega
I.6. Dispositivos para gráficos Una vez creado un gráfico es necesario visualizarlo y, para ello, existen diferentes dispositivos (devices). El más común, el cual se usa por defecto, es la pantalla y la función que controla este dispositivo es «windows()». Sin embargo, se puede visualizar el gráfico exportándolo a un archivo, que puede tener diferentes formatos, y se controlan con alguna de las siguientes funciones: «png()», «bitmap()» «jpeg()», «bmp()», «tiff()», «pdf()», «postscript()» e incluso a una impresora «win.print()». Los argumentos de estas funciones se explican en el cuadro siguiente. En el script I.5.R hay un ejemplo de la paleta de colores rgb que, además de verse en pantalla, se exporta a un archivo pdf. El mismo proceso serviría para
PROGRAMACIÓN DE GRÁFICOS CON R
35
exportarlo a otros formatos de archivo usando las funciones mencionadas anteriormente. En el script se hace una función con «function()» y varios bucles con «for()». Además se usan varias funciones gráficas como «plot()», «mtext()», «text()», «rug()» y «points()», que se explicarán en detalle en el Capítulo II. El archivo pdf con el gráfico exportado estará en el directorio de trabajo. Siempre que se exporte a un archivo es conveniente cerrar el dispositivo con la función «dev.off()». Cada vez que se ejecuta la función «windows()» se abre una ventana, es decir, que se van superponiendo las ventanas sin borrar las anteriores. En el gráfico se puede observar como varían los colores conforme cambian los valores de rojo, verde y azul.
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
#Se muestra en la pantalla windows(15,6) funcion<-function(){ plot(0,0, axes=FALSE, cex=0, xlab="", ylab="", xlim=c(0,1800), ylim = c(-30, 290), main="Paleta rgb",cex.main=2) mtext("Rojo",1,1.5,font=2,cex=1.5) text(-50,125,"Verde",font=2,cex=1.5,srt=90) text(175,275,"Azul (0)",font=2,cex=1.5) text(475,275,"Azul (50)",font=2,cex=1.5) text(775,275,"Azul (100)",font=2,cex=1.5) text(1075,275,"Azul (150)",font=2,cex=1.5) text(1375,275,"Azul (200)",font=2,cex=1.5) text(1675,275,"Azul (250)",font=2,cex=1.5) rug(325, ,ticksize=1,side=3, lwd=3, col="black") rug(625, ,ticksize=1,side=3, lwd=3, col="black") rug(925, ,ticksize=1,side=3, lwd=3, col="black") rug(1225, ,ticksize=1,side=3, lwd=3, col="black") rug(1525, ,ticksize=1,side=3, lwd=3, col="black") k<-0 i<--50 for (z in 1:6){ i<-i+50 h<--50 for (z in 1:6){ h<-h+50 j<--50 k<-k+50 text(k,-30,h) for (z in 1:6){ j<-j+50 color<-rgb(h, j, i, alpha=255, maxColorValue=255) points(k,j, col=color,cex=3,pch=16) text(0,h,h) }}}} funcion()
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
36
¾ #Se exporta a un archivo pdf ¾ pdf("Paleta rgb.pdf",paper="a4r",w=15,h=6) ¾ funcion() ¾ dev.off() Paleta rgb Azul (0)
Azul (50)
Azul (100)
Azul (150)
Azul (200)
Azul (250)
50 100 150 200 250 0
50 100 150 200 250 0
50 100 150 200 250 0
50 100 150 200 250
250
Verde
200 150 100 50 0 0
50 100 150 200 250 0
50 100 150 200 250 0
Rojo
Dispositivos para gráficos windows(width=7, height=7, pointsize = 1/72 inch, rescale = "R", xpinch = NA_real_, ypinch = NA_real_, bg = "transparent", canvas = "white", gamma = 1, xpos = -25, ypos = 0, buffered = TRUE, title = "", clickToConfirm = TRUE, fillOddEven = TRUE ) win.print(width = 7, height = 7, pointsize = 12, printer = "") bmp(filename = "Rplot%03d.bmp", width = 480, height = 480, units = "px", pointsize = 12, bg = "white", res = NA) jpeg(filename = "Rplot%03d.jpg", width = 480, height = 480, units = "px", pointsize = 12, quality = 75, bg = "white", res = NA) png(filename = "Rplot%03d.png", width = 480, height = 480, units = "px", pointsize = 12, bg = "white", res = NA) tiff(filename = "Rplot%03d.tif", width = 480, height = 480, units = "px", pointsize = 12, compression = "none", res = NA) bitmap(file, type = "png16m", height = 7, width = 7, res = 72, units = "in", pointsize) pdf(file = ifelse(onefile, "Rplots.pdf", "Rplot%03d.pdf"), width = 7, height = 7, onefile, family = "Helvetica", title, version = "1.4", paper = "special", encoding, bg = "transparent", fg = "black", pointsize, pagecentre = TRUE, colormodel = "rgb", fillOddEven)
PROGRAMACIÓN DE GRÁFICOS CON R
37
Dispositivos para gráficos (Continuación) bg: color de fondo. buffered: si es TRUE se evitan posibles parpadeos a la hora de mostrar el gráfico. canvas: color del dispositivo cuando el fondo es transparente. clickToConfirm: si es TRUE cuando se crea un nuevo gráfico la confirmación se hace con un click en la pantalla con el ratón, en vez de respondiendo a una pregunta en la consola. colormodel: tipo de paleta de colores: "rgb", "gray" o "cmyk". compression: tipo de archivo comprimido que puede ser "none", "rle", "lzw", "jpeg" o "zip". family: tipo de fuente de letra. fg: color que se pone al frente. filename: nombre del archivo. fillOddEven: si es TRUE la manera en que se resuelve la intersección de formas se hace de forma automática por R. onefile: si es TRUE permite varias figuras en un solo archivo. pagecentre: si es TRUE todo lo que se imprime en el pdf se centra. paper: tamaño del papel: "a4", "letter", "legal", "executive", "a4r", "USr" o "special", en este último el tamaño viene definido por width y height. pointsize: tamaño del texto. printer: nombre de la impresora como la reconoce el sistema operativo del ordenador. quality: calidad del archivo jpeg en porcentaje. res: resolución en ppi para texto y ancho de líneas. rescale: define como re-escala el gráfico cuando se agranda la pantalla y las opciones son "R", "fit" o "fixed". title: título de la salida. type: tipo de bitmap. units: unidades del width y height en píxeles "px", centímetros "cm" o pulgadas "in". version: versión de pdf necesaria para poder ver el archivo. width y height: ancho y alto en pulgadas. xpinch e ypinch: píxeles por pulgada. El valor por defecto NA_real_ significa que tome los valores por defecto de Windows. xpos e ypos: posición en píxeles del cuadrante superior izquierdo de la ventana.
CAPÍTULO II GRÁFICOS BÁSICOS
II.1. Gráficos de dispersión Se utilizan muy frecuentemente, y representan dos variables cuantitativas en un sistema de coordenadas rectangulares. Para el ejemplo se usará el conjunto de datos iris, y se representarán dos variables con relación lineal entre ellas: «Petal.Length» y «Petal.Width». Para el gráfico de dispersión más simple, utilizamos la función «plot()» sin modificar ninguno de sus argumentos por defecto. La función «par(ps=15)» permite definir el tamaño de la letra. Las instrucciones están en el archivo II.1.R.
1.5 1.0
Petal.Width
2.0
2.5
data(iris) attach(iris) par(ps=15) plot(Petal.Length,Petal.Width)
0.5
¾ ¾ ¾ ¾
1
2
3
4 Petal.Length
39
5
6
7
40
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R Función plot (paquete graphics) x e y: coordenadas de los puntos. type: "p": puntos. "l": líneas. "b": puntos y líneas sin superposición. "c": deja las líneas y pone un hueco donde van los puntos. "o": puntos y líneas superpuestos. "s": en escalera, con movimiento horizontal y luego vertical. "S": en escalera, con movimiento vertical y luego horizontal. "h": líneas de alta densidad, tipo histograma. "n": sin representación.
Se pueden usar todos los argumentos generales. Ahora podemos ir añadiendo y modificando elementos en el gráfico. Como muchas veces existen varios datos en el mismo punto, con la función «sunflowerplot()» es posible que pinte tantas rayas como número de datos coinciden en el mismo punto. Los argumentos que iremos cambiando sirven tanto para la función «sunflowerplot()» como para la función «plot()». Con el argumento «pch» es posible cambiar el tipo de símbolo:
¾
sunflowerplot(Petal.Length,Petal.Width, pch=19)
Ahora cambiamos el rótulo de los ejes, de forma que el nombre de las variables tenga un mejor formato y se indiquen las unidades. Esto podríamos hacerlo con los argumentos «xlab» e «ylab»: ¾
sunflowerplot(Petal.Length, Petal.Width,pch=19, xlab="Longitud (cm)", ylab="Anchura (cm)")
Ahora le podemos añadir un título, para lo cual existen dos opciones: o bien el argumento «main», dentro de las funciones «plot()» o «sunflowerplot()», o bien otra función llamada «title()». En este caso optaremos por la primera opción.
¾ sunflowerplot(Petal.Length,Petal.Width,pch=19, xlab="Longitud (cm)", ylab="Anchura (cm)", main=" Longitud de pétalo vs Anchura de pétalo") Ahora haremos una serie de ajustes en el tipo de letra: convertiremos en negrita la letra de la escala en los ejes (con «font.axis»), la etiqueta de los ejes (con «font.lab»), aumentaremos el tamaño de letra en el título (con «cex.main») y en la etiqueta de los ejes (con «cex.lab»). Además, cambiaremos el tipo de letra en todo el gráfico para que sea Times New Roman (con «family»). Los valores de cada uno de los argumentos anteriores serían los siguientes: para negrita, el valor es 2, para el tamaño de fuente se usa un número que es una proporción relativa al tamaño actual (1). Así pues, si lo cambiamos a 0,5, el tamaño se reduciría un 50%, si lo aumentamos a 1,5, se aumentaría un 50%. El valor de «family» para Times New Roman es serif. El argumento «asp»
GRÁFICOS BÁSICOS
41
define la proporción de escala o relación de aspecto de los ejes, es decir, una unidad en x tiene la misma longitud que asp unidades en y.
¾ sunflowerplot(Petal.Length,Petal.Width,pch=19, xlab="Longitud (cm)", ylab="Anchura (cm)", main=" Longitud de pétalo vs Anchura de pétalo", font.axis=2, font.lab=2, cex.main=1.5, cex.lab =1.25, family="serif", asp=1.5, ylim=c(0.5,2.5)) A continuación añadiremos a este gráfico una recta de regresión con la función «abline()». En esta función es necesario especificar los valores de los parámetros de la recta. Para conocer esos valores haremos un modelo lineal con la función «lm()», y utilizaremos el resultado como parámetro de «abline()»:
¾ reg<-lm(iris$Petal.Width~iris$Petal.Length) ¾ abline(reg) Así daríamos por terminada esta gráfica, cuyo aspecto final sería el siguiente:
2.0 1.5 1.0 0.5 0.0
Anchura (cm)
2.5
3.0
Longitud de pétalo vs Anchura de pétalo
1
2
3
4
Longitud (cm)
5
6
7
42
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Función sunflowerplot (paquete graphics) x e y: coordenadas de los puntos. number: vector opcional que indica cuantas veces se repite cada uno de los puntos. digits: número de decimales que se tienen en cuenta. Cuando se omite number (en cuyo caso lo calcula R a partir de los datos), el redondeo de decimales se hace antes: digits = 6. rotate: si es TRUE las líneas (pétalos), que indican el número de datos, se rotan al azar para evitar solapamientos: rotate = FALSE. cex.fact: tamaño del punto central donde hay flores con pétalos (valores más cercanos a cero el punto es mayor): cex.fact = 1.5. size: tamaño de los pétalos en pulgadas: size = 1/8. seg.col: color de los pétalos: seg.col = 2. seg.lwd: grosor de los pétalos: seg.lwd = 1.5. Se pueden usar todos los argumentos generales. Vamos ahora con un ejemplo en el que complicaremos un poco más las cosas. Se trata de una gráfica de dispersión similar a la anterior, en la que queremos resaltar diferentes grupos de datos. Las instrucciones están en el archivo II.2.R. Utilizaremos nuevamente el conjunto de datos iris, por lo que debemos cargarlo con «data()» y adjuntarlo con «attach()» para poder localizar a las variables por su nombre. Vamos a representar la variable longitud de pétalo frente a la variable longitud de sépalo, diferenciando los resultados para cada especie. El conjunto total de órdenes se muestran a continuación; iremos explicándolas una por una. La primera instrucción, «plot()», sirve para representar el diagrama de dispersión para la especie setosa. Además añadimos un rango de valores para los ejes, «xlim» e «ylim», indicamos que se usa un círculo relleno como símbolo «pch=19», de color azul con «col="blue"» y que la etiqueta de los ejes esté en blanco (eso es así porque está previsto etiquetar los ejes con otra función). Con la función «colors()» podemos obtener el listado de diferentes colores que existen. Con el argumento «bty="l"» se indica que no dibuje los bordes superior y derecho del marco. En las siguientes dos órdenes, con «points()» añadimos los valores correspondientes a las otras dos especies, con el mismo símbolo en un color diferente, verde y rojo (para los colores podríamos usar un código en números además del código en letra). El argumento «bg» permite especificar el color de relleno de algunos símbolos (solamente «pch» de 21 a 25). En la siguiente instrucción utilizamos la función «title()» para añadir el título del gráfico y las etiquetas de los ejes, especificando que ambos tipos de letra deben estar en cursiva y el tamaño del título aumentado en un 50%. Por último, añadimos un recuadro con la leyenda con la función «legend()», que situaremos sobre el gráfico con la función «locator()». Esta función permite obtener las coordenadas de cualquier punto que se señale sobre el plano de la gráfica con el ratón y situar el ángulo superior izquierdo de la leyenda sobre él. En lugar de la función «locator()» también podríamos escribir las coordenadas directamente. El siguiente argumento indica los nombres que debe llevar la leyenda y después los símbolos y colores respectivos. Al ejecutar esta última or-
GRÁFICOS BÁSICOS
43
den, la leyenda no aparece hasta que hagamos click en el lugar en que deseemos situarla (debido al argumento «locator()»).
¾ data(iris) ¾ attach(iris) ¾ plot(iris[Species=="setosa", "Petal.Length"], iris[Species=="setosa", "Sepal.Length"], xlim=c(0,9), ylim=c(3,9), pch=19, col="blue", xlab="", ylab="", bty="l") ¾ points(iris[Species=="virginica", "Petal.Length"], iris[Species=="virginica", "Sepal.Length"],pch=19,col="green") ¾ points(iris[Species=="versicolor","Petal.Length"],iris[Species=="versicolor" ,"Sepal.Length"],pch=21,bg="red") ¾ points(iris[Species=="versicolor","Petal.Length"],iris[Species=="versicolor" ,"Sepal.Length"],pch=21,bg="red") ¾ title(main="Longitud de Pétalo vs Longitud de sépalo", xlab="Longitud de pétalo (cm)", ylab="Longitud de sépalo (cm)", font.main=2, font.lab=2, cex.main=1.5) ¾ legend(locator(1), c("setosa","virginica","versicolor"), pch=c(19,19,19), col=c("blue","green","red"))
9
Longitud de Pétalo vs Longitud de sépalo
7 6 5 4 3
Longitud de sépalo (cm)
8
setosa virginica versicolor
0
2
4
6
Longitud de pétalo (cm)
8
44
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
En el siguiente ejemplo de gráfico de dispersión identificaremos cada uno de los puntos. Las instrucciones están en el archivo II.3.R. Los datos consisten en las coordenadas obtenidas a partir de un método de ordenación espacial realizado con ciertas características de las comunidades fitoplanctónicas de una serie de lagos sudamericanos. Para ello representamos una gráfica de dispersión simple con las coordenadas x e y. Posteriormente, por medio de la función «text()» etiquetamos cada uno de los puntos del gráfico anterior con el nombre de cada lago, que se encuentra en la variable «Lago» en el archivo de datos. El argumento «pos» indica la posición de la etiqueta respecto al punto (el valor 4 significa a la derecha), el argumento «offset» indica cuanto se aleja respecto al punto, y el argumento «cex» indica el tamaño de las etiquetas. Con «srt» es posible dar el ángulo que se quiera al texto. Por último, se resaltan los lagos del Amazonas y, para ello, se utiliza la función «polygon()», que nos permite dibujar un polígono y colorearlo o rellenarlo con diferentes tramas. A esta función es necesario indicarle las coordenadas de cada vértice.
¾ datos<-read.csv2("Ordenación Lagos.csv", header=TRUE, encoding= "latin1") ¾ attach(datos) ¾ plot(X,Y,xlim=c(-1.2,1.2), ylim=c(-0.6,1), main="Lagos Sudamericanos", font.main=2,font.lab=2,font.axis=2,pch=19) ¾ text(X,Y,labels=Lago,pos=4,offset=0.4,cex=1, srt= 0) ¾ polygon(x = c(-1,-0.33,0.25,-1), y = c(-0.55,0,-0.55,-0.55), col = "#0000ff22", border = NA)
GRÁFICOS BÁSICOS
45
En los gráficos de dispersión es posible incluir una recta de regresión y representar intervalos de confianza para el valor estimado, o rango de valores dentro del cual debe estar la predicción de la variable dependiente con una probabilidad determinada. Además en este ejemplo veremos la forma de insertar imágenes en los gráficos; para archivos jpg se puede usar la función «read.jpeg()», en la cual simplemente hay que especificar el nombre del archivo a importar. Si se tienen archivos tiff se podría usar la función «readTiff()» del paquete “rtiff” (Kort, 2012). Para más detalles de los tipos de dispositivos donde se pueden exportar los archivos véase el Capitulo I. También veremos cómo guardar los gráficos en un archivo pdf usando la función «pdf()». Las instrucciones están en el archivo II.4.R. Es necesario tener instalado el paquete “ReadImages” (Loecher, 2011). En el ejemplo se usan datos, los cuales están en el archivo Carangidae.csv, de la longitud estándar y base de la aleta dorsal de varias especies de peces de la familia Carangidae. Después de importar los datos, se calcula la regresión con la función «lm()» y el ANOVA con «summary()». La función «predict()» permite calcular el intervalo de confianza de la regresión, en este caso al 99%. Con la función «pdf()» abrimos un archivo pdf donde se guardará el gráfico. El argumento «onefile= TRUE» permite que se puedan poner varios gráficos dentro del mismo archivo de pdf. La función «par(new=T)» permite añadir un gráfico al que ya está creado. La función «matplot()» permite representar los intervalos de confianza de forma fácil, ya que representa las columnas de una matriz con las columnas de otra matriz. No hay cuadro explicativo porque los argumentos son iguales a los de la función «plot()». En este caso se representa «Longitud» que solo tiene una columna, frente a «Conf» que tiene tres columnas: los límites (inferior y superior) del intervalo y los valores que predice la regresión. La instrucción «dev.off()» cierra el archivo pdf. Para poder ver el gráfico hay que abrir el archivo pdf que se ha creado, ya que no sale en pantalla. El script puede tardar unos segundos, dependiendo de la calidad y tamaño de la imagen a importar.
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
library(ReadImages) Datos<-read.csv2("Carangidae.csv", header=TRUE, encoding="latin1") attach(Datos) regre<-lm(Dorsal~Longitud) modelo<-summary(regre) modelo Conf<- predict(regre,interval="confidence",level=0.99) pdf("Carangidae.pdf", height = 7, width = 7, pointsize = 10, paper = "a4", onefile = TRUE) foto<-read.jpeg("Carangidae.jpg") plot(foto) par(new=T) plot(Longitud,Dorsal,xlim=c(0,700), ylim=c(0,400), xlab= "Longitud estándar (mm)", cex.lab=1.6, font.lab=2, ylab="Base aleta dorsal (mm)", main="Especies de la familia Carangidae",cex.main=2.0, font.main=2) par(new=T) matplot(Longitud, Conf, type="l", lty=c(1,2,2), xlim=c(0,700), ylim= c(0,400), col=c(1,2,2),xlab="",ylab="") dev.off()
46
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
II.2. Gráficos con barras de desviaciones Una representación muy común es la de medias y sus errores o desviaciones estándar y, para ello, se puede usar la función «plotCI()». Las instrucciones están en el archivo II.5.R. Es necesario tener instalado el paquete “gregmisc” (Warnes, 2012a). En este ejemplo hay datos del área de distribución geográfica de diferentes especies de tiburones, que están en el archivo Tiburones.csv, los cuales son la media y la desviación típica para cada familia de tiburones. Con la función «windows()» se amplía la ventana de presentación del gráfico. En la función «plotCI()» es necesario indicar los valores del eje x (solo admite valores numéricos), el valor de la media (eje y) y la columna donde están las desviaciones con «uiw». La instrucción «xaxt="n"» indica que no se representen los intervalos del eje x. Con «gap=0» se indica que las barras de las desviaciones estén pegadas al valor medio y no se deje ningún hueco. Para representar también un intervalo para el eje x, se añade otra función «plotCI()», con los argumentos «add=T» para que represente el nuevo gráfico sobre el anterior y con «err="x"». Para poner los nombres de las familias en el eje x se utiliza la función «text()», explicada anteriormente. Debido a que la leyenda del eje y tiene caracteres especiales, usamos la instrucción «mtext()». En esta función, indicamos en primer lugar el texto que deseamos escribir, el margen en el que deseamos escribir el texto y la línea (contando desde el recuadro del gráfico) en la que se desea añadir el texto.
GRÁFICOS BÁSICOS
47
¾ ¾ ¾ ¾
Alopiidae
1.5e+08
2
2.0e+08
Area geográfica de tiburones
Pseudocarchariidae Lamnidae Cetorhinidae
1.0e+08 5.0e+07 0.0e+00
Area media por especie (km )
2.5e+08
library(gregmisc) windows(12,8) datos<-read.csv2("Tiburones.csv",header=TRUE,encoding= "latin1") plotCI(datos$Tipo, datos$Media, uiw = datos$STD, xlim=c(0,7), ylim= c(0,250000000), pch=15, col="black", ylab="",xlab="Familia", font.axis=1, font.lab=1,cex.axis=1.3,cex.lab=2.5,main="Area geográfica de tiburones", font.main=2, cex.main=2.5, cex=1.5,xaxt="n", gap=0) ¾ text(datos$Tipo, datos$Media, labels=datos$Familia, pos=2, offset=0.5, cex=1.6) ¾ mtext(expression(paste("Area media por especie (km"^2,")")), 2, line=2.2, font = 1, cex=1.8)
Odontaspididae Carcharhinidae Squalidae
Familia Función plotCI (paquete gplots) x, y, z: variables a representar uiw: valor superior o derecho de la barra. NULL para no pintarlas. liw: valor inferior o izquierdo de la barra. NULL para no pintarlas: liw = uiw. ui: límite superior de las barras. Por defecto y + uiw (verticales) o x + uiw (horizontales). li: valor inferior de las barras. Por defecto y - liw (verticales) o x - liw (horizontales).
48
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Función plotCI (Continuación) err: indica la dirección de las barras; "y" verticales y "x" para barras horizontales: err="y". barcol: color de las barras. pt.bg: utilizar pch=21 con pt.bg=par("bg") para puntos superpuestos a las barras de error. sfrac: grosor de la línea del extremo de las barras de error, como una fracción de la longitud del eje x: sfrac = 0.01. gap: espacio entre el punto central y el comienzo de la barra: gap=1. minbar y maxbar: valores mínimo y máximo permitidos para los topes de las barras de error. Se pueden usar los argumentos generales xlab, ylab, add, lty y lwd.
II.3. Modelos y gráficos en paneles Ahora veremos un ejemplo en el que representaremos un modelo de supervivencia. Las instrucciones están en el archivo II.6.R y los datos en el archivo DaphniaSurv.csv. Para esto también nos sirve la función «plot()», gracias a que con ella es posible representar ciertos objetos como modelos. Los datos consisten en la supervivencia de individuos de cladócero de la especie Daphnia sp., los cuales han sido sometidos a diferentes tratamientos en los que cambia el tipo de alimento, la concentración, y si reciben o no un tipo de suplemento alimenticio. Haremos dos modelos; en el primero de ellos (modelo1) ajustamos la supervivencia al tipo de alimento que reciben «FeedMode» y en el otro (modelo2) tendremos en cuenta si reciben o no el suplemento y las diferencias de concentración. Queremos que los modelos sean representados por líneas y en el mismo panel queremos un gráfico para el modelo1 y otro para el modelo 2. En primer lugar se carga el paquete “survival” (Therneau, 2012), que contiene las funciones necesarias para trabajar con modelos de supervivencia. El argumento «mgp» permite especificar la posición de la leyenda, del texto de las divisiones y de los ejes con respecto al cuadro principal del gráfico. Solamente se modifica la posición de las leyendas, ya que el valor por defecto es c(3,1,0) y se ha puesto c(2,1,0). Después ajustamos los modelos con la función «survfit()», que usa «Surv()» para definir el modelo. El argumento «mfrow» sirve para indicar que queremos un panel con varias gráficas. En nuestro caso queremos una fila y dos columnas, así que en el panel se dibujarán dos gráficas. El argumento «mfcol» hace lo mismo pero rellenando primero las columnas. En este caso, queremos que se represente el gráfico con líneas, por lo que utilizaremos el argumento «lty», en el que se indica qué tipo de línea representará cada grupo de datos. Los tipos de línea están codificados con números. En nuestro caso indicamos que se representen las líneas tipo 1 a 4. Los argumentos «tck» y «tcl» permiten definir la longitud de las marcas de los ejes. El primero en proporción (un valor 1 pondría líneas interiores) y el segundo son medidas reales. Al segundo gráfico se le añade una cuadrícula con «grid()», donde se define el número de celdas x e y. Para añadir la leyenda, debemos saber el orden de los tratamientos, para indicar a cuál le corresponde cada tipo de línea. En este caso,
GRÁFICOS BÁSICOS
49
para situar ambas leyendas exactamente en el mismo punto del área del gráfico, utilizamos coordenadas en lugar de la función «locator()».
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
library(survival) datos<-read.csv2("DaphniaSurv.csv",header=TRUE,encoding="latin1") attach(datos) par(mgp=c(2,1,0)) modelo1<-survfit(Surv(Time,Status)~FeedMode) modelo2<-survfit(Surv(Time,Status)~Trat+Conc) par(mfrow=c(1,2)) plot(modelo1,lty=1:4,main="Tipo de alimentación",xlab="Tiempo (h)", ylab= "Supervivencia",font.main=2,font.lab=2,cex.main=1.25, tck = -0.03) legend(205,0.7,c("H","HM","O","OM"),lty=1:4) plot(modelo2,lty=1:4,main="Tratamiento",xlab="Tiempo (h)",ylab="Supervivencia",font.main=2,font.lab=2,cex.main=1.25, tcl= 0) grid(10,10,col="grey") legend(205,0.7,c("NoH","NoL","SiH","SiL"),lty=1:4)
0.8
1.0
Tratamiento
NoH NoL SiH SiL
0.2 0.0
0.0
0.2
Supervivencia 0.4 0.6
H HM O OM
Supervivencia 0.4 0.6
0.8
1.0
Tipo de alimentación
0 50
150 250 Tiempo (h)
350
0 50
150 250 Tiempo (h)
350
II.4. Diagrama de cajas El diagrama de cajas se utiliza para variables cuantitativas. Se representa la mediana (línea gruesa dentro de la caja) y otros parámetros relacionados con su dispersión.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
50
La caja abarca el rango en el que se encuentran el 1er y 3er cuartil. Las líneas punteadas indican el máximo y el mínimo si no hay outliers, o 1,5 veces la longitud de la caja si los hay. Los outliers (valores atípicos o extremos) se representan como puntos aislados más allá de los límites de la línea punteada. Representaremos con un diagrama de cajas la tasa de crecimiento de rotíferos a los que se somete a diferentes tratamientos, algunos de ellos con alimento tóxico. Las instrucciones están en el archivo II.7.R.
¾ ¾ ¾ ¾
datos<-read.csv2("Rotíferos.csv",header=TRUE,encoding="latin1") attach(datos) boxplot(r~Treatment) title("Tasa de crecimiento de los rotíferos",xlab="Tratamiento", ylab="r", font.main=2, font.lab = 2, cex.main=1.25)
-4
-3
-2
r
-1
0
1
Tasa de crecimiento de los rotíferos
High Tox A
Low Tox A
No Tox A
No Tox B
Tratamiento
Una versión de este tipo de gráfico consiste en añadir un elemento, llamado «notch» (muesca) que representa intervalos de confianza aproximados al 95% para la mediana: dos medianas son distintas (los grupos son distintos) si los intervalos o muescas de las cajas correspondientes no se solapan.
¾ boxplot(r~Treatment,notch=TRUE) ¾ title(xlab="Tratamiento", ylab="r",font.lab=2)
GRÁFICOS BÁSICOS
-2 -5
-4
-3
r
-1
0
1
51
High Tox A
Low Tox A
No Tox A
No Tox B
Tratamiento
Función boxplot (paquete graphics) x o formula: vector o variable con los datos (x) o expresión (formula) con las variables a representar del tipo y ~ grp, donde grp es un factor o variable de agrupación. range: indica cuanto se extienden las barras, desde el borde de la caja, en número de veces la longitud de la caja: range=1.5. width: vector del tipo c(x1, x2,..) con el ancho de las cajas: width = NULL. varwidth: si su valor es TRUE el ancho de la caja es proporcional a la raíz cuadrada del número de datos: varwidth = FALSE. notch: si es TRUE se ponen muescas en las barras. Si las muescas de dos cajas no se solapan, los grupos (sus medianas) son diferentes: notch = FALSE. outline: si es FALSE no se representan los outliers: outline = TRUE. names: variable o vector con las etiquetas de las cajas. plot: si es FALSE no se pinta el gráfico y se muestran los resultados: plot=TRUE. border: color de los bordes de las cajas. NA es sin borde: border = par("fg"). col: color de las cajas: col = NULL. pars: listado de otros posibles parámetros gráficos: pars = list (boxwex = 0.8, staplewex = 0.5, outwex = 0.5). horizontal: cajas horizontales si es TRUE: horizontal = FALSE. add: si es TRUE añade otro boxplot al existente: add = FALSE. at: valor numérico que indica donde se añade el nuevo boxplot: at = NULL.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
52
II.5. Beanplots Una alternativa a los diagramas de cajas son los beanplots, los cuales se representan con la función «beanplot()». Al igual que los diagrama de cajas, se utilizan para comparar una variable cuantitativa entre diferentes grupos. Sin embargo, tienen la ventaja de que, además de mostrar el rango de variación de la variable, también muestran la distribución de la variable, lo que permite comprobar si es Normal o no. Como ejemplo usaremos el Índice de Masa Corporal de niñas y niños de Italia y España que están en el archivo IMC.csv. Las instrucciones están en el archivo II.8.R. Para que el script funcione es necesario tener instalado el paquete “beanplot” (Kampstra, 2008; Kampstra, 2012). En el script hay tres gráficos. En el primer gráfico, al no especificar nada, los grupos se ordenan alfabéticamente en función de la etiqueta asignada a cada grupo.
library(beanplot) datos<-read.csv2("IMC.csv",header=TRUE,encoding="latin1") attach(datos) beanplot(IMC ~ Sexo, ll = 0.04, what=c(1,1,1,1), ylim = c(17,24), xlim = c(0,5), ylab = "Índice de masa corporal", cex.lab=1.6, log="")
22 21 20 19 18 17
Índice de masa corporal
23
24
¾ ¾ ¾ ¾
Niña-España
Niña-Italia
Niño-España
Niño-Italia
GRÁFICOS BÁSICOS
53
Si se quiere otro tipo de orden es necesario etiquetar los grupos con números, en este caso la columna «Sexo1» en el archivo. Se define el carácter «levels» con el orden en que están los grupos en la nueva columna y simplemente se utiliza «Sexo1» en vez de «Sexo» para identificar la variable de agrupación. Es necesario incorporar la instrucción «names», la cual informa de las nuevas etiquetas de los grupos. En lo que se refiere al resto de argumentos, la instrucción «ll» indica la longitud de la línea dibujada en color blanco por cada punto existente. El argumento «what» es un vector lógico (0 no y 1 si) que indica si se muestran los siguientes cuatro elementos: la línea discontinua con el valor medio de todos los grupos, las “judías” o distribuciones, la línea que indica la media de cada grupo y las líneas para cada punto cuyo tamaño se definía con «ll». El argumento «method» define qué hacer cuando hay dos datos iguales: la opción por defecto «stack» los apila, «overplot» los pone unos encima de otros y con «jitter» es posible definir un pequeño desplazamiento o “ruido”. Con el argumento «log=""» se especifica que no aplique los logaritmos de forma automática y eso permite poner cero en los límites inferiores de los ejes x e y.
22 21 20 19 18 17
Índice de masa corporal
23
24
¾ levels<-c("Niño-España", "Niña-España", "Niño-Italia", "Niña-Italia") ¾ beanplot(IMC ~ Sexo1, ll = 0.04, what=c(1,1,1,1), ylim = c(17,24), xlim = c(0,5) , ylab = "Índice de masa corporal", cex.lab=1.6, names=levels, method = "overplot", log="")
Niño-España Niña-España
Niño-Italia
Niña-Italia
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
54
En el tercer gráfico se observa que se puede representar en parejas, para una mejor comparación. El argumento «lend» define como es el acabado de las líneas; al ponerle el valor 1, que significa el extremo grueso, se ve más uniforme la zona de unión entre los grupos. Con «side="both"» se especifica que se representen ambos grupos juntos; la opción por defecto es «no» y otras opciones son «first» o «second». Con «border» se indica el color del borde (en este ejemplo se especifica que no se pinte). Con el argumento «innerborder», que no se utiliza en el ejemplo, se podría poner una línea de separación entre los grupos de un color determinado. Con «boxwex» se define un factor de escala para el tamaño de las “judías”. Al ponerle el valor 1, deja el tamaño por defecto. Con la instrucción «overallline» se define si se representa una línea con la media «"mean"» o la mediana «"median"» general de todos los grupos. Con «show.names=F» se indica que no se ponga la leyenda de los grupos en el eje. Por último, en la leyenda con «ncol=4» se especifica que se pongan las etiquetas de los grupos en cuatro columnas en vez de cuatro filas.
22 21 20 19 18
Índice de masa corporal
23
24
¾ par(lend=1) ¾ beanplot(IMC ~ Sexo, ll = 0, ylim=c(18, 24), ylab = "Índice de masa corporal", side = "both", border = NA, boxwex=1, overallline="median", col = list("black","grey", "red", c("blue", "white")), show.names=F, cex.lab=1.6) ¾ legend("topleft", fill = c("black", "grey", "red", "blue"), legend = c ("NiñaEspaña", "Niña-Italia", "Niño-España", "Niño-Italia"), bty="n", ncol=4) Niña-España
Niña-Italia
Niño-España
Niño-Italia
GRÁFICOS BÁSICOS
55
Función beanplot (paquete beanplot) …...: fórmula con las variables a representar del tipo y ~ x, vector o data frame. bw: método para calcular la longitud de las bandas: bw = "SJ-dpi". kernel: especificación del núcleo para la función de suavizado ("epanechnikov", "gaussian", "rectangular", "triangular", "biweight", "cosine", "optcosine"): kernel = "gaussian". cut: define cuanto se alargan los extremos: cut = 3. cutmin: define cuanto se alarga el extremo inferior: cutmin = -Inf. cutmax: define cuanto se alarga el extremo superior: cutmax = Inf. grownage: el ancho de la “judía” crece con el número de puntos hasta que se alcanza este valor: grownage = 10. what: vector del tipo 0 ó 1 que define lo que se representa en el siguiente orden: la media total, las curvas de densidad, la media de cada grupo y las líneas de los puntos: what = c(TRUE, TRUE, TRUE, TRUE). col: vector con hasta 4 colores en el siguiente orden: relleno del área interior, líneas interiores, líneas exteriores y la media de cada grupo. ll: longitud de las líneas por punto: ll = 0.16. maxwidth: ancho máximo de cada beanplot: maxwidth = 0.8. maxstripline: longitud máxima de cada beanplot: maxstripline = 0.96. method: define que hacer cuando hay dos datos iguales: "stack" los apila, "overplot" los pone unos encima de otros y con "jitter" es posible definir el ruido deseado cuando hay varios puntos en la misma posición: method="stack". names: vector con los nombres de los grupos. overallline: promedio general utilizado, "mean" (media) o "median" (mediana): overallline = "mean". beanlines: promedio a representar en cada grupo: "mean", "median" o "quantiles": beanlines = overallline. boxwex: factor de escala de los puntos: boxwex=1. horizontal: si es TRUE los grupos se pintan horizontales. horizontal = FALSE. side: lado en que se representan los grupos. Para grupos simétricos es “no”, y también se puede usar "first", "second" y "both": side = "no". jitter: valor numérico que introduce un ruido en caso de solapamiento, si method = "jitter": jitter = NULL. beanlinewd: el grosor de línea de la media de cada grupo: beanlinewd = 2. frame.plot: si es TRUE se pinta un marco: frame.plot=TRUE. border: color del borde externo de cada grupo: border = NULL. innerborder: color del borde interno de cada grupo: innerborder = NA. at: posición de cada grupo. Por ejemplo at = c(1:2, 1, 2) significa que los grupos 1 y 2 se queden en su posición, el grupo 3 en la posición 1 y el grupo 4 en la posición 2: at = NULL. show.names: si es TRUE se muestran las etiquetas en los ejes: show.names = NA. Se pueden usar los argumentos generales add, axes, log, xlim e ylim.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
56
Por último, en el gráfico 4 se muestra que es posible obtener una representación similar utilizando la función «bwplot()», para lo cual es necesario tener instalado el paquete “lattice” (Sarkar, 2008; 2012). Esta función gráfica además de dar información de la distribución de los datos, también muestra un diagrama de cajas. Las modificaciones que se quieran realizar de las etiquetas y formato de las divisiones de los ejes, se deben introducir con una lista en el argumento «scales». Del mismo modo, las modificaciones de las leyendas de los ejes, títulos o subtítulos, deben incluirse dentro del propio argumento por medio de una lista, como se muestra en este ejemplo para «ylab».
¾ library(lattice) ¾ bwplot(IMC ~ Sexo, ylim=c(18,24), scales=list(cex=1.2, font=2), ylab = list ("Indice de masa corporal", cex=2), panel = function(..., box.ratio) { panel.violin(..., col = "transparent", varwidth = FALSE, box.ratio = box.ratio) panel.bwplot(..., fill = NULL, box.ratio = 0.1) })
Indice de masa corporal
23
22
21
20
19
Niña-España
Niña-Italia
Niño-España
Niño-Italia
GRÁFICOS BÁSICOS
57
Función bwplot (paquete lattice) formula: variables a representar con el formato del tipo y ~ x. data: datos donde pueden existir otras variables que se pueden utilizar para definir grupos, hacer selecciones con subset, etc. allow.multiple: si por ejemplo en la fórmula y se pone como la suma de dos variables y1 + y2, si se coloca FALSE, lo que hace es sumar las celdas, y si se coloca TRUE las dos variables las considera como diferentes, es decir, no suma los datos y considera los datos independientes de las dos variables. outer: si allow.multiple = TRUE y por ejemplo en la fórmula y se puso como y1 + y2, entonces al poner TRUE se hacen dos gráficos, uno con y1 y otro con y2 como variable independiente: outer=FALSE. auto.key: si es TRUE se genera una leyenda automáticamente. Si se quiere hacer la leyenda manualmente, se usa por ejemplo auto.key = list(colum=2), donde se pondrían dos columnas. Para ver las posibilidades de una leyenda manual véase en el menú ayuda de R la función simpleKey: auto.key=FALSE. aspect: define el tamaño del gráfico y su aspecto. Puede ser un número o un carácter: con "fill" intenta hacer el panel lo más grande posible, "xy" intenta conseguir un aspecto basado en los 45 grados de la pendiente de los ejes (véase la función banking en el menú de ayuda de R), e "iso" intenta que las diferencias de los datos se manifiesten también en diferencias en los ejes, teniendo así los dos ejes la misma escala: aspect = "fill". panel: dentro de este argumento se pueden especificar diferentes funciones que se van a realizar como por ejemplo panel.xyplot, panel.barchart, panel.violin, panel.bwplot, etc. prepanel: tiene la misma función que panel, es decir, agrupar argumentos y funciones a realizar, pero previas al uso de panel. Por ejemplo, útil para especificar xlim, ylim, realizar gráficos previos de preparación del panel, etc.: prepanel = NULL. scales: una lista especificando como las marcas y etiquetas de los ejes se van a representar (véase el menú ayuda de bwplot si se quiere tener más detalles): scales = list(). strip: cuando se tienen varios paneles, si se pone TRUE se representan unas etiquetas identificadoras de cada panel: strip = TRUE. groups: variable que se puede utilizar para agrupar los datos: groups = NULL. box.ratio: define la proporción de tamaño de las curvas de densidad con respecto al rectángulo interior: box.ratio = 1. horizontal: determina cual es la variable que actúa como factor, si es FALSE x, y si es TRUE y: horizontal = NULL. drop.unused.levels: si es TRUE los niveles de los factores que no se utilizan son eliminados. Solamente es útil cuando se ha hecho una selección de datos y se desea que no se eliminen del gráfico los niveles no seleccionados. Se pueden usar los argumentos generales xlab, ylab, xlim e ylim.
58
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
II.6. Curvas de ajuste Otros gráficos de uso muy frecuente son aquellos en los que se representa una curva ajustada a un diagrama de dispersión de datos. La curva puede ajustarse por métodos paramétricos o no paramétricos. En nuestro caso veremos un ejemplo paramétrico en el que se representa la tasa de crecimiento. Se trata de los resultados de tasa de crecimiento de una microalga (Chlorella vulgaris), con nitrato como recurso limitante. Queremos representar una curva del modelo de Michaelis-Menten. Para ello debemos crear por separado un objeto con la curva predicha por el modelo sobre unas coordenadas determinadas, que añadiremos a nuestro gráfico con la función «lines()». Aprovecharemos este ejemplo para mostrar cómo se pueden escribir caracteres especiales en la leyenda de los ejes y fórmulas matemáticas (o cualquier otro tipo de texto) en el panel. Las instrucciones están en el archivo II.9.R. Los datos están en el archivo Curva de crecimiento.csv. Después de cargar el archivo de datos y adjuntarlos, utilizamos la función «plot()», a la cual le añadimos el título del gráfico (esta vez en negrita y cursiva, código 4) y las etiquetas de los ejes. El argumento «lab=c(8,8,1)» define el número de divisiones de los ejes y el último número, aunque es necesario especificarlo, R no lo utiliza. Con «xlog=F» e «ylog=F» se especifica que los ejes no sean logarítmicos. En este caso, la complicación está en el eje x, que debe utilizar la letra griega μ para indicar las unidades micromolares. Esta letra existe con el nombre de mu en la fuente symbol (véase Capítulo I). Generalmente, todas las letras griegas se pueden utilizar de la misma manera (pi, sigma, phi, etc.). Después ajustamos un modelo de Michaelis-Menten mediante la función «nls()» y creamos dos vectores de coordenadas para representar esa función, «coordx» y «coordy». Ambos vectores deben tener la misma longitud, y en nuestro caso nos interesa que se extiendan en el mismo rango que nuestros datos. La función «lines()» dibujará las líneas de la ecuación predicha para el modelo por la función «predict()». Estas líneas no son continuas, sino segmentos entre cada par de coordenadas. Por eso al crear los vectores de coordenadas hemos definido un paso muy pequeño (0,01); así los segmentos no se notan y parece una línea continua. Con «rect()» pintamos un rectángulo para resaltar la ecuación de Michaelis–Menten, la cual se escribe con la función para texto «paste()» combinada con las funciones «substitute()» y «frac()» para expresiones matemáticas, además de una serie de símbolos («[]» indica subíndice). En la página de ayuda que aparece al teclear «help(symbol)» o «help (plotmath)», podemos ver una relación completa de los símbolos matemáticos disponibles para esta fuente. Además utilizamos el argumento «cex» para aumentar el tamaño de esta expresión. Con la función «segments()» se representa la línea azul que indica el máximo de crecimiento. Es importante resaltar que los diferentes tipos de fuente (negrita, cursiva, negrita cursiva) no se aplican a las expresiones matemáticas ni símbolos de este tipo.
¾ datos<-read.csv2("Curva crecimiento.csv", header=TRUE, encoding= "latin1") ¾ attach(datos) ¾ plot(N,r,main="C. vulgaris",xlab=expression(paste("Nitrato (",paste (mu, "M)"), sep=" ")), ylab="Tasa de crecimiento", font.main=4, cex.main=1.75,pch=19, lab=c(8,8,1), cex.lab = 1.5, xlog=F, ylog=F)
GRÁFICOS BÁSICOS
59
¾ ¾ ¾ ¾ ¾ ¾
modeloMM<-nls(r~rmax*N/(Ks+N),start=list(rmax=1.8,Ks=5)) coordx<-seq(0,160,0.01) coordy<-predict(modeloMM,list(N=coordx)) lines(coordx,coordy) rect(80,0.3,120,0.7, col="grey", density=20, angle=45) text(100,0.5,substitute("r"==paste(frac(paste("r"[max]*"S"), paste("K"[s]+"S")))),cex=1.5) ¾ segments(-8,1.55,163,1.55,lty=2,col="blue",lwd=2)
1.2 1.0 0.8 0.6
r
rmaxS Ks S
0.0
0.2
0.4
Tasa de crecimiento
1.4
1.6
1.8
C. vulgaris
0
20
40
60
80
100
120
140
160
Nitrato (PM)
II.7. Histogramas El histograma representa las frecuencias de una variable continua mediante áreas. Veremos un ejemplo de histograma sobre el que representaremos una curva de densidad de probabilidad. Jugando con los argumentos de la función para crear histogramas definiremos las clases de forma que cada barra represente –en lo posible– la frecuencia absoluta o relativa de solamente un valor. Además, introduciremos algunos nuevos parámetros gráficos. Las instrucciones están en el archivo II.10.R. Los datos de que disponemos son una serie de parámetros celulares correspondientes a una población de microalgas en el archivo Microalga.csv. Las unidades de medida se corresponden con una señal eléctrica de un determinado detector en un citómetro de flujo. Nos interesa representar un histograma sin agrupar los tamaños en clases, de modo que a cada valor individual de la variable le corresponda su densidad de probabilidad en el eje y.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
60
Con la función «hist()» representaremos el histograma. El argumento «breaks» define el número de barras del histograma y, por ello, el rango de valores de nuestra variable que abarca cada barra. Le indicamos que sea igual al número de valores de nuestra variable, por lo que cada barra abarcará un solo valor. El argumento «freq» es específico de esta función. Por defecto tiene valor «TRUE» y entonces se representarían las frecuencias absolutas de cada valor. Al darle valor «FALSE», se representan valores de densidad de probabilidad. Con «xaxp» se definen los límites de los intervalos del eje x y el número de ellos. Para el eje y se usa «yaxp». Además, utilizamos la función «lines()» para añadir una línea que estime la densidad de probabilidad, de un modo no paramétrico. El argumento «lwd» define el grosor de la línea.
¾ datos<-read.csv2("Microalga.csv",header=TRUE,encoding="latin1") ¾ attach(datos) ¾ hist(Tamaño,breaks=length(Tamaño),xlim=c(0,1000),ylim=c(0,0.02),main= "Tamaño del alga",xlab="Tamaño",ylab="Densidad" ,font.main=2, font.lab =2, cex.main=1.25, freq=FALSE, xaxp=c(0,1000,10)) ¾ lines(density(Tamaño,na.rm=TRUE),lwd=2,col="red")
0.010 0.000
0.005
Densidad
0.015
0.020
Tamaño del alga
0
100
200
300
400
500
600
700
800
900
1000
Tamaño
También es posible representar dos series de datos en la misma gráfica. En el siguiente ejemplo, cuyas instrucciones están en el archivo II.11.R, además de representar el tamaño se representa la rugosidad; ambas variables se miden en mV y tienen un rango similar. Una instrucción nueva es «border», con la cual asignamos dos tonalidades de gris diferentes para el tamaño («grey22») y la rugosidad («grey55»). Utilizando la función para modificar parámetros de gráficos «par()», indicamos por medio del argumento «new=TRUE», que representaremos un nuevo histograma en el mismo panel.
GRÁFICOS BÁSICOS
61
¾ datos<-read.csv2("Microalga.csv",header=TRUE,encoding="latin1") ¾ attach(datos) ¾ hist(Tamaño,breaks=length(Tamaño),xlim=c(0,1000),ylim=c(0,0.02),main= "Tamaño y Rugosidad", xlab="mV", ylab="Densidad", font.main=2, font.lab=2, cex.main=1.25,freq=FALSE,border="grey22") ¾ par(new=TRUE) ¾ hist(Rugosidad, breaks=length(Tamaño), xlim=c(0,1000), ylim=c(0,0.02), main="", xlab="", ylab="",freq=FALSE,border="grey55") ¾ lines(density(Tamaño,na.rm=TRUE),lwd=2,col="red") ¾ lines(density(Rugosidad,na.rm=TRUE),lwd=2,col="blue") ¾ legend(0,0.0175, c("Tamaño","Rugosidad"), lty=c(1,1), lwd=c(2,2), col= c("red","blue"))
0.020
Tamaño y Rugosidad
0.010 0.000
0.005
Densidad
0.015
Tamaño Rugosidad
0
200
400
600
800
1000
mV
En el siguiente ejemplo se muestra cómo combinar dos histogramas en un panel y seleccionar determinados casos. Las instrucciones están en el archivo II.12.R, en el cual se detalla cada uno de los pasos a modo de resumen de todo lo visto anteriormente. Los datos, que están en el archivo Morfología.csv, son medidas morfométricas de peces. Con la instrucción «par(mfrow)» se crea un panel con dos gráficas, posicionadas en dos filas y una columna. La siguiente instrucción selecciona solo el orden Perciformes. Posteriormente se hace el histograma para la variable M2. Con la instrucción «par(new=TRUE)» permitimos que el nuevo histograma con la variable M3 se haga en el mismo gráfico de antes. Luego se hacen las curvas de densidad para ambas variables y se coloca una leyenda. Posteriormente, se selecciona el orden Characiformes y se repite todo el proceso.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
62
60
Perciformes
0
20
40
M2 M3
0.00
0.05
0.10
0.15
0.20
0.25
0.20
0.25
300
Characiformes
200
¾ ¾
100
¾ ¾
0
¾ ¾ ¾ ¾ ¾
Nº de individuos
¾ ¾
datos<-read.csv2("Morfología.csv",header=TRUE,encoding="latin1") attach(datos) par(mfrow=c(2,1)) datos1 <- datos[Orden=="Perciformes", ] hist(datos1$M2,breaks=length(M2),xlim=c(0,0.25),ylim=c(0,60),main="Per ciformes",xlab="",ylab="Nº de individuos", font.main=2, font.lab=2, cex.main=1.25, freq=FALSE,border="grey22") par(new=TRUE) hist(datos1$M3,breaks=length(M3), xlim=c(0,0.25), ylim=c(0,60), main="", xlab="", ylab="", freq=FALSE, border="grey55") lines(density(datos1$M2,na.rm=TRUE),lwd=2,col="red") lines(density(datos1$M3,na.rm=TRUE),lwd=2,col="blue") legend(0.2,60,c("M2","M3"),lty=c(1,1),lwd=c(2,2),col=c("red","blue")) datos2 <- datos[Orden=="Characiformes", ] hist(datos2$M2, breaks=length(M2), xlim=c(0,0.25), ylim=c(0,300), main= "Characiformes", xlab="Ratio de las variables M2 y M3 frente a la longitud estándar", ylab="Nº de individuos", font.main=2, font.lab=2, cex.main=1.25, freq=FALSE,border="grey22") par(new=TRUE) hist(datos2$M3,breaks=length(M3),xlim=c(0,0.25),ylim=c(0,300),main="", xlab="",ylab="",freq=FALSE,border="grey55") lines(density(datos2$M2,na.rm=TRUE),lwd=2,col="red") lines(density(datos2$M3,na.rm=TRUE),lwd=2,col="blue")
Nº de individuos
¾ ¾ ¾ ¾ ¾
0.00
0.05
0.10
0.15
Ratio de las variables M2 y M3 frente a la longitud estándar
GRÁFICOS BÁSICOS
63
Función hist (paquete graphics) x: vector o variable con los valores a representar. breaks: un número, un vector, un carácter o una función que indica el número de barras: breaks = "Sturges". freq: si es TRUE se muestran las frecuencias y si es FALSE la densidad de probabilidad: freq = NULL. include.lowest: si es TRUE y breaks es un vector, se mostrará el valor del break en la primera barra: include.lowest = TRUE. right: si es TRUE los intervalos se cierran por la derecha: right = TRUE. density: densidad de las líneas de sombreado: density = NULL. angle: ángulo de las líneas de sombreado: angle = 45. col: color de relleno de las barras: col = NULL. border: color de los bordes. NA es sin borde: border = NULL. plot: si es FALSE no se representa el gráfico y muestra los datos: plot = TRUE. labels: si es TRUE se muestran los valores de las densidades encima de las barras. También se puede especificar un carácter o un vector con caracteres: labels = FALSE. Se pueden usar todos los argumentos generales. Otro tipo de histograma es el gráfico de frecuencia de puntos de la función «dotplot()» del paquete “epicalc” (Chongsuvivatwong, 2012). Las instrucciones están en el archivo II.13.R y como ejemplo de nuevo usaremos datos morfométricos de peces que están el archivo Morfología.csv. Con la función «dotplot()» es preferible guardar los datos con el nombre «.data» para que funcionen bien los argumentos que se dejan en modo automático. Con la función «rainbow()» se define una paleta de 4 colores, ya que los grupos a representar son 4 familias. Con el «bin» se puede definir el número de puntos a representar o dejarlo en modo automático. El argumento «by» es una variable que define los diferentes grupos, en este caso las diferentes familias de peces. Con «xmin» y «xmax» se pueden especificar los límites inferior y superior del eje x, los cuales también se pueden dejar en modo automático. El argumento «time.step» puede ser un carácter del tipo "year", "week", "sec", etc., y «time.format» otro carácter que define el formato de tiempo del tipo "%H:%M", "%Y", etc. Por último, con «cex.X.axis» y «cex.Y.axis» se define el tamaño de las marcas de los ejes.
¾ ¾ ¾ ¾ ¾
require(epicalc) .data<-read.csv2("Morfología.csv",header=TRUE,encoding="latin1") attach(.data) color<-rainbow(4) dotplot(M12, bin="auto", by=Familia, xmin = 0, xmax = 1, time.format = NULL, time.step = NULL, pch = 18, dot.col = color, main = "Distribución de la variable M12 por familias", ylab = "auto", cex.X.axis = 1, cex.Y.axis = 1)
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
64
Distribución de la variable M12 por familias
phyraenidae
Sparidae
Cichlidae
Characidae
0
0.2
0.4
0.6
0.8
1
II.8. Diagrama de tallo y hojas El diagrama de tallo y hojas (Stem-and-Leaf Diagram) permite obtener simultáneamente una distribución de frecuencias de la variable y su representación gráfica. El gráfico es similar a un histograma y, por lo tanto, es adecuado para representar variables continuas, ya que permite visualizar la distribución de la variable sin perder de vista los valores individuales de los datos. Se representa mediante caracteres –por lo que no necesita un dispositivo gráfico– y contiene en el mismo gráfico información sobre los valores de la variable. Tiene más información que el histograma, aunque la calidad del gráfico es inferior. Para construir el gráfico se ordenan los valores de menor a mayor, y para cada valor se separa el último dígito de la derecha, con el que se formarán las “hojas”, a la derecha de la línea vertical, y los restantes dígitos forman el “tallo”, a la izquierda de la línea vertical. Veamos un ejemplo con los datos del archivo Morfología.csv, utilizando la función «stem()» del paquete básico “graphics”. Las instrucciones están en el archivo II.14.R
GRÁFICOS BÁSICOS
65
En el ejemplo se representa la variable M12, habiendo seleccionado previamente el grupo de elementos correspondiente a la familia Sparidae.
¾ datos<-read.csv2("Morfología.csv",header=TRUE,encoding="latin1") ¾ datos1 <- subset(datos, Familia == "Sparidae") ¾ stem(datos1$M12) El resultado que se muestra aparece en la consola o ventana de resultados, y no en una ventana de gráficos:
The decimal point is 2 digit(s) to the left of the 42 | 6 43 | 44 | 45 | 7 46 | 589 47 | 11457889 48 | 345677888999 49 | 0011223344455566788888 50 | 000111222222333344444555556666666666677777888888999 51 | 00000111112222222233444555556666777788889999 52 | 000000001111122223333344444555555666666666777777788999 53 | 0001111122222333444444445555555666666677788999999 54 | 00011122333333444455556667788888899 55 | 011122222333334444555566778889999 56 | 00000111223333333444556777899 57 | 2224444666777889 58 | 0012668 59 | 457 60 | 61 | 62 | 7 Como se muestra en los resultados, los valores del tallo deben leerse con la coma desplazada dos lugares a la izquierda (62 es 0,62). El aspecto general del gráfico es similar al histograma, pero ahora es posible reconstruir los valores de la variable a partir del gráfico, ordenados de menor a mayor, tomando el tallo y cada una de las hojas: 0,627, 0,597, 0,595, 0,594, 0,588, 0,586, 0,586, 0,582, etc.
II.9. Gráficos de barras El gráfico de barras se utiliza para variables cuantitativas discretas y variables cualitativas. La función «barplot()» permite representar barras simples, barras agrupadas, o barras apiladas. Para realizar estos tipos de gráficos, partiremos del archivo que usamos en el ejemplo anterior Morfología.csv, es decir, medidas morfológicas de una serie de
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
66
peces clasificados en orden, familia, género y especie. El objetivo es representar los valores de distintas variables por familias. Las instrucciones están en el archivo II.15.R. En primer lugar, seleccionamos solamente la variable M2 para crear un gráfico de barras simples. La única función importante, que no hayamos visto hasta ahora en esta sección, es «tapply()», que usamos para obtener los valores promedio de M2 por familias.
¾ datos<-read.csv2("Morfología.csv",header=TRUE,encoding= "latin1") ¾ attach(datos) ¾ barplot(tapply(M2,Familia,mean),ylim=c(0,0.16),ylab="Longitud",font.lab= 2, font.axis=2, main="M2", font.main=2)
0.00
0.05
Longitud
0.10
0.15
M2
Characidae
Cichlidae
Sparidae
Sphyraenidae
En los gráficos de barras, nos podría interesar en muchos casos representar barras de error o desviación estándar en el eje y. Para realizar esto no existe ninguna función predefinida que actúe directamente sobre la función «barplot()». Existen funciones como «errbar()» en el paquete “Hmisc” (Harrell, 2012) o la función «plotCI()» en el paquete “gplots” (Warnes, 2012b) –esta última más comúnmente utilizada para representar intervalos de confianza– que pueden actuar sobre otras funciones gráficas. Por lo tanto, la mejor forma de hacerlo es crear una función definida por el usuario. Existen muchas formas de hacerlo. Podemos, por ejemplo, utilizar un código muy simple disponible libremente en http://monkeysuncle.stanford.edu. Modificaremos ligeramente este código, para que las desviaciones o errores se muestren sólo por encima de las barras y lo utilizaremos en el ejemplo de barras simples y agrupadas. En el caso de las barras simples es necesario añadir algunos
GRÁFICOS BÁSICOS
67
detalles al código mostrado anteriormente. Destacamos que es necesario crear un objeto, «ejeX», que nos muestre los valores del eje x sobre los que se encuentran las barras (paso 1), ya que estos valores los adjudica la función «barplot()» sin que nosotros los conozcamos. Creamos también en el paso 1 un objeto para los valores del eje y, «valores», además de un vector, «dvest», con las desviaciones estándar, en el paso 2.
¾ valores<-tapply(M2,Familia,mean) ¾ ejeX<-barplot(valores, ylim=c(0,0.16), ylab="Longitud", font.lab=2, font.axis=2, main="M2",font.main=2) ¾ dvest<-tapply(M2,Familia,sd) ¾ error.bar <- function(x, y, upper, lower, length=0.1,...) { if(length(x) != length(y) | length(y) !=length(lower) | length(lower) != length(upper)) stop("vectors must be same length") arrows(x,y+upper, x, y-lower, angle=90, code=3, length=length, ...) } ¾ error.bar(ejeX,valores,upper=dvest,lower=rep(0,length=length(dvest)))
0.00
0.05
Longitud
0.10
0.15
M2
Characidae
Cichlidae
Sparidae
Sphyraenidae
Ahora, representaremos los valores promedio de una serie de variables (M2, M3, M4 y M5) para cada familia, mediante un gráfico de barras agrupadas. Las instrucciones están en el archivo II.16.R. La función «aggregate()» permite obtener los valores medios de cada una de las variables (M2, M3, M4 y M5), y con el argumento «by» se crea una lista donde se pueden indicar las variables de
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
68
agrupación; en este ejemplo se utiliza únicamente familia. Dentro de la función «barplot()», debemos indicar que el argumento «beside» tenga valor «TRUE». De no ser así, se generaría un gráfico de barras apiladas, como veremos posteriormente.
¾ datos<-read.csv2("Morfología.csv",header=TRUE,encoding= "latin1") ¾ datos2<-datos[,c("Familia","M2","M3","M4","M5")] ¾ datos2M<-aggregate(datos2[,c("M2","M3","M4","M5")],by=list(datos2$ Familia),mean) ¾ datos2M<-datos2M[,-1] ¾ rownames(datos2M)<- c("Characidae", "Cichlidae", "Sparidae", "Sphyraenidae") ¾ datos2M<-as.matrix(datos2M) ¾ barplot(t(datos2M),beside=TRUE,ylim=c(0,0.15),main="Morfología",ylab= "Longitud",font.main=2,font.axis=2,font.lab=2,col=1:4) ¾ legend("topleft",colnames(datos2M), bty="n", fill=c("black","red","green", "blue"))
M2 M3 M4 M5
0.08 0.06 0.00
0.02
0.04
Longitud
0.10
0.12
0.14
Morfología
Characidae
Cichlidae
Sparidae
Sphyraenidae
Al igual que hicimos anteriormente, es posible incorporar barras de desviación en el gráfico.
#Paso 1. Se representa el gráfico ¾ datos<-read.csv2("Morfología.csv",header=TRUE) ¾ datos2<-datos[,c("Familia","M2","M3","M4","M5")] ¾ datos2M<-aggregate(datos2[ , c("M2", "M3", "M4", "M5")], by= list(datos2$Familia),mean)
GRÁFICOS BÁSICOS
69
¾ datos2M<-datos2M[,-1] ¾ rownames(datos2M)<-c("Characidae", "Cichlidae", "Sparidae", "Sphyraenidae") ¾ datos2M<-as.matrix(datos2M) ¾ ejeX<-barplot(t(datos2M), beside=TRUE, ylim=c(0,0.16), main= "Morfología", ylab="Longitud", font.main=2, font.axis=2, font.lab=2, col=1:4) ¾ legend("topleft",colnames(datos2M),bty="n",fill=c("black","red","green", "blue")) #Paso 2. Se añaden las desviaciones ¾ datos2Mdvest<-aggregate(datos2[ , c("M2", "M3", "M4", "M5")], by= list(datos2$Familia),sd) ¾ datos2Mdvest<-datos2Mdvest[,-1] ¾ datos2Mdvest<-as.matrix(datos2Mdvest) ¾ error.bar <- function(x, y, upper, lower, length=0.1,...){ if(length(x) != length(y) | length(y) !=length(lower) | length(lower) != length(upper)) stop("vectors must be same length") arrows(x,y+upper, x, y-lower, angle=90, code=3, length=length, ...)} ¾ error.bar(ejeX,t(datos2M),upper=t(datos2Mdvest),lower=rep(0,length= length(datos2Mdvest)))
M2 M3 M4 M5
0.00
0.05
Longitud
0.10
0.15
Morfología
Characidae
Cichlidae
Sparidae
Sphyraenidae
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
70
Por último, simplemente dejando el valor por defecto del argumento «beside» en el gráfico sin dispersiones, obtendríamos un gráfico de barras apiladas. Las instrucciones están en el script II.17.R.
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
datos<-read.csv2("Morfología.csv",header=TRUE,encoding= "latin1") attach(datos) datos2<-datos[,c("Familia","M2","M3","M4","M5")] datos2M<-aggregate(datos2[,c("M2","M3","M4","M5")],by=list(datos2$ Familia), mean) datos2M<-datos2M[,-1] rownames(datos2M)<-c("Characidae", "Cichlidae", "Sparidae", "Sphyraenidae") datos2M<-as.matrix(datos2M) barplot(t(datos2M),ylim=c(0,0.4),main="Morfología",ylab="Longitud",font. main=2,font.axis=2,font.lab=2,col=1:4) legend("topleft",colnames(datos2M),bty="n",fill=c("black","red","green", "blue"))
0.4
Morfología
0.2 0.1 0.0
Longitud
0.3
M2 M3 M4 M5
Characidae
Cichlidae
Sparidae
Sphyraenidae
GRÁFICOS BÁSICOS
71
Función barplot (paquete graphics)
height: un vector o matriz con los valores de las barras. width: grosor de las barras: width = 1. space: espacio entre barras: space = NULL. names.arg: vector con los nombres que se pondrán debajo de las barras: names.arg = NULL. legend.text: si su valor es TRUE se utilizan las etiquetas de las filas del archivo como leyenda. También puede ser un vector con nombres. Solo es útil si height es una matriz: legend.text = NULL. beside: si su valor es TRUE se ponen unas barras al lado de las otras y si su valor es FALSE se ponen apiladas: beside = FALSE. horiz: barras horizontales si es TRUE: horiz = FALSE. density: densidad del sombreado de las barras: density = NULL. angle: ángulo de las líneas de sombreado: angle = 45. border: color de los bordes de las barras. NA es sin borde. xpd: si es TRUE se permite que las barras salgan de la región del gráfico: xpd = TRUE. axes: si es TRUE se muestran las etiquetas del eje y: axes=TRUE. axisnames: si es TRUE se muestra el otro eje con sus etiquetas: axisnames = TRUE. cex.axis: tamaño de las etiquetas del eje y: cex.axis = par("cex.axis"). cex.names: tamaño de las etiquetas de las barras: cex.names = par("cex.axis"). inside: si es TRUE se resaltan las líneas que dividen las barras adyacentes. Solo se utiliza si space = 0: inside = TRUE. axis.lty: tipo de línea de las marcas que hay debajo de las barras: axis.lty = 0. offset: vector indicando cuanto se separan las barras del eje x: offset = 0. args.legend: listado adicional de argumentos para la leyenda: args.legend = NULL.
Se pueden usar todos los argumentos generales. En el script II.18.R se utiliza la función «barp()» del paquete “plotrix” (Lemon, 2012). En la primera parte del script se calculan las medias por familia de varias medidas morfológicas (M2, M3, M4 y M5). Posteriormente al archivo creado con las medias se le quita la primera columna y se crea «datos2». A esta matriz de datos se le añaden las etiquetas de las columnas con la función «colnames()», quedando la matriz de datos como se muestra a continuación:
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
72
En la función «barp()», con el argumento «names.arg» se definen las etiquetas del eje x, que en este caso son las etiquetas de las columnas de la matriz de datos. El paquete “grDevices”, el cual viene por defecto cuando se instala R, permite utilizar los colores de forma más cómoda: usaremos «rainbow(4)» para definir los colores de relleno de las barras. El número 4 es debido a que hay cuatro familias de peces en los datos. Con «cylindrical=TRUE» se puede especificar que las barras sean cilíndricas y con «shadow=TRUE» que tengan sombra. Con «staxx=TRUE» y «staxy=TRUE» se puede hacer que las etiquetas de los ejes x e y no se pongan al mismo nivel en vertical, lo cual es útil en el caso de etiquetas grandes que se solapan.
0.1
M2 M3 M4 M5
0
¾ ¾
Longitud
¾ ¾ ¾ ¾ ¾
library(plotrix) datos<-read.csv2("Morfología.csv",header=TRUE,encoding= "latin1") attach(datos) datos1<-aggregate(datos[ ,c("M2", "M3", "M4", "M5")], by = list(Familia), mean) datos2<-datos1[,-1] datos3<-t(datos2) colnames(datos3)<-c("Characidae","Cichlidae","Sparidae","Sphyraenidae") datos3 barp(datos3,names.arg=colnames(datos3), cex.axis=1.2, col=rainbow(4), cylindrical=TRUE, shadow=TRUE, staxx=FALSE, staxy=FALSE, legend.lab= c("M2","M3","M4","M5"), legend.pos=list(x=0.7,y=0.12), xlab="", ylab="", border=TRUE) mtext("Familias",1,line=2.8, font=2, cex=1.6) mtext("Longitud",2,line=2.6, font=2, cex=1.6)
0.05
¾ ¾ ¾ ¾
Characidae
Cichlidae
Sparidae
Familias
Sphyraenidae
GRÁFICOS BÁSICOS
73
II.10. Gráficos circulares En el script II.19.R hay tres ejemplos de gráfico circular o de sectores, que representa las frecuencias de una variable mediante la amplitud de un sector circular. Aunque se suele utilizar con variables cualitativas, también es útil para representar variables cuantitativas. Se utiliza el archivo Población.csv, que contiene datos de la estructura de la población de hombres y mujeres de España en diferentes años. En el primer gráfico se representa la estructura de edad de las mujeres que había en España en el año 1991. La función que se utiliza es «pie()». El argumento «sep="\n"» permite saltar una línea en el título del gráfico. Con «clockwise» se puede indicar si los sectores del gráfico van cambiando en el sentido de las agujas del reloj o a la inversa. Con «init.angle» se especifica el ángulo donde empieza el primer sector, que por defecto es cero. Por último, con «radius» se define el tamaño del círculo.
¾ Datos<-read.csv2("Población.csv", header=TRUE, encoding="latin1") ¾ attach(Datos) ¾ pie(M.1991, labels=Edad, main = paste("Estructura de edad de", sep="\n", "mujeres españolas en 1991"), cex.main=1.55, clockwise=FALSE, init.angle = 0, radius = 1)
Estructura de edad de mujeres españolas en 1991 20 a 24
15 a 19 10 a 14
25 a 29 5a9
30 a 34 <5 > 85 80 a 84
35 a 39
75 a 79 40 a 44
70 a 74 65 a 69
45 a 49 50 a 54
60 a 64 55 a 59
74
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Función pie (paquete graphics) x: vector o variable con los valores a representar. labels: vector o variable con las etiquetas. edges: el círculo es en realidad un polígono, y edges es el número de lados: edges = 200. radius: tamaño del círculo en una escala de -1 a 1: radius = 0.8. clockwise: valor lógico que define si las secciones avanzan en el mismo sentido o contrario de las agujas del reloj: clockwise = FALSE. init.angle: ángulo donde se inicia la primera sección: init.angle = if(clockwise) 90 else 0. density: densidad de las líneas de sombreado: density = NULL. angle: ángulo de las líneas de sombreado: angle = 45. border: color de los bordes. NA es sin borde: border = NULL. Se pueden usar todos los argumentos generales.
En el segundo gráfico se utiliza la función «pie3D()» también del paquete “plotrix” (Lemon, 2012). En primer lugar se transpone la matriz con la función «t()» seleccionando solamente las filas 2 a 5 de la matriz original. Posteriormente, con «colnames()» se asignan a la nueva matriz las etiquetas que había en la primera columna de la matriz original, es decir, las clases de edad. El nuevo archivo queda de la siguiente forma:
¾ ¾ ¾ ¾
library(plotrix) Datos1<-as.data.frame(t(Datos[,2:5])) colnames(Datos1)<-(Datos[1:18,1]) Datos1
En la función «pie3D()», el argumento «explode» especifica cuanto se separan los sectores. Con «height» y «tetha» se define la altura y el ángulo de inclinación de los sectores. Con «start» se indica el ángulo en que comienza el primer sector.
¾ pielabels<-c("Mujeres\n en 1900","Hombres\n en 1900","Mujeres\n en 1991","Hombres\n en 1991")
GRÁFICOS BÁSICOS
75
¾ pie3D(Datos1[,18], edges=100, explode=0.1, radius=0.87, height=0.3, theta=0.5, start=0, labelcol="black", labelcex=1.2, main = "", cex.main= 1.55, labels=pielabels) ¾ text(0, 0.75, paste("Personas mayores de 85 años", sep="\n", "en diferentes años"), font=2, cex=1.6)
Personas mayores de 85 años en diferentes años Mujeres en 1991
Hombres en 1900 Mujeres en 1900
Hombres en 1991 En el tercer y último gráfico del script, se utiliza la función «fan.plot()» del paquete “plotrix” (Lemon, 2012). En primer lugar definimos una paleta de colores con la función «terrain.colors()» y asignamos el valor 18, ya que es el número de clases de edad. Con el argumento «max.span» se indica la amplitud, en radianes, que ocupa el gráfico completo. Con «label.radius» se indica cuanto se separan las etiquetas del gráfico. Con «radius» se define el tamaño del gráfico.
¾ library(plotrix) ¾ color<-terrain.colors(18) ¾ fan.plot(H.1900, labels=Edad, max.span=6, col=color, label.radius=1.2, radius=1, edges=100, main = "Estructura de edad de hombres españoles en 1900") En el gráfico, el número de individuos de cada clase de edad se muestra por medio del tamaño de cada uno de los sectores del gráfico, es decir, aquellas clases de edad con más individuos tienen un sector del círculo de mayor tamaño. Además las clases se ordenan por frecuencia, de menor a mayor, de tal forma que la clase con menos individuos es la de hombres mayores de 85 años y la que tiene más individuos es la de los niños de menos de 5 años. Si dos clases tuviesen el mismo número de individuos entonces se solaparían, ya que el tamaño de ambos sectores sería igual.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
76
Estructura de edad de hombres españoles en 1900 40 a 44
35 a 39
30 a 34
50 a 54 25 a 29 45 a 49 20 a 24 55 a 59
15 a 19
60 a 64
10 a 14 65 a 69
70 a 74 75 a 79 80 a 84
5a9 > 85
<5
La función «dotcircle()» del paquete “ade4” (Chessel y col., 2012) permite representar puntos en un círculo. Se utilizan de nuevo los datos del archivo Población.csv y las instrucciones están en el script II.20.R. El radio del círculo viene determinado por el valor máximo de la serie de datos. El argumento «labels» define la variable que se usará como etiqueta. Con «clabel» y «cleg» se especifica el tamaño de las etiquetas y de los rangos de la variable. Con «alpha0» se define el ángulo polar del primer radio. Por último, para los títulos usamos el argumento «ltext» del paquete “lattice” (Sarkar, 2012).
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
library(lattice) library(ade4) Datos<-read.csv2("Población.csv",header=TRUE,encoding= "latin1") attach(Datos) windows(15,7) par(mfrow=c(2,2)) dotcircle(M.1900,labels=Edad,clabel=1,cleg=1.5,alpha0=2) ltext(x = 120, y =20,labels = "Mujeres en 1900",cex = 1.5,font=2) dotcircle(M.1991,labels=Edad,clabel=1,cleg=1.5,alpha0=2) ltext(x = 800, y =20,labels = "Mujeres en 1991",cex = 1.5,font=2) dotcircle(H.1900,labels=Edad,clabel=1,cleg=1.5,alpha0=2) ltext(x = 120, y =340,labels = "Hombres en 1900",cex = 1.5,font=2) dotcircle(H.1991,labels=Edad,clabel=1,cleg=1.5,alpha0=2) ltext(x = 800, y =340,labels = "Hombres en 1991",cex = 1.5,font=2)
14
5a9
<5
5 >8
80
a
84
1800000
10 a
14
80
a
10 a
1200000
84
77
Mujeres en 1991
5a9
5 >8
Mujeres en 1900
<5
GRÁFICOS BÁSICOS
19
79
79
75 a 20 a
24
0
70 a 74
0
0
19
20 a
1200000
1800000
2e+05
2e+05
1800000
25 a 29
25 a 29
2e+05
65 a
0
65 a
69
30 a
34
a 60
64
69
64
14
5a9
<5
80
a
84
2e+06
10 a
14 10 a
80
a
5 >8
5a9
<5
5 >8
39
Hombres en 1991
44
45 a 49
54
44
50 a
1800000
a 40
59
a 40
54
45 a 49
50 a
1200000
84
a
39
55 a
a
59
Hombres en 1900
35
35
55 a
1200000
34
a 60
30 a
24
2e+05
70 a 74
1200000
a 15
75 a
a 15
19
79
79
75 a 20 a
24
0
70 a 74
0
0
19
20 a
1200000
2e+06
0
0
2e+06
25 a 29
25 a 29
0
65 a
30 a
65 a
69
34
a 60
0
69
30 a
34
a 60
64
35
64
35
a 39
39
55 a
a
55 a
44
45 a 49
a 40
2e+06
54
44
50 a
59
a 40
54
45 a 49
50 a
59
1200000
24
0
70 a 74
1200000
a 15
75 a
a 15
Función dotcircle (paquete ade4) z: vector, variable o conjunto de datos a representar. alpha0: ángulo polar donde se coloca el primer eje: alpha0 = pi/2. labels: vector o variable con las etiquetas de los ángulos: labels = names(z). xlim: límites de círculo: xlim = range(pretty(z)). clabel: tamaño de letra de las etiquetas de los ángulos: clabel = 1. cleg: tamaño de letra de los rangos de la variable: cleg = 1.
II.11. Gráficos de puntos El gráfico de puntos es similar al diagrama de barras, y representa un punto (en lugar de una barra) cuya altura es proporcional al valor de la variable que se representa. Las instrucciones están en el archivo II.21.R y se usan de nuevo los datos del archivo Población.csv. Se representa en este caso la estructura de edad de los hombres en España en los años 1900 y 1991. La función que se utiliza es «dotchart()». Al final se añade una leyenda, que ubicamos arriba a la derecha con «topright», y con el argumento «bty="n"» se indica que no tenga borde.
¾ Datos<-read.csv2("Población.csv", header=TRUE, encoding="latin1") ¾ attach(Datos) ¾ dotchart(H.1991, labels=Edad, xlim=c(0,2000000), main = paste ("Estructura de edad de", sep="\n","hombres españoles en 1900 y 1991"), cex.main = 1.8, pch = 15, xlab ="Nº de hombres", cex.lab=1.6, font.lab=2) ¾ mtext("Clases de edad en años",2,line=2.4, font=2, cex=1.6)
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
78
¾ par(new=TRUE) ¾ dotchart(H.1900,labels=Edad, xlim=c(0,2000000)) ¾ legend("topright", c("1900", "1991"), bty="n", pch = c(1,15))
Estructura de edad de hombres españoles en 1900 y 1991 1900 1991
> 85 80 a 84
Clases de edad en años
75 a 79 70 a 74 65 a 69 60 a 64 55 a 59 50 a 54 45 a 49 40 a 44 35 a 39 30 a 34 25 a 29 20 a 24 15 a 19 10 a 14 5a9 <5
0
500000
1000000
1500000
2000000
Nº de hombres II.12. Gráficos ternarios Se utilizan para representar simultáneamente tres variables con suma constante. Este tipo de gráficos se puede hacer con la función «triangle.plot()» del paquete “ade4” (Chessel y col., 2012). En este ejemplo usaremos también la función «grid_legend()», que requiere tener instalado el paquete “vcd” (Meyer y col., 2012). Las instrucciones están en el archivo II.22.R. Los datos están en el archivo Pigmentos.csv y consisten en la cantidad de diferentes pigmentos que tienen tres algas fitoplanctónicas. En el primer gráfico se selecciona la especie T.suecica y se representan los pigmentos que están en las columnas 2, 3 y 5. Es necesario seleccionar 3 variables y automáticamente los datos se transforman en proporciones cuya suma es 1. El argumento «scale=TRUE» permite que el gráfico ajuste de forma automática la escala de los ejes a los datos. El triángulo pequeño muestra la posición del
GRÁFICOS BÁSICOS
79
gráfico representado en el triángulo completo. Con «cpoint» se define el tamaño de los símbolos. Con «sub» se puede poner un título al gráfico y, con «possub» y «csub» se define la posición y tamaño de letra del título, respectivamente.
¾ ¾ ¾ ¾ ¾ ¾ ¾
library(ade4) library(vcd) datos<-read.csv2("Pigmentos.csv",header=TRUE,encoding="latin1") attach(datos) windows(11,7) par(mfrow = c(2,2)) triangle.plot(datos[Especie=="T. suecica",c(2,3,5)], scale =TRUE, cpoint=3, sub="T. suecica", possub = "topright", csub=2)
En el segundo gráfico se utilizan todas las especies y hemos cambiado los pigmentos, ahora son las variables 3, 4 y 5 de la matriz de datos. En este caso «scale=FALSE» para poder definir los límites de los ejes del gráfico con «min3» y «max3». Como hay tres especies, en vez de los símbolos se usa el nombre de las especies con el argumento «label» y el tamaño de esta leyenda se define con «clabel». La zona sombreada del triángulo pequeño muestra como el rango de los ejes ha cambiado.
¾ triangle.plot(datos[,c(3,4,5)],scale =FALSE, cpoint=3, sub="% Pigmentos", possub = "topright",csub=2, min3=c(0,0,0.6), max3=c(0.6,0.6,1), label= Especie, clabel=1) En el tercer gráfico se quita el triángulo pequeño con «show.position= FALSE» y «addmean=TRUE» permite mostrar el valor medio de las tres variables para todo el conjunto de datos.
¾ triangle.plot(datos[,c(3,4,5)],scale =TRUE, cpoint=3, sub="% Pigmentos", possub = "topright", csub=2, min3=c(0,0,0.6), max3=c(0.6,0.6,1), show.position=FALSE, addmean=TRUE) En el último gráfico se muestra como poner diferentes símbolos a cada especie y una leyenda. Para ello es necesario representar por separado cada especie y luego con «points()» se cambia el color y el tamaño de los símbolos. La función «grid_legend()» permite añadir una leyenda.
¾ G1 <-triangle.plot(datos[Especie=="T. suecica", c(3,4,5)], scale =TRUE, cpoint=3, sub="", possub = "topleft", csub=2, min3=c(0,0,0.6), max3=c(0.6,.6,1), show.position=FALSE) ¾ points(G1 , pch=16, col="blue", cex=2) ¾ par(new=TRUE) ¾ G2 <-triangle.plot(datos[Especie=="Chlorella sp.", c(3,4,5)], scale =TRUE, cpoint=3, sub="", possub = "topleft", csub=2, min3=c(0,0,0.6), max3=c(0.6,.6,1),show.position=FALSE) ¾ points(G2 , pch=16, col="green", cex=2) ¾ par(new=TRUE)
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
80
¾ G3 <-triangle.plot(datos[Especie=="Ch. autotrophica", c(3,4,5)], scale = TRUE, cpoint = 3, sub="", possub = "topleft", csub=2, min3=c(0,0,0.6), max3=c(0.6,.6,1),show.position=FALSE) ¾ points(G3 , pch=16, col="red", cex=2) ¾ grid_legend(0.85, 0.45, pch=c(16,16,16), col = c("blue","green","red"), c("T. suecica", "Chlorella sp.", "Ch. autotrophica"), title = "Algas", gp = gpar (fontface=3, fontsize=12)) T. suecica 0.2
0.7
0
1
Ch.autotrophica autotrophica Ch. Ch. autotrophica
NEOXANTINA
LUTEINA
VIOLOXANTINA
LUTEINA
Chlorella Chlorellasp. sp. Chlorellasp. sp. Chlorella
T. suecica T. suecica T.T.suecica suecica
0.5 0.1
VIOLOXANTINA
0.4 0.4
T. suecica
0.4 0
ZEAXANTINA
% Pigmentos 0
1
0.158 VIOLOXANTINA
0
LUTEINA
1
0.6 0.4
Algas T. suecica Chlorella sp. Ch. autotrophica
VIOLOXANTINA
LUTEINA
0.74
0.4 0
0.102 ZEAXANTINA
0.6 0.4
0.4 0
ZEAXANTINA
0.6 0.4
Función triangle.plot (paquete ade4) ta: data frame donde hay que especificar las tres variables a representar. label: variable con las etiquetas de los puntos. clabel: tamaño de letra de las etiquetas: clabel = 0. cpoint: tamaño de los puntos: cpoint = 1. draw.line*: si es TRUE se pinta la trama de líneas interiores: draw.line = TRUE. addaxes: si es TRUE se pintan los ejes principales: addaxes = FALSE. addmean: si es TRUE se pinta la media de cada eje: addmean = FALSE. labeltriangle: si es TRUE se muestran los nombres de las variables: labeltriangle = TRUE. sub: título del gráfico. csub: tamaño de letra del título.
GRÁFICOS BÁSICOS
81
Función triangle.plot (Continuación) possub: posición del título con las opciones: "topleft", "topright", "bottomleft" o "bottomright": possub = "topright". show.position*: si es TRUE se representa la posición del triángulo dentro del triángulo completo: show.position = TRUE. scale*: si es TRUE se ajusta automáticamente la escala de los ejes: scale = TRUE. min3 y max3: vectores con formato c(x, y, z) que indican el mínimo y el máximo de los ejes si scale es FALSE: min3 = NULL y max3 = NULL. box: si es TRUE se pinta un marco: box = FALSE. Los argumentos con * también son de la función triangle.biplot(). En el gráfico del script II.23.R se muestra un ejemplo de la función «triangle.biplot()», que es también del paquete “ade4” (Chessel y col., 2012). Esta función permite representar dos matrices. En el script se importan los datos del archivo Pigmentos1.csv, con los mismos pigmentos y especies de algas fitoplanctónicas, pero en otras condiciones diferentes de cultivo. La única diferencia es que hay que definir dos matrices, cada una con tres variables. Las flechas nos indican el cambio que se ha producido al cambiar de medio de cultivo.
¾ ¾ ¾ ¾
library(ade4) datos<-read.csv2("Pigmentos.csv",header=TRUE,encoding="latin1") datos1<-read.csv2("Pigmentos1.csv",header=TRUE,encoding="latin1") triangle.biplot(datos[datos$Especie=="T. suecica", c(2,3,5)], datos1 [datos1$Especie== "T. suecica",c(2,3,5)], show.position=T, scale=T)
0.2
0.7
NEOXANTINA
LUTEINA 4 3 12 5
0.5 0.1
VIOLOXANTINA
0.4 0.4
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
82
El gráfico ternario también se puede hacer con la función «ternaryplot()», la cual necesita tener instalado el paquete “vcd” (Meyer y col., 2012). Las instrucciones están en el archivo II.24.R y usaremos los mismos datos del archivo Pigmentos.csv. El argumento «scale» permite definir si los datos se transforman a una escala de 1 ó de 100. El argumento «dimnames_position» define la posición de las leyendas de los ejes. Con «grid_color» se especifica el relleno del triángulo, el cual es «grey60» en el primero y «transparent» en los siguientes, para que no tape los símbolos de los gráficos anteriores. Con «labels_color» y «labels» se especifica el color y la posición de la numeración de los ejes, ésta última teniendo las otras opciones de «inside» y «none». Por último, con «newpage» se define si se crea un nuevo gráfico o se añaden los símbolos al anterior. En este gráfico no es posible cambiar los límites de los ejes.
¾ ¾ ¾ ¾
library(vcd) datos<-read.csv2("Pigmentos.csv",header=TRUE,encoding="latin1") attach(datos) ternaryplot(datos[Especie=="T. suecica",c(2,3,5)],scale=100,pch=c(15), col = "blue", dimnames_position = "edge", main="Porcentaje pigmentos", bg = "grey60", grid_color="black", labels_color="black", labels=c("outside")) ¾ ternaryplot(datos[Especie=="Chlorella sp.",c(2,3,5)],scale=100,pch=c(16), col="green",grid=FALSE,dimnames_position = "edge", bg="transparent", main="Porcentaje pigmentos", labels=c("outside"), newpage = FALSE) ¾ ternaryplot(datos[Especie=="Ch. autotrophica",c(2,3,5)], scale=100,pch= c(17),col="red",grid=FALSE,dimnames_position="edge",bg= "transparent", main="Porcentaje pigmentos", labels = c("outside"), newpage = FALSE) ¾ grid_legend(0.8, 0.75, pch=c(15,16,17), col=c("blue","green", "red"), c("T. suecica", "Chlorella sp.", "Ch. autotrophica"),title = "Algas", gp = gpar (fontface=3, fontsize=12)) Porcentaje pigmentos
20
Algas T. suecica Chlorella sp. Ch. autotrophica
60
AN T VIO
A TI N
LO X
60
AN OX NE
40
INA
80
40
80
LUTEINA
20
40
60
80
20
GRÁFICOS BÁSICOS
83
Función ternaryplot (paquete vcd) x: data frame donde hay que especificar las tres variables a representar. scale: los valores se ponen en una escala de 1 ó de 100: scale = 1. dimnames: se puede especificar una variable que se usa para las leyendas de los ejes: dimnames = NULL. dimnames_position: posición de las leyendas de los ejes, donde las opciones son "corner","edge" o "none". dimnames_color: color de las leyendas de los ejes: dimnames_ color = "black". id: etiquetas opcionales que se pueden mostrar al lado de los símbolos: id = NULL. id_color: color de las etiquetas anteriores: id_color = "black". id_just: vector con 1 o 2 términos indicando la justificación de las etiquetas anteriores: id_just = c("center", "center"). coordinates: si es TRUE se muestran las coordenadas de los puntos: coordinates = FALSE. grid: si es TRUE se muestra la trama interior de líneas: grid = TRUE. grid_color: especifica el color de la trama: grid_color = "gray". labels: posición de la numeración de los ejes, la cual puede ser "inside", "outside" o "none". labels_color: color de la numeración de los ejes: labels_color = "darkgray". prop_size: si es TRUE el tamaño de los símbolos es proporcional a la suma de las tres variables: prop_size = FALSE. newpage: si es FALSE no se crea un nuevo gráfico y, por tanto, se añaden los símbolos al anterior gráfico ya creado: newpage = TRUE.
II.13. Gráficos de contornos y superficies Los gráficos de contornos son fáciles de realizar en R si disponemos de los datos adecuados. Hay varias funciones en el paquete “graphics” como «image()», «contour()» y «filled.contour()» que nos permiten realizar este tipo de gráficos. La función «contour()» permite hacer mapas topográficos. En el archivo Batimetría.csv hay datos de profundidades y de alturas de islas en una zona del océano donde hay fosas abisales, que fueron obtenidos de la página web http://rda.ucar.edu/datasets/ds759.2/. Las instrucciones están en el archivo II.25.R. Se utiliza la función de interpolación «interp()», presente en el paquete “akima” (Akima, 1978: Akima, 1996; Akima y col., 2012), por lo que es necesario instalarlo. El argumento «type="n"» indica que no se represente ningún marcador en el eje. El argumento «pty="m"» indica que la región del gráfico sea la máxima posible cuando se amplía la pantalla, como se muestra en el gráfico. El argumento «fg="blue"» modifica el color del marco, líneas y texto del gráfico.
¾ require(akima) ¾ par(fg=”blue”) ¾ Datos<-read.csv2("Batimetría.csv", header=TRUE, encoding="latin1")
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
84 ¾ ¾ ¾ ¾
attach(Datos) input<-interp(Datos$Longitud, Datos$Latitud, Datos$Profundidad) par(pty = "m",fg="blue") plot(x = 0, y = 0,type = "n", xlim = c(130,150), ylim = c(33,35), xlab = "Longitud", ylab = "Latitud", cex.lab=1.7, font.lab = 2, cex.axis = 1.6) ¾ contour(input, lty = "solid", add = TRUE, vfont = c("sans serif", "plain"), labcex=1.2) ¾ title("Batimetría y Altimetría entre 33º N a 35ºN y 130ºE a 150ºE", font = 2, cex.main=2)
34.0 33.0
33.5
Latitud
34.5
35.0
Batimetría y Altimetría entre 33º N a 35ºN y 130ºE a 150ºE
130
135
140
145
150
Longitud
Si se realiza un pequeño cambio y se especifica «pty= "s"», la región del gráfico es cuadrada, como se muestra a continuación, y no se hace rectangular cuando se amplía la ventana, como en el caso anterior. Si además se pone «fg="black"», se observa como ahora el gráfico es en negro en vez de azul.
GRÁFICOS BÁSICOS
85
Función contour (paquete graphics) x, y, z: x e y son las coordenadas, y z la variable a representar. nlevels: si levels es NULL define el número de líneas de contorno: nlevels = 10. levels: vector numérico con los niveles de los contornos que se representan. Por ejemplo, levels=c(20,300) solamente representa los niveles 20 y 300: levels = pretty(zlim, nlevels). labels: etiqueta de las líneas de contorno: labels = NULL. zlim: como xlim e ylim especifica los límites de la variable z. labcex: tamaño de la letra de las etiquetas de las líneas de contorno: labcex = 0.6. drawlabels: si es FALSE no se ponen las etiquetas de los contornos: drawlabels = TRUE. method: se especifica donde se colocan las etiquetas de los contornos: "simple", "edge" o "flattest": method = "flattest". vfont: vector con dos términos: tipo y estilo de letra. axes: si es TRUE se pintan todos los ejes: axes = TRUE. Se pueden usar todos los argumentos generales.
Veamos otro ejemplo con «filled.contour()». Las instrucciones están en el archivo II.26.R. En el archivo Riqueza.csv hay datos de número de especies para diferentes latitudes y longitudes. Para este tipo de funciones, primero tenemos que crear un objeto dividido en niveles con un intervalo regular, y con valores crecientes de las variables x e y. Si no disponemos de esos datos, como es nuestro caso, debemos generarlos. Para eso nos sirve la función «interp()», presente en el paquete “akima” (Akima, 1978: Akima, 1996; Akima y col., 2012). Una vez que poseemos este objeto, es muy sencillo el uso de la función gráfica «filled.contour()» o similares. Sólo es importante tener en cuenta que la instrucción «interp()» no admite celdas vacías. Para poder ver los valores bajos del eje z, a veces es conveniente poner valores cero de z. Una escala de grises se puede ver con el argumento «col=grey.colors(33, start=1, end=0, gamma=1)». Con el argumento «plot.axes» se especifican los intervalos de los ejes. Con «axis» se especifica el intervalo y el número de marcas en cada uno de los ejes. Con «key.title» se indica el título del gráfico. Por último, con «key.axes» se especifica el rango e intervalos de la barra de colores de la leyenda.
¾ ¾ ¾ ¾
require(akima) datos<-read.csv2("Riqueza.csv",header=TRUE,encoding="latin1") attach(datos) input<-interp(Longitud.Oeste, Latitud.Sur,Riqueza.especies, duplicate= "mean") ¾ filled.contour(input,xlab="Longitud", ylab="Latitud", main="Riqueza de especies",font.lab=2, plot.axes = { axis(1, seq(50, 70, by = 5)) axis(2, seq(0, 20, by = 2))}, key.title = title(main= "Número\nespecies", cex.main=1.1), key.axes = axis(4, seq(0, 35, by = 5)))
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
86
Número especies
Riqueza de especies
35
18 16
30 14 25
Latitud
12 10
20
8 15 6 4
10
2 5 50
55
60
65
Longitud
Función filled.contour (paquete graphics) x, y, z: x e y son las coordenadas, y z la variable a representar. zlim: como xlim e ylim especifica los límites de la variable z. levels: vector numérico con los niveles de los contornos que se representan. Por ejemplo, levels=c(20,300) solamente representa los niveles 20 y 300. nlevels: si levels es NULL especifica el número de líneas de contorno: nlevels = 20. labels: etiqueta de las líneas de contorno. color.palette: función con los colores del gráfico. plot.axes: define los intervalos de los ejes. key.title: título de la leyenda del gradiente de colores. key.axes: permite modificar los intervalos y límites del gradiente de colores. frame.plot: si es TRUE se pinta un marco: frame.plot = axes. Se pueden usar todos los argumentos generales.
GRÁFICOS BÁSICOS
87
II.14. Gráficos tridimensionales Otra función gráfica interesante es «persp()», la cual permite realizar gráficos en tres dimensiones. Las instrucciones para este ejemplo están en el archivo II.27.R. Los datos que se utilizan, que están en el archivo Altimetría1.csv, son de altimetría y batimetría; desde el Golfo de Omán hasta la estepa Siberiana, en concreto para una latitud desde 23º10´N hasta 61º5´N y una longitud desde 61ºE hasta 117º30´E. Cada celda son 5 segundos. Con la función «windows()» se especifica que se cree una nueva ventana con un tamaño específico de alto y ancho, para así poder ver el gráfico más grande. Después de leer los datos, la instrucción «as.matrix» los convierte en una matriz. Como el archivo solo tiene datos de altura y profundidad (coordenada z), es necesario definir las coordenadas x (latitud) e y (longitud). Se multiplica por 100 para que el espacio sea mayor entre coordenadas y quede más claro el gráfico. La instrucción «scale=FALSE» hace que tengan el mismo tamaño los ejes z, x e y, lo cual permite que se mantenga la proporción entre los ejes. La instrucción «box=TRUE» representa un marco. Las flechas en cada eje representan el orden de los datos en el archivo. La latitud en el archivo va desde 61º5´N (primera fila) a 23º10´N (última fila) y, por tanto, la flecha nos indica de mayor a menor latitud. La longitud en el archivo va desde entre 61ºE (primera columna) a 117º30´E (última columna) y, por tanto, la flecha nos indica de menor a mayor longitud.
¾ ¾ ¾ ¾ ¾ ¾
Datos<-read.csv2("Altimetría1.csv", header=TRUE, encoding="latin1") windows(w=15.5,h=9.5) z<-as.matrix(Datos) x <- 100 * (1:nrow(z)) y <- 100 * (1:ncol(z)) persp(x, y, z, theta = 120, phi = 20, scale = FALSE, box=TRUE, zlab= "Metros", xlab="Latitud", ylab="Longitud", cex.lab=2) ¾ title("Latitud 23º25´N a 61º5´N y Longitud 61ºE a 117º30´E", font=2, cex.main = 2)
88
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
En el siguiente gráfico, pequeñas modificaciones pueden dar lugar a cambios importantes en el formato. Con la instrucción «phi» se puede cambiar el ángulo de visión. La instrucción «theta» permite cambiar la orientación del gráfico; se observa como ahora se ve de frente la latitud, e incluso se puede observar la zona del Golfo de Omán donde hay profundidades superiores a 2.000 metros. El argumento «border=NA» elimina el borde, dándole ese aspecto más uniforme. La instrucción «shade» permite dar sombras. Los valores de sombra cercanos a 1 producen sombreados similares a un modelo de fuente de luz puntual y valores cercanos a 0 no producen sombra. Valores en el rango de 0,5 a 0,75 proporcionan una aproximación a la iluminación diurna. Por último, la instrucción «ticktype="detailed"» pone intervalos en los ejes del gráfico con sus correspondientes valores. Es necesario recordar que los valores de latitud y longitud van en una escala que no es la real, ya que simplemente muestran el número de fila y columna de cada celda en la matriz de datos, multiplicado por 100. En el siguiente ejemplo veremos como realizar gráficos con coordenadas reales.
¾ windows(w=15.5, h=9.5) ¾ persp(x, y, z, theta = 20, phi = 20, scale = FALSE, zlab="Metros", xlab= "Latitud", ylab="Longitud", cex.lab=2, box=TRUE, border=NA, shade= 0.5, ticktype="detailed") ¾ title("Latitud 23º15´N a 61º5´N y Longitud 61ºE a 117º30´E", font = 2, cex.main = 2)
GRÁFICOS BÁSICOS
89
Función persp (paquete graphics)
x, y, z: x e y son las coordenadas, y z la variable a representar. nlevels: si levels es NULL especifica el número de líneas de contorno. zlim: como xlim e ylim especifica los límites de la variable z. theta: ángulo de orientación del gráfico: theta = 0. phi: ángulo de visión: phi = 15. r: distancia desde el punto de visión al centro del gráfico. Da una idea de profundidad: r = sqrt(3). d: valores menores que 1 aumentan la perspectiva y mayores que 1 la disminuyen: d = 1. scale: si es FALSE hace que se mantengan las proporciones entre los ejes: scale = TRUE. expand: factor de expansión del eje z: expand = 1. ltheta y lphi: orientación y ángulo de visión del sombreado: ltheta = -135 y lphi = 0. shade: permite dar sombras: shade = NA. box: si es TRUE se pinta un marco: box =TRUE. nticks: número de marcas en los ejes. No funciona si ticktype=”simple”: nticks = 5. ticktype: "simple" dibuja una flecha en la dirección de crecimiento de la variable y "detailed" marcas normales: ticktype = "simple".
Se pueden usar todos los argumentos generales.
En el gráfico 3 se utiliza la función «wireframe()» del paquete “lattice” (Sarkar, 2008; 2012). Se usa un área más restringida, en concreto de 23ºN a 26ºN de latitud y una longitud de 70ºE a 85ºE, cuyos datos están en el archivo Altimetría2.csv. Con los argumentos «shade» y «light.source» se hace el efecto de sombreado de colores. Como el rango de longitud es 5 veces mayor que el de latitud, con «aspect» se hace que el eje de la longitud sea 5 veces superior al eje de la latitud. Las modificaciones en las leyendas de los ejes se deben introducir para cada eje por separado en una lista. Por ejemplo, en el caso del eje z se especifica que «rot=90», con lo cual se le da una rotación de 90º a la leyenda de ese eje. Las etiquetas y formato de las marcas de los ejes se deben introducir en el argumento «scales» y también dentro de una lista, pudiéndose hacer especificaciones para cada eje. Por ejemplo, para el eje z se especifica que no se pinten las flechas «arrows=FALSE». Con «ltext» es posible introducir textos.
¾ ¾ ¾ ¾
library(lattice) Datos<-read.csv2("Altimetría2.csv", header=TRUE, encoding="latin1") z<-as.matrix(Datos) wireframe(z, shade = TRUE, aspect = c(1.5,1,0.3), light.source = c(10,0,10), zlab=list("Metros",cex=1.2,font=2,rot=90), xlab=list("Latitud", cex=1.2, font=2), ylab=list("Longitud",cex=1.2,font=2), scales=list (z=list (arrows= FALSE)), page = function(...) { ltext(x = 0.47, y = 0.15,labels = "70ºE",cex = 1.2,font=2) ltext(x = 0.15, y = 0.40,labels = "85ºE",cex = 1.2,font=2)
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
90
ltext(x = 0.57, y = 0.15,labels = "23ºN",cex = 1.2,font=2) ltext(x = 0.85, y = 0.29,labels = "26ºN",cex = 1.2,font=2) })
Metros
1000 800 600 400 200 0
85ºE
26ºN Longitud 70ºE
23ºN
Latitud
Función wireframe (paquete lattice)
x: matriz con los datos a representar. data: opcionalmente se puede especificar la matriz con los datos. zlab: título del eje z con el mismo formato que xlab e ylab. aspect: especifica la proporción que tienen los ejes z, x e y entre ellos. zlim: como xlim e ylim especifica los límites de la variable z. row.values y column.values: vectores opcionales que permiten definir la trama del gráfico, donde x es la matriz. Tanto row.values como column.values deben tener la misma longitud que el número de filas y columnas de la matriz x, respectivamente.
Permite el uso de otros argumentos del paquete “lattice” como: allow.multiple, outer, auto.key, prepanel, strip, groups, xlab, xlim, ylab, ylim, drop.unused.levels, lattice.options, scales, etc., los cuales se describieron en el cuadro de la función bwplot().
GRÁFICOS BÁSICOS
91
Como se mencionó anteriormente, también es posible realizar este tipo de representaciones con matrices que tengan las tres coordenadas z, x e y. Por ejemplo, usando los mismos datos del archivo Batimetría.csv y con las instrucciones que están en el archivo II.28.R, se obtiene el gráfico que se muestra a continuación. En este caso se usa «scale=TRUE» y, por tanto, se le da el mismo tamaño a los tres ejes, es decir, no se permite que los ejes tengan el tamaño en función de su rango de valores. Debido a que uno de los ejes (altura/profundidad, eje z) tiene un rango mucho mayor que los otros dos, no es conveniente usar la opción «scale=FALSE». El argumento «family="serif"» define el tipo de letra del gráfico.
¾ ¾ ¾ ¾ ¾ ¾ ¾
require(akima) par(family="serif") Datos<-read.csv2("Batimetría.csv", header=TRUE, encoding="latin1") attach(Datos) windows(w=11,h=9) input<-interp(Datos$Longitud, Datos$Latitud, Datos$Profundidad) persp(input, theta = 20, phi = 20, scale = TRUE, family="sans", zlab = "Metros", xlab = "Latitud", ylab="Longitud", cex.lab=2, box=TRUE, border=NA, shade=0.5, ticktype="detailed") ¾ title("Batimetría y Altimetría entre 33ºN a 35ºN y 130ºE a 150ºE", font = 2, cex.main=2)
Batimetría y Altimetría entre 33ºN a 35ºN y 130ºE a 150ºE
0
-2000
Metros
-4000
35.0 -6000
Longitu
d
34.5 34.0
-8000 130
33.5
135 140
Latit ud
145 33.0 150
La función «persp()» también permite representar funciones tridimensionales. En el archivo II.29.R están las instrucciones para representar diferentes funciones gráficas. La instrucción «seq()» crea una secuencia, en este ejemplo
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
92
de -1 a 1 dividida en 50 intervalos. La instrucción «outer()» estima los valores de la coordenada z usando la función que se especifique y en base a los valores x e y definidos anteriormente. Con «fig=c(x1,x2,y1,y2)» se puede definir la posición relativa en el panel de cada una de las gráficas, en una escala de 0 a 1. Con «fin=c(ancho,alto)» también se podría definir la posición pero la unidades serían en pulgadas.
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
sx <- 50; sy <- 50 x <- seq(-1, 1, length = sx); y <- seq(-1, 1, length = sy) z <- outer(x, y, function(x,y) x^2 + y^2 + 1) par(fig=c(0,0.6,0.4,1)) persp(x, y, z, col = "green", theta = 120, cex.lab=2) z <- outer(x, y, function(x,y) x^2 - y^2) par(new=T,fig=c(0.4,1,0.4,1)) persp(x, y, z, col = "blue", theta = 120, cex.lab=2) z <- outer(x, y, function(x,y) x^3 - y^2) par(new=T,fig=c(0,0.6,0,0.6)) persp(x, y, z, col = "red", theta = 120, cex.lab=2) z <- outer(x, y, function(x,y) x^3 + y^3) par(new=T,fig=c(0.4,1,0,0.6)) persp(x, y, z, col = "grey", theta = 120, cex.lab=2)
z x
y
y
x
z
z
y
x
x
z
y
Por último, en el archivo II.30.R están las instrucciones para representar gráficos tridimensionales con la función «cloud()» del paquete “lattice” (Sarkar, 2008; 2012). En este script también usaremos la función «grid_legend()» del paquete “vcd” (Meyer y col., 2012), que permite poner leyendas de un modo más fácil que los argumentos «key» y «auto.key» que usa la función «cloud()» para leyendas. Los datos, que están en el archivo Aminoácidos.csv, correspon-
GRÁFICOS BÁSICOS
93
den al porcentaje de aminoácidos de varias especies de rotíferos que habitan el parque Nacional de Doñana (España). En «cloud()» se ponen las variables de los ejes z, x e y. Como se ha comentado varias veces, en las funciones del paquete “lattice” (Sarkar, 2008; 2012) las modificaciones de las leyendas de los ejes, títulos o subtítulos, deben incluirse dentro del propio argumento por medio de una lista, como por ejemplo se muestra en este caso para «zlab», «xlab» e «ylab». Es interesante mencionar que para dar la vuelta a la numeración del eje y se ha especificado «ylim=c(10,0)». Con «screen» se controla el ángulo de rotación de los ejes. Si se quisiera poner características diferentes para cada uno de los ejes, de nuevo sería en formato de lista para cada eje. El argumento «distance» permite definir la distancia de las leyendas a los ejes. En la función «grid_legend()» con el argumento «frame=FALSE» se indica que no se pinte un marco en la leyenda y «vgap» define el espacio entre filas. El tipo y tamaño de letra se modifica con el argumento «gp=gpar()».
¾ ¾ ¾ ¾ ¾
library(lattice) library(vcd) Datos<-read.csv2("Aminoácidos.csv", header=TRUE, encoding="latin1") attach(Datos) cloud(ASP ~ SER * GLU, data = Datos, cex = 1.2, pch=c(15,16,17), col=c("green","blue","red"), groups = Especie, zlab=list("Aspartato (%)", cex=1.2, font=2, rot=90), ylab=list("Glutámico (%)", cex=1.2, font=2, rot=50), xlab=list("Serina (%)",cex=1.2,font=2, rot=15),zlim=c(4,10), xlim=c(10,18), ylim=c(10,0), screen = list(z = 20, x = -70, y = 10), scales = list(arrows=FALSE,distance=0.8)) ¾ grid_legend(0.82, 0.46, pch=c(15,16,17), col = c("green","blue","red"), frame = FALSE, c("B. angularis", "B. calyciflorus", "B. plicatilis"), title = "Rotíferos", hgap=10,vgap=0.5, gp=gpar(fontface=3, fontsize=12)) 10
Aspartato (%)
9
8
7
6
Rotíferos B. angularis B. calyciflorus B. plicatilis
5 4 0 2
G
o ic m tá lu
4
6
18 16
8
14
(% )
10
12 10
Serin
a (%
)
94
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Función cloud (paquete lattice) x: matriz de datos o fórmula con el formato z ~ x * y. data: datos que se van a usar con otras variables que se pueden utilizar para definir grupos, hacer selecciones con subset, etc. at: rango para la barra de colores que se representa con drape. drape: si es TRUE se representa una barra con la escala de colores: drape = FALSE. pretty: si es TRUE se calculan automáticamente los puntos de corte de la barra de colores: pretty = FALSE. arrows: si es TRUE los ejes se ponen como flechas: arrows = TRUE. colorkey: permite poner una barra continua o una lista de colores. col.regions: vector de colores de la barra que se crea si drape=TRUE. alpha.regions: valor numérico en un rango de 0 a 1 con el grado de transparencia de los colores de la barra que se crea si drape=TRUE. Los otros argumentos: allow.multiple, aspect, outer, auto.key, prepanel, etc., son comunes a la mayoría de las funciones del paquete “lattice” y se explicaron en los cuadros de la funciones bwplot() y/o wireframe().
Función grid_legend (paquete vcd) x e y: posición de la leyenda. hgap: espacio horizontal entre símbolos y etiquetas: hgap = unit(0.5, "lines"). vgap: espacio vertical entre símbolos y etiquetas: vgap = unit(0.3, "lines"). default_units: término que indica las unidades de la leyenda: default_units = "lines". gp: objeto de la clase gpar() para modificar el tipo y estilo del texto en la leyenda. draw: si es FALSE no se muestra la leyenda: draw = TRUE.
II.15. Configuración de márgenes y ejes adicionales En el ejemplo se usarán series temporales para mostrar como se pueden incluir varios ejes y en el gráfico para representar variables cuyas escalas son muy diferentes. Las instrucciones están en el archivo II.31.R. Se trata de una serie temporal de medidas mensuales, de dos años de duración, realizadas en una laguna. Las variables medidas son: eclosión promedio de larvas de mosquito por metro cuadrado, materia orgánica particulada en mgl-1 y temperatura media del agua en el momento del muestreo. Representaremos un eje y distinto para cada variable. Los datos están en el archivo Mosquitos.csv. En primer lugar debemos establecer un tamaño para los márgenes externos con la instrucción «par(oma)» dejando espacio suficiente para todos los ejes, especialmente del lado derecho. El argumento «par(mex)», al ser menor que 1, permite que la figura se pueda pegar más a los bordes del marco. El argumento
GRÁFICOS BÁSICOS
95
«bg="grey98"» permite especificar el color de fondo del área donde se pondrán los gráficos. Después creamos los sucesivos gráficos, con la particularidad de que utilizamos el argumento «new=TRUE» antes de cada uno de los gráficos que representarán cada variable en un eje distinto. En la función «plot()» con el argumento «yaxs="i"», en vez del valor por defecto «yaxs="r"», se define que se representen exactamente los límites del eje y que se especifican en la función «ylim=c(0,65)» y que no se deje un margen mayor, es decir, en este caso que el valor 0 esté en el extremo inferior y el valor 65 en el extremo superior del eje y. Se podría hacer lo mismo para el eje x con el argumento «xaxs». La función «plot.default()», que tiene los mismos argumentos que la función explicada anteriormente «plot()», permite usar el argumento «ann=FALSE» que especifica que no se muestren las leyendas de los ejes ni los títulos de estos nuevos gráficos. En los nuevos gráficos, indicamos que el eje y no se represente «yaxt="n"». Ese eje lo dibujaremos después con la función «axis()», indicando el margen (4 significa a la derecha). En el segundo caso (eje para POM) indicaremos que el eje lo represente en el margen exterior (argumento «outer=TRUE»), y en la línea 4. El argumento «adj» de la función «title()» permite definir la alineación del texto (en este caso es 0,5, es decir, centrado). También se añade una leyenda, en la cual indicamos que se ubique arriba a la izquierda «topleft». Los argumentos en «pch», «lty» y «lwd» indican el tipo de símbolos, el tipo de líneas y el grosor de las líneas, respectivamente, de cada una de las tres variables. Con «rug()» se representa una línea vertical roja que divide el estudio en dos periodos. Con «box(which="outer")» se pinta un marco exterior. Al final los argumentos de lectura «cra» y «din» informan sobre el tamaño del área donde se muestran los gráficos en píxeles y en pulgadas, respectivamente.
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
datos<-read.csv2("Mosquitos.csv", header=TRUE, encoding="latin1") attach(datos) par(oma=c(1,1,1,9), bg="grey98") par(mex = 0.6) plot(Mes,Mosquitos, type="b", lty=1, lwd=2, ylim=c(0,65), font.lab=2, yaxs="i") par(new=TRUE) plot.default(Mes,Temp,ylim=c(0,30), ann=FALSE ,yaxt="n",type="l",lty=1, yaxs="i") axis(4) mtext("Temperatura",4,line=3,font=2) par(new=TRUE) plot.default(Mes, POM, ylim=c(0,6), ann=FALSE, yaxt="n", type="l", lty=3, lwd = 2, yaxs="i") axis(4,line=4,outer=TRUE) mtext("POM",4,line=9,font=2) title("Eclosión de larvas de mosquito", cex=2, font=2, adj=0.5) legend("topleft", c("Mosquitos", "Temperatura", "POM"), bty="n", pch = c(21,NA,NA), lty=c(1,1,3), lwd=c(2,1,2)) rug(12,5,ticksize=1,side=3, lwd=3, col="red") box(which=”outer”) par("cra","din")
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
96
5
10
15
6 4 3 POM 1 0
2
5 0
0
10
20
10
15 Temperatura
Mosquitos 30 40
20
50
5
Mosquitos Temperatura POM 25
60
30
Eclosión de larvas de mosquito
20
Mes
II.16. Formas especiales Otro aspecto interesante relativo al formato de los gráficos es la posibilidad de añadir elementos como polígonos y flechas, o texto en los márgenes. Para esto, utilizaremos como ejemplo un plano en el que se muestran las isoclinas de un modelo de competencia interespecífica de Lotka–Volterra. Las instrucciones están en el archivo II.32.R. En primer lugar crearemos un panel gráfico con los márgenes externos un poco mayores de lo habitual, para dejar sitio al texto marginal. Para esto utilizamos la función «par()», que permite ajustar parámetros gráficos, y modificamos el argumento «oma», que indica los valores de cada margen mediante un vector. Después creamos un gráfico usando la función «plot()», etiquetando los ejes en blanco. Además, no queremos que se representen los valores de las coordenadas en los ejes y, para ello, utilizamos los argumentos «xaxt» y «yaxt» con valor «"n"».
¾ par(oma=c(3,3,3,3)) ¾ plot(0,0,xlim=c(0,1),ylim=c(0,1),xlab="",ylab="",xaxt="n",yaxt="n",type= "n",main="Isoclinas de crecimiento 0",font.main=2) Ahora, mediante la función «mtext()» añadiremos texto a los márgenes. Dentro del paréntesis indicamos, en primer lugar, el texto que deseamos escribir. En este caso se trata de texto con expresiones matemáticas. Ya hemos visto anteriormente un ejemplo similar. Además indicamos el margen en el que deseamos escribir el texto (1 indica inferior, 2 indica izquierdo), la línea (contando
GRÁFICOS BÁSICOS
97
desde el recuadro del gráfico) en la que se desea añadir el texto, y con el argumento «at», la coordenada del gráfico a la altura de la cual queremos escribir el texto. Para localizar las coordenadas más adecuadas, resulta útil la función «locator()», que ya hemos visto, y que nos proporciona las coordenadas de cualquier punto que marquemos en el gráfico. El argumento «las», por último, indica mediante un código la orientación del texto que escribiremos.
¾ ¾ ¾ ¾ ¾ ¾
mtext(expression(K[1]),2,1,at=0.76,las=1) mtext(expression(frac(K[2],alpha[12])),2,1,at=0.53,las=1) mtext(expression(K[2]),1,1,at=0.78,las=1) mtext(expression(frac(K[1],alpha[21])),1,2,at=0.5,las=1) mtext(expression(N[1]),2,1,at=1,las=1) mtext(expression(N[2]),1,1,at=1,las=1)
A continuación nos interesa pintar en diferentes colores las distintas regiones del gráfico delimitadas por estas isoclinas. Para esto podemos utilizar la función «polygon()», que nos permite dibujar un polígono y colorearlo o rellenarlo con diferentes tramas. Dibujaremos un polígono para cada región. A esta función es necesario indicarle las coordenadas de cada vértice, lo cual se puede hacer de diferente forma según el caso. Aquí, para definir bien los límites de cada polígono, cuando estos estén definidos por las líneas de las isoclinas, es bueno marcar con «locator()» encima de las isoclinas. Cuando dibujemos el polígono éstas desaparecerán, ocultas por el límite del polígono. Luego se pueden volver a dibujar y los polígonos quedarán perfectamente delimitados, sin espacios en blanco. Además de las coordenadas, la función «polygon()» tiene más argumentos: en este caso definimos diferentes colores de relleno, sin trama, y no queremos dibujar bordes.
¾ polygon(x=c(-0.038,-0.038,1.039,1.039,0.78,0.255),y=c(0.753,1.038,1.038, -0.039,-0.039,0.325),col="gray88",border=NA) ¾ polygon(x=c(-0.038,-0.038,0.255),y=c(0.525,0.751,0.325),col="gray77", border=NA) ¾ polygon(x=c(0.255,0.78,0.494),y=c(0.325,-0.039,-0.039),col="gray77", border=NA) ¾ polygon(x=c(-0.038,-0.038,0.255,0.494),y=c(-0.039,0.525,0.325,-0.039), col="gray66",border=NA) Se representan las isoclinas de crecimiento 0, que definen las regiones del plano en las cuales se observa coexistencia, o dominancia de una u otra especie.
¾ abline(0.5,-0.7); abline(0.7,-1.5) Nos interesa dibujar flechas que indiquen la dirección de la resultante a la que tienden las densidades de población en cada región. En este caso todas tienden, si están más o menos centradas, al punto de equilibrio estable definido por el cruce de ambas isoclinas. Las flechas se dibujan con la función «arrows()», a la que debemos indicar las coordenadas de inicio y de fin. Además le indicamos el tamaño de la punta de la flecha, y también un grosor de línea determinado.
¾ arrows(0.04,0.08,x1=0.15,y1=0.2,length=0.1,lwd=3)
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
98
¾ arrows(-0.009,0.6,x1=0.075,y1=0.51,length=0.1,lwd=3) ¾ arrows(0.57,0.015,x1=0.48,y1=0.1,length=0.1,lwd=3) ¾ arrows(0.53,0.63,x1=0.4,y1=0.48,length=0.1,lwd=3) Con la función «arctext()» del paquete “plotrix” (Lemon, 2012) se puede escribir el texto en curva. El argumento «center» especifica las coordenadas x e y que se tomarán como centro del texto. Con «radius» se especifica el radio de la circunferencia. El argumento «start» define donde se comienza a escribir en radianes. Con «stretch» se define el espacio entre letras en el texto y con «middle» la posición del centro del texto en radianes.
¾ library(plotrix) ¾ arctext("Punto de equilibrio",center=c(0.26,0.32), radius=0.075, start=pi/2, stretch=1.25, middle=pi/2, cex=1) También es posible hacer flechas en círculos con la función «selfarrow()» del paquete “diagram” (Soetaert, 2012). Hay que especificar las coordenadas de origen con «pos». Con «path» se define la posición del círculo: «R» (derecha), «L» (izquierda), «U» (arriba) y «D» (abajo). Con «arr.pos» se especifica la posición relativa de la punta de la flecha (de 0 a 1) y con «arr.type» el tipo de punta de flecha («simple», «triangle», «curved», «circle», «ellipse» o «T»). El argumento «curve» define el tamaño relativo de la curva.
¾ library(diagram) ¾ selfarrow(c(0.14,0.32), path = "R", arr.pos = 0.2,lty= 1, lwd=5, lcol="red", arr.col="blue", arr.type="curved", curve = c(0.12, 0.12),) Isoclinas de crecimiento 0 N1
K1
K2
P un to d e
i l ib rio
D 12
K1 D 21
K2
N2
equ
GRÁFICOS BÁSICOS
99
II.17. Gráficos combinados En el archivo II.33.R están las instrucciones para ver un ejemplo de cómo combinar diferentes tipos de gráficos. Los datos que se usarán, que están en el archivo Población.csv, son la estructura de edad de la población española, hombres y mujeres, de los años 1900 y 1991. Después de importar los datos y cargarlos en la memoria, se asignan las variables que queremos representar a los objetos «x» e «y»; en este caso se utilizan los datos del año 1900. Se calculan los máximos y mínimos para saber los límites de los ejes en los gráficos. A continuación, con la instrucción «matrix()», se crea un matriz de 2x2 con las posiciones donde se colocarán las figuras conforme se vayan creando. Con «layout()» se divide la pantalla en el número de columnas y filas que deseamos y el valor z nos indica la posición de cada una de las figuras. Con «par(mar)» se definen los márgenes de cada uno de los gráficos. Si en vez de líneas se quiere dar los márgenes en pulgadas, se debe usar «par(mai)». En primer lugar se crea un gráfico de dispersión que representa el número de mujeres frente al número de hombres, para cada clase de edad. Posteriormente se crean dos gráficos de barras con la función «barplot()». Dentro de esta función el argumento «names.arg» permite identificar la variable que se usará para las etiquetas que se ponen en la base de las barras, con «las=2» se especifica que se pongan en posición vertical y con «axes=TRUE» que se dibujen los ejes. En el último gráfico, que representa la estructura de edad de los hombres, se indica con «horiz=TRUE» que las barras son horizontales y no verticales.
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
Datos<-read.csv2("Población.csv", header=TRUE, encoding="latin1") attach(Datos) x<-M.1900 y<-H.1900 maxx<-max(x) maxy<-max(y) z<-matrix(c(2,0,1,3),2,2,byrow=TRUE) z layout(z,widths=c(3,1), heights=c(1,3), respect=TRUE) par(mar=c(5,5,1,1)) plot(x, y, xlim = c(0,maxx), ylim = c(0,maxy), xlab= "Nº mujeres", ylab= "Nº > hombres", cex.lab=1.5, pch=15) text(200000,1e6,"1900", cex=2, font=2) par(mar=c(3,5,1,1)) barplot(x, ylim = c(0,maxx), axes= TRUE, names.arg = Edad, las=2) par(mar=c(5,3,1,1)) barplot(y,xlim=c(0,maxy),axes=TRUE,names.arg=Edad,horiz=TRUE,las=2)
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
100 1e+06 8e+05 6e+05 4e+05
> 85
80 a 84
75 a 79
70 a 74
65 a 69
60 a 64
55 a 59
50 a 54
45 a 49
40 a 44
35 a 39
30 a 34
25 a 29
20 a 24
15 a 19
10 a 14
<5
5a9
2e+05 0e+00
1e+06
1900
> 85 80 a 84 75 a 79 65 a 69 60 a 64
6e+05
55 a 59 50 a 54 45 a 49 40 a 44 35 a 39
4e+05
Nº hombres
8e+05
70 a 74
30 a 34 25 a 29
2e+05
20 a 24 15 a 19 10 a 14
0e+00
5a9
2e+05
4e+05
6e+05
8e+05
Nº mujeres
1e+06
4e+05 6e+05 8e+05 1e+06
0e+00
0e+00 2e+05
<5
II.18. Gráficos dentro de gráficos Con las instrucciones «par(new=T,omd=c(x1,x2,y1,y2))» es posible insertar fácilmente gráficos dentro de otros gráficos. Los valores x1, x2, y1 e y2 solo pueden ser entre 0 y 1, e indican la posición relativa de la figura dentro del panel. El argumento «par(omi=c(x1,x2, y1,y2))» indica lo mismo pero en pulgadas. Por ejemplo, usando de nuevo los datos de la longitud estándar y base de la aleta dorsal de varias especies de peces de la familia Carangidae, que están en el archivo Carangidae.csv, con las instrucciones del script II.34.R, se representa la relación entre dos variables y luego se inserta un histograma de cada una para averiguar si la distribución es Normal.
¾ Datos<-read.csv2("Carangidae.csv", header=TRUE, encoding="latin1") ¾ attach(Datos) ¾ plot(Longitud, Dorsal, xlim=c(0,700), ylim=c(0,400), xlab="Longitud estándar (mm)", cex.lab=1.6, font.lab=2, ylab="Base aleta dorsal (mm)", main="Especies de la familia Carangidae",cex.main=2.0, font.main=2) ¾ par(new=T, omd=c(0,0.6,0.55,1))
GRÁFICOS BÁSICOS
101
¾ hist(Dorsal, breaks = length(Longitud), main="", xlim=c(0,400), xlab="", ylab="", cex.lab=1, font.lab =1,freq=FALSE, yaxt="n") ¾ lines(density(Dorsal,na.rm=TRUE),lwd=2,col="red") ¾ mtext("Base aleta dorsal (cm)",1,line=2,font=2) ¾ par(new=T, omd=c(0.39,0.99,0.1,0.55)) ¾ hist(Longitud, breaks=length(Longitud), main="", xlim=c(0,800), xlab="", ylab= "", cex.lab=1,font.lab =1,freq=FALSE, yaxt="n") ¾ lines(density(Longitud,na.rm=TRUE),lwd=2,col="red") ¾ mtext("Longitud estándar (cm)",1,line=2,font=2)
300
100 200 300 Base aleta dorsal (cm)
400
200
0
100
Base aleta dorsal (mm)
400
Especies de la familia Carangidae
0
0
0
100
200
300
200 400 600 Longitud estándar (cm) 400
500
600
800
700
Longitud estándar (mm) Otra opción específica para insertar gráficos dentro de otros gráficos es la función «subplot()» del paquete “Hmisc” (Harrell, 2012). Las instrucciones están en el script II.35.R y los datos, que están en el archivo Temperatura.csv, corresponden a datos de temperatura en un lago tomados cada media hora durante varios meses. En la primera parte del script, con la función «aggregate()» se obtienen los valores medios de la temperatura para cada día. Posteriormente, con la función «order()» se ordenan los datos por fechas y con «format="%d/%m/%Y"» se especifica el formato de fecha que hay en la matriz de datos. A la matriz creada se le añaden las etiquetas de las columnas con «colnames()» y luego se elimina la primera columna que se crea automáticamente con la instrucción
102
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
«rownames(datos2)<-NULL», quedando la matriz de datos como se muestra a continuación.
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
library(Hmisc) datos<-read.csv2("Temperatura.csv", header=TRUE, encoding="latin1") datos<-na.exclude(datos) attach(datos) datos1<-aggregate(datos[ , c("Temperatura")], na.rm=TRUE, by= list(Fecha=Fecha), mean) datos2<-datos1[order(as.Date(datos1$Fecha, format = "%d/%m/%Y")),] colnames(datos2)<-c("Fecha","Temperatura") rownames(datos2)<-NULL datos2
En la siguiente parte del script se genera el gráfico principal donde se representa solamente la temperatura media diaria del archivo «datos2» creado anteriormente, sin especificar el eje x. El argumento «xaxt="n"» indica que no se representen los intervalos del eje x. Con la función «axis()» añadimos un eje x, indicado por el valor 1, y con «seq(0, 50, by=10)» se define que las marcas en el eje x sean de 0 a 50 a intervalos de 10 días. Con «labels» se especifican los nombres de las etiquetas de las marcas.
¾ windows(11,7) ¾ plot(datos2$Temperatura, type="b", pch=16, col="blue", cex=1.5, xaxt="n", cex.main=1.6, xlab="Días",cex.lab=2, cex.axis=1.5, ylab="", main= "Temperatura media diaria en el lago Yahuarkaka (Leticia, Amazonas)") ¾ mtext("Temperatura",2, line=2.5,cex=2) ¾ axis(1, at=seq(0,50,by=10), labels=c("19/3/2006", "29/3/2006", "8/4/2006", "18/4/2006", "28/4/2006", "8/5/2006"), cex.axis=1.5) Finalmente, se generan 3 gráficos con la función «subplot()», cada uno de los cuales representa el ciclo diario de temperatura en diferentes días. Para ello se selecciona previamente el día y luego dentro de la función «subplot()» se genera cada uno de los gráficos con «plot()». Dentro de «subplot()» se especifican las coordenadas donde se ubica el gráfico interno con «x» e «y». Con «size» se indica el tamaño del gráfico interior y los argumentos «vadj» y «hadj» permiten definir el ajuste vertical y horizontal del gráfico, respectivamente. Un valor 0 significa que se ajusta a la izquierda y 1 a la derecha en «hadj». El valor 0 significa abajo y 1 arriba en el caso de «vadj». Por tanto, un valor de 0,5 es centrado en ambos casos.
GRÁFICOS BÁSICOS
103
¾ G1<-datos[Fecha=="29/03/2006",] ¾ subplot(plot(G1$Hora,G1$Temperatura,type="b",pch=17, col="red", cex=1, ylab="", xlab="",bty="l",cex.axis=1,xaxp=c(0,30,5)), x=10, y=27.35, size=c(1.5,1.5), vadj=0.5, hadj=0.5) ¾ text(10, 26.55, "Hora del día") ¾ text(2.4, 27.3, "Temperatura",srt=90) ¾ G2<-datos[Fecha=="25/04/2006",] ¾ subplot(plot(G2$Hora,G2$Temperatura,type="b",pch=17, col="red", cex=1, ylab="", xlab="",bty="l",cex.axis=1,xaxp=c(0,30,5)), x=37, y=28.9, size=c(1.5,1.5), vadj=0.5, hadj=0.5) ¾ text(37, 28.1, "Hora del día") ¾ text(29.4, 28.85, "Temperatura",srt=90) ¾ G3<-datos[Fecha=="09/05/2006",] ¾ subplot(plot(G3$Hora,G3$Temperatura,type="b",pch=17, col="red", cex=1, ylab="", xlab="", bty="l", cex.axis=1,xaxp=c(0,30,5)), x=51, y=28, size=c(1.5,1.5), vadj=0.5, hadj=0.5) ¾ text(51, 27.2, "Hora del día") ¾ text(43.4, 27.95," Temperatura",srt=90)
Temperatura 29.5 30.5
26.5 19/3/2006
6 12 18 Hora del día
Temperatura 26.2 26.6 27.0
28.5
0
6 12 18 Hora del día
28.5
27.5
28.0
0
27.0
Temperatura
29.0
Temperatura 27.2 27.6 28.0
Temperatura media diaria en el lago Yahuarkaka (Leticia, Amazonas)
0
6 12 18 Hora del día
29/3/2006
8/4/2006
18/4/2006
28/4/2006
8/5/2006
Días
II.19. Ampliación de un área dentro de un gráfico La función «zoomInPlot()» del paquete “plotrix” (Lemon, 2012) permite ampliar un rango de valores dentro de un gráfico. Como ejemplo usaremos los datos, que están en el archivo Clima.csv, de temperatura del agua y del aire, y la intensidad del viento de este a oeste (Viento.X) y de sur a norte (Viento.Y) a
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
104
42º norte y 10º oeste, desde 1925 hasta 1997. Las instrucciones están en el script II.36.R. Después de cargar el paquete e importar los datos, con la función «zoomInPlot()» se representa la relación entre las temperaturas del agua y del aire. Los argumentos «rxlim» y «rylim» definen el rango de datos que se amplia, en este ejemplo de 12 a 14 ºC. Con «xend» se define donde finalizan las proyecciones que señalan el comienzo del gráfico ampliado. Si se pone «xend=NA» las proyecciones finalizan justo donde comienza el eje x del gráfico ampliado. Con los argumentos «zoomtitle» y «titlepos» se especifica el título y su posición en el panel gráfico, respectivamente.
¾ ¾ ¾ ¾
library(plotrix) datos<-read.csv2("Clima.csv",header=TRUE,encoding="latin1") attach(datos) zoomInPlot(Temperatura.agua,Temperatura.aire, xlim=c(10,20), ylim=c(10, 20), rxlim=c(12,14), rylim=c(12,14), xend=NA, xlab="Temperatura del agua (ºC)", ylab="Temperatura del aire (ºC)", zoomtitle="Ampliación en el rango de 12 a 14 ºC", titlepos=11.3, pch=2, col="blue")
13.5 12.5
13.0
Temperatura del aire (ºC)
16 14 10
12.0
12
Temperatura del aire (ºC)
18
20
14.0
Ampliación en el rango de 12 a 14 ºC
10
12
14
16
18
20
Temperatura del agua (ºC)
12.0
12.5
13.0
13.5
14.0
Temperatura del agua (ºC)
II.20. Gráficos con intervalos en los ejes Las funciones «gap.plot()», «gap.barplot()» y «gap.boxplot()» del paquete “plotrix” (Lemon, 2012) permiten incluir saltos en la escala de los ejes de los gráficos de puntos, de barras y de cajas, respectivamente. Las instrucciones
GRÁFICOS BÁSICOS
105
están en el script II.37.R y como ejemplo se usan datos de metales en sedimentos a distintas profundidades del lago Yahuarkaka (Leticia, Colombia), que están en el archivo Sedimentos.csv (Cotes, 2011). El argumento «gap» permite incluir todos los intervalos que se deseen; en este caso no se representan los valores en el eje y en los intervalos 51-99 y 151-199 cm de profundidad. Al ejecutar el script sale un mensaje de aviso de que hay datos que no se representan debido a los intervalos que se han seleccionado. Con «gap.axis» se define en que eje se realiza el intervalo. Con «bgcol» y «breakcol» se definen los colores de relleno y del marco del intervalo, respectivamente. Con «brw» se define el tamaño relativo del intervalo. Por último, con «ytics» y «xtics» se especifica qué marcas de los ejes se muestran.
¾ ¾ ¾ ¾
library(plotrix) datos<-read.csv2("Sedimentos.csv",header=TRUE,encoding="latin1") attach(datos) gap.plot(Al,Profundidad, gap=c(51,99,151,199), gap.axis="y", type="b", lty=2, pch=16, col="red", bgcol="blue", breakcol="white", brw=0.1, xlab="Concentración del metal", ylab = "Profundidad (cm)", ytics=c(0,50, 150,250,300), xtics = c(0,20,40,60,80,100), xlim=c(0,100), cex.lab=1.7) ¾ gap.plot(Cr, Profundidad, gap=c(51,99,151,199), gap.axis="y", type="b", lty=1, pch=17, col="green", bgcol="blue", breakcol="white", brw=0.1, xlab="Concentración del metal", ylab = "Profundidad (cm)", ytics=c(0,50, 150,250,300),xtics=c(0,20,40,60,80,100),xlim=c(0,100),cex.lab=1.7, add=T) ¾ legend("topleft",c("Aluminio","Cromo"),pch=c(16,17),col=c("red","green"))
250 150 50 0
Profundidad (cm)
300
Aluminio Cromo
0
20
40
60
80
Concentración del metal
100
106
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
II.21. Paquetes que permiten realizar varios tipos de gráficos básicos Hay algunos paquetes en R que tienen un formato de ventanas, con diferentes menús, que permiten realizar algunos de los gráficos mostrados anteriormente.
II.21.1. R COMMANDER R commander es una Interfaz Gráfica de Usuario (GUI) que facilita considerablemente el uso de R. Contiene un menú que permite –de forma similar a otros programas estadísticos– realizar de modo sencillo la mayoría de las operaciones estadísticas habituales, y separa las instrucciones y resultados en dos ventanas diferentes. Para utilizar R Commander hay que instalar el paquete “Rcmdr” (Fox 2005; 2007; Fox y col., 2012). En general, al mismo tiempo se instalan automáticamente todos los paquetes dependientes o complementarios necesarios para un funcionamiento correcto. Normalmente cuando se arranca por primera vez instala más paquetes, que son necesarios para que funcione. Los diseñadores de R Commander trataron de incluir en él todas las técnicas contenidas en un curso básico de Estadística, añadiendo posteriormente algunas otras técnicas de uso común, pero después han preferido mantener su estructura simple en lugar de seguir añadiendo técnicas en un menú crecientemente complejo que intente cubrir todos los métodos. Posteriormente han surgido nuevos paquetes que se incorporan como opciones de menú complementarias o extensiones de R Commander, de gran utilidad para usuarios que reclaman técnicas específicas en el menú, los cuales solo deben instalar el paquete adicional (plug-in package) de su interés, como por ejemplo “FactoMineR” (véase Guisande y col., 2011). La mayoría de los paquetes plug-in de R Commander empiezan por “RcmdrPlugin.”, como por ejemplo “RcmdrPlugin.MAd” para Meta-análisis, “RcmdrPlugin.epack” para series temporales, “RcmdrPlugin.qual” para control de calidad, “RcmdrPlugin.survival” para análisis de supervivencia, o “RcmdrPlugin.DoE” para diseño de experimentos industriales. Las opciones de menú de R Commander conducen en general a cuadros de diálogo que permiten incorporar a las instrucciones todas las variables y opciones necesarias en cada aplicación, de manera que el usuario de R no necesita conocer ni utilizar el lenguaje de programación. La estructura de los cuadros de diálogo es simple y clara, y a menudo no necesita explicación alguna. Habitualmente incluye un botón de ayuda que remite a la documentación de R sobre la función que se quiere utilizar. La principal ventaja de R Commander es que el usuario puede realizar casi todas las operaciones estadísticas de tratamiento de datos sin conocer en absoluto el complejo lenguaje de programación. R Commander se encarga de construir las órdenes a partir del menú, como lo hacen otros programas estadísticos (SPSS, Statística, SAS, etc.). Incluso para aquellos que conocen a fondo el lenguaje de R resulta a menudo más cómodo y rápido utilizar R Commander. Las limitaciones de R Commander consisten en que muchas técnicas estadísticas no están en el menú (solo las más habituales), y que algunas opciones de las técnicas incluidas no se pueden aplicar desde el menú. El conocimiento del lenguaje de programación de R permite multiplicar la potencia estadística y mejorar
GRÁFICOS BÁSICOS
107
los resultados y su presentación, para lo cual se pueden modificar convenientemente las órdenes generadas inicialmente por R Commander. Para iniciar R Commander tecleamos –recuerde que en R siempre es necesario respetar las mayúsculas– la instrucción siguiente en la consola de R (RGui):
¾ library(Rcmdr) También es posible iniciar R Commander en el menú «Paquetes» Ö «Cargar paquete…», y en la ventana que aparece se selecciona «Rcmdr».
108
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Cuando se utiliza el menú de R Commander, el programa genera las instrucciones adecuadas, que se muestran en la «Ventana de instrucciones». También aparecen las instrucciones junto con los resultados producidos en la «Ventana de resultados». El usuario puede acceder a cualquiera de ellas para observar, copiar resultados o instrucciones, o modificar y ejecutar de nuevo cualquier instrucción (con el botón «Ejecutar»), de un modo mucho más interactivo que con el RGui. Es más, cualquier instrucción o conjunto de instrucciones que podamos construir en RGui puede ser también generalmente realizada en la ventana de instrucciones de R Commander. La separación de instrucciones y resultados en ventanas diferentes es muy conveniente para una mejor organización de todos los elementos de la aplicación estadística. Además R Commander muestra una tercera ventana de «Mensajes», en la que advierte de cualquier error o problema en la aplicación. Los mensajes se numeran correlativamente, y pueden ser borrados en cualquier momento para evitar confusión e identificar más claramente los mensajes nuevos. Veamos el siguiente ejemplo, cuyas instrucciones las introducimos en la «Ventana de instrucciones». Después de seleccionarlo todo y pulsar Ejecutar aparecen las instrucciones junto con los resultados producidos en la «Ventana de resultados». El gráfico aparece en la ventana principal de R.
¾ ¾ ¾ ¾ ¾ ¾
#Ejemplo de archivo de instrucciones (Script) #Introducir los datos en R desde una instrucción X<-c(34,47,56,3,78,36,56,23,14) Y<-c(36,41,55,4,75,38,58,21,16) #Gráfico que relaciona ambas variables plot(X,Y)
Antes de poder utilizar el menú para realizar algún gráfico es necesario cargar los datos como se muestra en la siguiente ventana. La opción «Nuevo conjunto de datos», sirve para introducir un conjunto de datos directamente (esto es útil cuando el conjunto de datos es pequeño); también se puede «Cargar un conjunto de datos» en formato R; «Fusionar conjuntos de datos»; «Importar datos» desde archivo de texto o portapapeles, o desde otros programas estadísticos (SPSS, Minitab, STATA….), o desde Excel, Access o dBase.
GRÁFICOS BÁSICOS
109
También se puede seleccionar el «Conjunto de datos activo», o «Modificar las variables del conjunto de datos activo» (recodificar, calcular una nueva variable, tipificar, convertir, segmentar, reordenar, renombrar, eliminar, ...). Las instrucciones se ejecutan sobre el conjunto de datos activo. Cuando existen varios, lo cual es muy habitual, debe definirse cuál es el activo para que el menú de R Commander se refiera siempre a él. Por ejemplo, supongamos que tenemos dos series de datos, vamos a «Datos» Ö «Conjunto de datos activo» Ö «Seleccionar conjunto de datos activo…», y en la ventana que aparece se selecciona la serie de datos con la que se quiera trabajar.
A modo de ejemplo vamos a utilizar datos de pigmentos de algas que están en el archivo PigAlgas.xls. Lo mejor para R Commander es usar archivos de Excel 2003 (extensión “xls”). En el menú se selecciona «Datos» Ö «Importar datos» Ö «desde conjunto de datos Excel, Access o dBase».
110
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Aparece un pequeño cuadro de diálogo para introducir el nombre del conjunto de datos, en el que dejamos el nombre por defecto «Datos» y pulsamos «Aceptar». Posteriormente aparecen los archivos del directorio de trabajo, en el que elegimos PigAlgas.xls y pulsamos «Abrir».
En R Commander pulsamos en «Visualizar conjunto de datos». Es importante inspeccionar los datos y comprobar que no existan líneas vacías, que contienen exclusivamente el código
. Si existen estas líneas, hay que eliminarlas.
En lo que se refiere al menú de gráficos, hay varios tipos que son los más básicos y de uso más frecuente: secuencial (para series temporales), histograma (para variables continuas), de tallo y hojas, diagrama de cajas, diagrama de dispersión (para ver la relación entre dos variables cuantitativas), gráfica de líneas, de barras, de sectores (para variables cualitativas), gráficos 3D, etc. Vamos a hacer un ejemplo con un diagrama de caja.
GRÁFICOS BÁSICOS
111
En la nueva ventana se selecciona la variable «Chlorophyll.a.epimer» y pulsamos en «Gráfica por grupos…».
Se selecciona «Especies» y después de pulsar «Aceptar» dos veces se obtiene el gráfico.
El gráfico es sencillo, y ya se vió anteriomente que se puede mejorar su presentación, por ejemplo poniendo colores a las barras. Para ello sería necesario introducir las instrucciones sobre el código que aparece en la ventana superior de R Commander y, después de seleccionar las instrucciones, pulsar el botón «Ejecutar» o ctrl-R.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
0.03 0.02 0.00
0.01
Chlorophyll.a.epimer
0.04
0.05
112
Cianofíceas
Clorofíceas
Criptofíceas
Diatomeas
Dinofíceas
Especies
II.21.2. GrapheR El paquete “GrapheR” (Hervé, 2011; 2012) es una interfaz que permite al usuario dibujar gráficos sin tener conocimientos de R y que usa la plataforma GUI. Se pueden hacer seis tipos de gráfico: histogramas, de caja, barras, circulares, curvas y gráficos de dispersión. Una vez instalado el paquete y seleccionado el directorio de trabajo, para poder usar el paquete hay que introducir las siguientes instrucciones en la ventana principal de GUI:
¾ library(GrapheR) ¾ run.GrapheR()
GRÁFICOS BÁSICOS
113
En la ventana que aparece, al pulsar el botón «data» se accede al menú donde se puede indicar el tipo y características del archivo de datos que vamos a importar. En este caso se especifica que es un archivo de tipo csv, con los decimales separados por comas y las columnas por semicolon.
Después de pulsar «Load» abrimos el archivo Clima España.csv, que contiene datos climáticos de diferentes ciudades de España. Como se observa en la ventana, es posible realizar diferentes modificaciones en los datos una vez cargados y también obtener información básica de cada una de las variables como el mínimo, máximo, la media, etc.
114
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Vamos a representar dos gráficos y, para ello, pulsamos el botón «window» donde obtenemos la siguiente ventana en la que seleccionamos dos gráficos en dos filas. Hay que pulsar «OK» para que se haga efectiva la orden.
Posteriormente, pulsamos en el botón «Draw a scatter plot» y representamos la temperatura máxima frente a la mínima, seleccionando «Ciudad» como factor opcional y marcando las tres ciudades. En el menú se observa que es posible modificar el color y tamaño de los símbolos, la leyenda de los ejes, el título del gráfico, etc.
GRÁFICOS BÁSICOS
115
Una vez hemos acabado de introducir las modificaciones para obtener el formato deseado, se pulsa en el botón «DRAW» para obtener el gráfico, el cual aparece en una ventana creada. Es posible hacer cualquier modificación y volver a pulsar «DRAW» para obtener el nuevo gráfico. Es importante tener claro en que posición lo queremos dentro de la ventana, si arriba o abajo antes de realizar el segundo gráfico, ya que todos los parámetros introducidos para realizar este gráfico de dispersión se pierden al iniciar al cuadro de diálogo del siguiente. Para hacer el segundo gráfico pulsamos «Draw a bar plot». En la nueva ventana introducimos las variables a representar: «T.Media» y el factor «Ciudad». Posteriormente podemos introducir el título, la leyenda de los ejes, cambiar el tamaño de la leyenda, el color y trama de las barras, el color de los bordes de la barras, el tipo de error de las barras (en este ejemplo se selecciona la desviación estándar), etc. Los límites del eje se han puesto de 0 «Lower limit:» a 36 «Upper limit:», para dejar espacio arriba para poder añadir posteriormente texto. Al igual que antes pulsamos el botón «DRAW» para obtener el gráfico.
116
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Si se pulsa en el botón «p-val», aparece una ventana adicional que permite añadir texto para comparar dos o más barras. En el ejemplo hemos aplicado previamente una prueba estadística de comparación de grupos, y añadiremos al gráfico el valor p calculado, que indica si existe o no diferencia significativa en la temperatura media entre ciudades. Introducimos el texto que deseamos incluir «p = 0,309» y después de pulsar en «Select», se pulsa en el gráfico con el ratón en las dos barras a comparar, en el primer caso entre las ciudades de Huelva y Mallorca. Luego se repite el proceso, es decir, se pone de nuevo otro texto «p < 0,001» y al pulsar «Select», se marca con el ratón las ciudades de Palma de Mallorca y Vigo, entre las que hay diferencias significativas en la temperatura media.
Se obtiene el segundo gráfico, que se muestra a continuación junto con el primer gráfico de dispersión. En el gráfico de barras es posible que dé un aviso de error si no se hubiese dejado espacio suficiente por arriba en el eje y. En ese caso se puede hacer cualquier modificación en el gráfico, pulsar en el botón «DRAW», y de nuevo se intenta hacer el proceso de seleccionar las barras para añadir el texto. Sin embargo, es muy importante tener en cuenta lo mencionado anteriormente, si pulsamos el botón «DRAW» otra vez podemos perder el gráfico realizado de dispersión. Lógicamente en el caso de estar trabajando con un solo gráfico y no tener una ventana con varios gráficos, no hay problema en pulsar «DRAW» tantas veces como se quiera hasta obtener el gráfico deseado.
GRÁFICOS BÁSICOS
117
40 10
20
30
Huelva Palma de Mallorca Vigo
0
Temperatura mínima (ºC)
Temperaturas máxima y mínima en ciudades de España
0
10
20
30
40
Temperatura máxima (ºC)
30
p =0,309
5 10
20
p < 0,001
0
Temperatura media (ºC)
Temperatura media en ciudades de España
Huelva
Palma de Mallorca
Vigo
II.22. Representaciones interactivas para páginas web La Aplicación de Interface de Programación (API) de visualización de Google permite realizar representaciones dinámicas, las cuales se pueden incorporar a páginas web. El paquete “googleVis” (Gesmann y de Castillo, 2011; 2012) proporciona una interfaz entre R y la API de visualización de Google. Es necesario tener conexión a internet.
II.22.1. GRÁFICOS En el archivo Banco mundial.csv hay datos obtenidos de la página web http://datos.bancomundial.org/, donde se puede observar el porcentaje de po-
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
118
blación y de desempleados para diferentes edades, así como la población total y el número de mujeres, en diferentes regiones del mundo. Las instrucciones están en el script II.38.R. La función «gvisMotion()» del paquete “googleVis” (Gesmann y de Castillo, 2011; 2012) prepara objetos que luego pueden ser representados en forma de gráficos dinámicos en páginas web. Con el argumento «idvar» se especifica la variable de identificación, en este caso las diferentes regiones. Con «timevar» se define la variable que contiene la información de tiempo. Existe otro argumento «date.format="%Y/%m/%d"», que permite definir el formato del tiempo, en el caso de que no fueran años.
¾ ¾ ¾ ¾
library(googleVis) datos<-read.csv2("Banco mundial.csv",header=TRUE,encoding="latin1") G <- gvisMotionChart(datos, idvar = "Region", timevar = "Year") plot(G)
En la gráfica que se obtiene hay diferentes opciones, las cuales se explican sobre la propia gráfica. Es posible también seleccionar una zona con el ratón y entonces se obtendrá una ampliación. Aparecerá una pantalla a la derecha donde de nuevo es posible reducir. En las siguientes representaciones se cambia de gráfico y se seleccionan diferentes regiones Diferentes gráficos
Escala logarítmica o lineal
Variable indicadora del color
Variable indicadora del tamaño Selección variable eje y
Selección de variable Si alguna variable está seleccionada, se sigue su ruta en la animación Escala logarítmica o lineal Herramientas avanzadas
Cursor para ver diferentes años
Play para animación Velocidad de animación
Selección variable eje x
GRÁFICOS BÁSICOS
119
120
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
La función «gvisAnnotatedTimeLine()» del paquete “googleVis” (Gesmann y de Castillo, 2011; 2012) permite representar series temporales. En el archivo Mareas.csv hay datos del ángulo entre el sol y la luna, y la diferencia en metros entre pleamar y bajamar, para 42º 8´Norte y 14º 13´Oeste, del 1/1/2004 al 14/3/2004. Las instrucciones están en el script II.39.R. En el argumento «datevar» se introduce la variable que tiene los datos de las fechas. En «numvar» la variable a representar. En «idvar» se podría poner una variable identificativa, de tal forma que habría tantas series temporales como grupos tuviese esa variable. El argumento «titlevar» permite poner una variable con eventos, que en este ejemplo son las diferentes fases de la luna. Con el argumento «options» es posible introducir modificaciones en el gráfico, las cuales se pueden consultar en el menú de ayuda de la función.
¾ library(googleVis) ¾ datos<-read.csv2("Mareas.csv",header=TRUE,encoding= "latin1",fill=TRUE) ¾ G2 <- gvisAnnotatedTimeLine(datos, datevar="Fecha", numvar= "Angulo.Sol.Luna", idvar= "", titlevar="Fase", options= list(displayAnnotations=TRUE, legendPosition='newRow', width=1000, height=500)) ¾ plot(G2)
II.22.2. TABLAS Las tablas se realizan con la función «gvisTable()» del paquete “googleVis” (Gesmann y de Castillo, 2011; 2012). En el script II.40.R se muestra como generar tablas interactivas para páginas de internet usando de nuevo el archivo de Banco mundial.csv.
GRÁFICOS BÁSICOS
121
En la función «gvisTable()», con el argumento «options» es posible introducir modificaciones en la tabla, las cuales se pueden consultar en el menú de ayuda de la función.
¾ T <- gvisTable(datos,options = list(width = 1000, height = 500, page= "enable")) ¾ plot(T)
II.22.3. COMBINACIÓN DE REPRESENTACIONES La función «gvisMerge()» del paquete “googleVis” (Gesmann y de Castillo, 2011; 2012) permite combinar gráficos, tablas y/o mapas en una sola pantalla. Los mapas interactivos los estudiaremos en el Capítulo IV, y en este apartado realizaremos la integración de gráficos y tablas utilizando los datos del archivo Banco mundial.csv del ejemplo anterior. Las instrucciones están en el archivo II.41.R. Después de generar el gráfico y la tabla, como se explicó anteriormente, ambos se integran en un mismo dispositivo con «gvisMerge()». El argumento «horizontal=FALSE» significa que se pongan en la misma columna, en diferentes filas.
¾ ¾ ¾ ¾
library(googleVis) datos<-read.csv2("Banco mundial.csv",header=TRUE,encoding="latin1") G <- gvisMotionChart(datos, idvar = "Region", timevar = "Year") T <- gvisTable(datos,options = list(width = 500, height = 250, page= "enable")) ¾ GT <- gvisMerge(G, T, horizontal = FALSE) ¾ plot(GT)
122
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
CAPÍTULO III GRÁFICOS AVANZADOS
III.1. Gráficos demográficos La estructura de edad de una población se puede representar con la función «pyramid.plot()» del paquete “plotrix” (Lemon, 2012). Las instrucciones están en el script III.1.R y se usan de nuevo los datos del archivo Población.csv. Se representa el porcentaje de hombres y mujeres españolas, junto con el de hombres y mujeres extranjeros, los cuales son datos publicados por el Instituto Nacional de Estadística de España (www.ine.es). Después de cargar el paquete e importar los datos, se calcula el porcentaje de hombres y mujeres españoles y extranjeros en 1991. En el primer gráfico se representa la población de españoles y en el segundo, que está superpuesto al primero, la población de extranjeros. El argumento «gap» es para establecer el espacio entre la pirámide de hombres y la de mujeres. Con el argumento lógico «show.values=T» se especifica que se muestren los valores de las barras y con «ndig» se define el número de decimales. Por último, en el segundo gráfico hay que especificar «add=T» para que se pinte sobre el anterior y no sea un gráfico nuevo.
¾ ¾ ¾ ¾ ¾ ¾ ¾
library(plotrix) Datos<-read.csv2("Población.csv", header=TRUE, encoding="latin1") attach(Datos) s<-sum(H.1991) + sum(M.1991) + sum(HE.1991) + sum(ME.1991) M1991<-M.1991*100/s; H1991<-H.1991*100/s ME1991<-ME.1991*100/s; HE1991<-HE.1991*100/s pyramid.plot(H1991,M1991,labels=Edad, main="Población española y extranjera en 1991",lxcol="blue", rxcol="pink", labelcex=1.2, unit="%", gap=1, show.values = T, top.labels=c("Hombres","Edad","Mujeres"), ndig= 1, xlim=c(5,5)) ¾ pyramid.plot(HE1991,ME1991,lxcol="red", rxcol="red", labelcex=0, gap=1, show.values=F, ndig=2, xlim=c(5,5), add=T) ¾ legend(3.5,19, c("Hombres", "Mujeres", "Extranjeros"), bty="n", pch = c(15,15,15), col=c("blue","pink","red"))
123
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
124
Población española y extranjera en España en 1991 Hombres
Edad
0.3 0.6 0.9 1.3
3
2
1 %
0
Hombres Mujeres Extranjeros
0.7 1
> 85 80 a 84 75 a 79 70 a 74 65 a 69 60 a 64 55 a 59 50 a 54 45 a 49 40 a 44 35 a 39 30 a 34 25 a 29 20 a 24 15 a 19 10 a 14 5a9 <5
1.9 2.3 2.5 2.2 2.5 2.7 2.9 3.3 3.6 3.8 3.9 3.6 2.9 2.4 4
Mujeres
1.5 1.8 2.3 2.5 2.6 2.3 2.5 2.8 2.9 3.3 3.5 3.6 3.7 3.4 2.7 2.2 0
1
2
3
4
%
Función pyramid.plot (paquete plotrix) lx y rx: conjunto de datos izquierdo y derecho, que pueden ser vectores, matrices o data frames. labels: etiquetas de las barras: labels = NA. top.labels: títulos de los dos conjuntos de datos y de la variable en el centro: top.labels= c("Male", "Age", "Female"). laxlab y raxlab: etiquetas opcionales para los ejes: laxlab=NULL y raxlab=NULL. unit: título con las unidades del gráfico: unit= "%". lxcol y rxcol: color de las barras izquierda y derecha: lxcol = rainbow(length(labels)) y rxcol = rainbow(length(labels)). gap: espacio entre ambos conjuntos de barras: gap = 1. ppmar: márgenes del gráfico: ppmar=c(4,2,4,2). labelcex: tamaño de las etiquetas: labelcex=1. show.values: si es TRUE se ponen etiquetas en las barras: show.values = FALSE. ndig: decimales de las etiquetas: ndig = 1. Se pueden usar los argumentos generales main, add y xlim.
GRÁFICOS AVANZADOS
125
III.2. Gráficos de burbujas Este tipo de gráficos se puede realizar con la función «size_n_color()» del paquete “plotrix” (Lemon, 2012). Las instrucciones están en el script III.2.R. Como ejemplo se usan unos datos, que están en el archivo AARotíferos.csv, de abundancia y concentración de aminoácidos por individuo, de la especie de rotífero Brachionus angularis, en lagunas del parque Nacional de Doñana (España). En el gráfico la abundancia de los individuos se representa con el tamaño de los círculos, y el gradiente de colores dentro de los círculos representa la concentración de aminoácidos. La escala de la variable que se representa con los tamaños de los círculos (en este caso la abundancia), debe tener un rango similar a la escala de la variable del eje x (en este caso temperatura). Por ello, en primer lugar la variable abundancia se divide por 10. Con la función «color.scale()» se define el gradiente de color dentro de los círculos y la función de la matriz de datos que se usa para los cálculos. El último número puede ser 0 (escala de verdes) ó 1 (escala de azules). Si solamente se quisiera representar la variable abundancia y no la concentración de aminoácidos, con el argumento «col» se definiría el color de los círculos y no sería necesario «color.scale()», ya que todos los círculos tendrían el mismo color. Los argumentos «xat» e «yat» sirven para ubicar las marcas y etiquetas de los ejes. La leyenda del tamaño de los círculos se representa con las funciones «points()» y «text()» que ya se explicaron en el Capítulo II. La leyenda del gradiente de colores se representa con la función «color.legend()», en la cual se especifican las coordenadas de los extremos del rectángulo (cuatro coordenadas), los límites de la secuencia de colores y el intervalo, si se representa en posición vertical «gradient="y"» u horizontal «gradient="x"», y donde se ubican las etiquetas del gradiente; a la derecha con «align="rb"» o a la izquierda con «align="lt"». Con el argumento «rect.col» se pone el mismo intervalo para la secuencia de colores y el mismo gradiente de colores que se usó en la función «size_n_color()» con el argumento «color.scale».
¾ ¾ ¾ ¾ ¾
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
library(plotrix) Datos<-read.csv2("AARotíferos.csv", header=TRUE, encoding="latin1") attach(Datos) Ab<-Datos$Abundancia/10 size_n_color(Temperatura, Conductividad, Ab, cex.main= 1.6, color.scale (AA,c(0.8,0),c(0.8,1),1), pch=16, xlab="", ylab="", main="Abundancia y concentración de aminoácidos", xat=seq(20,35,by=5), yat=seq(0,2,by=0.5), xlim = c(20,35), ylim=c(0,2)) points(21,1.9,cex=10);text(22,1.9,"100 Individuos por litro",cex=1.2, pos=4) points(21,1.685,cex=2.5);text(22.8,1.685," 25",cex=1.2) points(21,1.580,cex=1);text(22.8,1.58," 10",cex=1.2) color.legend(20,0,21,0.50,seq(4500,6500,by=500),gradient="y",align="rb", rect.col=color.scale(seq(4500,6500,by=500),c(0.8,0),c(0.8,1),1)) text(23.8,0.28,"Picomoles", cex=1.2) text(23.8,0.195,substitute("individuo"^-1),cex=1.2) mtext(expression(paste("Conductividad (mScm"^-2,")")), 2, line=2.4, font = 1, cex=1.4) mtext(expression(paste("Temperatura (ºC)")), 1, line=2.8, font = 1, cex=1.4)
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
126
Abundancia y concentración de aminoácidos 2.0
2
Conductividad (mScm )
100 Individuos por litro 25 10 1.5
1.0
0.5
6500 6000 5500 Picomoles 1 5000 individuo 4500
0.0 20
25
30
35
Temperatura (ºC) Función size_n_color (paquete plotrix) x, y, size: variables x e y, más la variable que indica el tamaño de los círculos. xat e yat: especifica donde se colocan las marcas y etiquetas de los ejes. xaxlab y yaxlab: etiquetas de las marcas de los ejes: xaxlab=NULL, yaxlab=NULL. xcex e ycex: tamaño de las etiquetas de las marcas de los ejes: xcex=1, ycex=1. xlas e ylas: orientación de las etiquetas de las marcas de los ejes: xlas=0, ylas=1. xgrid e ygrid: trama interior de ambos ejes: xgrid=FALSE, ygrid=TRUE. boxit: si es TRUE se dibuja un marco: boxit=TRUE. Se pueden usar los argumentos generales pch, add, col, main, xlab e ylab.
GRÁFICOS AVANZADOS
127
Otra función interesante para realizar estos gráficos de burbuja, porque es muy fácil de usar, aunque tiene el problema de que no da mucho margen para introducir modificaciones en las leyendas de ejes, tamaños, etc., es «ggally_points()» del paquete “GGally” (Schloerke, 2012). Las instrucciones están en el script III.3.R. Como ejemplo se usan de nuevo los datos de abundancia y concentración de aminoácidos por individuo, de la especie de rotífero Brachionus angularis en varias lagunas del parque Nacional de Doñana (España), los cuales están en el archivo AARotíferos.csv. En el argumento «aes_string» se define cuales son las variables x e y. En ese mismo argumento también se especifica cual es la variable que define el gradiente de color «color» y cual es la que define el tamaño de los círculos «size». Para tapar las leyendas en inglés es necesario usar la función «polygon()» y luego poner leyendas nuevas con la función «mtext()».
library(GGally) datos<-read.csv2("AARotíferos.csv", header=TRUE, encoding="latin1") attach(datos) ggally_points(datos, aes_string(x = "Temperatura", y = "Conductividad", color = "AA", size = "Abundancia"))
1.4
AA
1.2
5000 5500 6000
Conductividad
¾ ¾ ¾ ¾
1.0
6500 Abundancia 0
0.8
20 40 60 0.6
80 100
0.4
24
26
28
30
32
Temperatura
Función ggally_points (paquete GGally) data: data frame con los datos mapping: composición definiendo las variables de los ejes x e y, el rango de colores y el tamaño de los círculos.
128
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
III.3. Gráficos de escalera Este gráfico muestra una secuencia de incrementos y cambios en el total mediante una serie de barras enlazadas. Se puede realizar con la función «staircase.plot()» del paquete “plotrix” (Lemon, 2012). Las instrucciones están en el script III.4.R. El ejemplo muestra como se pierde la biomasa desde los productores primarios hasta los secundarios, debido a las pérdidas en el consumo, asimilación y respiración. Es posible importar los datos desde un archivo, pero en este caso se utilizan vectores: el que define los valores de las barras «datos», el vector lógico que define si los datos son totales o una reducción «totals» y las etiquetas de las barras «labels». El argumento «halfwidth» especifica el ancho de las barras. Con «total.col» se define el color de las barras de los datos que son «TRUE» y con «in.col» de los datos que son «FALSE» en la variable «totals». El argumento «bg.col» es el color del fondo del gráfico. Con «direction» se define la orientación de las barras utilizando los puntos cardinales: "n" de abajo a arriba (hacia el norte), "s" de arriba a abajo, "e" de izquierda a derecha y "w" de derecha a izquierda. El argumento lógico «display.height» especifica si se muestran los valores de las barras. Por último, «stagger» es un argumento lógico que permite escalonar las etiquetas de las barras en caso de solapamiento.
¾ ¾ ¾ ¾
library(plotrix) datos<-c(100,-20,-25,-30,25) totals<-c(TRUE,FALSE,FALSE,FALSE,TRUE) labels<-c("Producción primaria","Eficiencia de consumo","Eficiencia de asimilación", "Eficiencia de producción", "Producción secundaria") ¾ staircase.plot(datos, totals, labels, halfwidth=0.3, main="Transferencia biomasa de productores primarios a secundarios", total.col="gray", inc.col=2:4, bg.col = "#eeeebb", direction="s", display.height=T, stagger=F) Transferencia biomasa de productores primarios a secundarios
Producción primaria
100
Eficiencia de consumo
-20
Eficiencia de asimilación
-25
Eficiencia de producción
Producción secundaria
-30
25
GRÁFICOS AVANZADOS
129
Función staircase.plot (paquete plotrix) heights: vector numérico, matriz o data frame con al menos 2 columnas. totals: vector lógico ó variable con 0/1 indicando si los heights anteriores son totales (TRUE) o una reducción (FALSE): totals = NA. labels: etiquetas de las barras: labels = NULL. halfwidth: ancho de las barras: halfwidth = 0.3. mar: márgenes del gráfico: mar = NA. total.col: color de las barras que son TRUE en totals: total.col = "blue". inc.col: color de las barras que son FALSE en totals: inc.col = NA. bg.col: color de fondo del gráfico: bg.col = NA. direction: orientación de las barras: "n" horizontales de abajo/arriba, "s" horizontales de arriba/ abajo, "e" verticales de izquierda/derecha y "w" verticales de derecha/izquierda: direction = "e". display.height: si es TRUE se muestran los valores de las barras: display.height = TRUE. stagger: si es TRUE se escalonan las etiquetas para evitar solapamientos: stagger = FALSE. Se pueden usar los argumentos generales cex, las y main.
III.4. Diagramas de flujo La función «plotweb()» del paquete “diagram” (Soetaert, 2012) permite realizar este tipo de gráficos. Las instrucciones están en el script III.5.R. Los datos son de un estudio de flujo de carbono en un lago (Stone y Berman, 1993), que están en el archivo Carbono.csv. Después de importar los datos y guardarlos en memoria, con la función «is.na()» las celdas en blanco en el archivo se rellenan con ceros. El argumento «lab.size» es para definir el tamaño de las etiquetas de los nodos. Con «sub» se puede poner un subtítulo. Con el argumento «val=F» se especifica que no se muestre la leyenda con los valores de cada flujo. Con «budget=T» se especifica que se muestre la leyenda con la suma de los flujos que entran a cada nodo. En el diagrama, los círculos muestran flujos dentro del mismo nodo. Con «nullflow=c(5,500)» se indica que no se pone flecha a los flujos comprendidos entre ese rango de valores.
¾ ¾ ¾ ¾ ¾
library(diagram) datos<-read.csv2("Carbono.csv", header=TRUE, encoding="latin1") attach(datos) datos[is.na(datos)]<-0 plotweb(datos, main = "Flujo de carbono en una cadena trófica", sub ="", lab.size = 1, val=F, arr.col="red", budget=T, bud.title="Flujos de entrada", bud.size=0.6, length=0.15, nullflow=c(5,500)) ¾ text(1.5,0.932, expression(paste("mg C m"^"-2","d"^"-1")))
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
130 Flujos de entrada
Flujo de carbono en una cadena trófica
Detrítico : 392 Sedimentación : 1092 Ciliados : 93 Flagelados : 44 Bacterias : < 2.22e-16 Pirrof itas : < 2.22e-16 No.Pirrof itas : < 2.22e-16 Rotíf eros : 46 Cladóceros : 103 Copépodos : < 2.22e-16 Peces : 93
-2
mg C m d
-1
Peces Copépodos
Detrítico
Cladóceros
Sedimentación
Rotíferos
Ciliados
No.Pirrofitas
Flagelados
Pirrofitas
Bacterias 170 5
Función plotweb (paquete diagram) flowmat: data frame o matriz con los datos, donde los flujos van desde la fila a la columna. names: vector de texto con los nombres de los nodos. Si es NULL se usan los nombres de las variables de la matriz o data frame: names = NULL. lab.size: tamaño relativo de las etiquetas de los nodos: lab.size = 1.5. fig.size: si add es FALSE, indica el tamaño relativo del diagrama: fig.size = 1.3. sub: si add es FALSE, subtítulo arriba del diagrama. sub2: si add es FALSE, subtítulo debajo del diagrama.
GRÁFICOS AVANZADOS
131
Función plotweb (Continuación) nullflow: un valor numérico o un vector con dos valores numéricos. En el caso de un número, no se pone flecha a aquellos flujos menores que el número. En el caso de un vector con dos números, no se pone flecha a los flujos comprendidos entre ese rango: nullflow = NULL. minflow y maxflow: valores de flujo para el grosor mínimo y máximo de las flechas. Si no se indica se toman los valores mínimo y máximo: minflow = NULL y maxflow = NULL. legend: si es TRUE se pone una leyenda con los valores máximo y mínimo de los flujos. leg.digit: número de dígitos de la leyenda: leg.digit = 5. leg.title: título de la leyenda. arr.col: color de las flechas: arr.col = "black". val: si es TRUE se pone una leyenda con los valores de cada flujo. val.digit, val.size, val.col, val.title y val.ncol: número de dígitos, tamaño de los números, color, título de la leyenda y número de columnas de los valores de los flujos: val = FALSE, val.digit = 5, val.size = 0.6, val.col = "red", val.title = NULL y val.ncol = 1. budget: si es TRUE se suman los flujos entrantes y salientes de cada nodo: budget = FALSE. bud.digit, bud.size, bud.title y bud.ncol: número de dígitos, tamaño de los números, título de la leyenda y número de columnas de la leyenda con la suma de los flujos. bud.digit = 5, bud.size = 0.6, bud.title = "budget" y bud.ncol = 1. maxarrow y minarrow: máximo y mínimo grosor de las flechas, respectivamente: maxarrow = 10 y minarrow = 1. length: longitud de las puntas de la flecha: length = 0.1. dcirc: si es 0 no se pintan los flujos de un compartimento a sí mismo: dcirc = 1.2. Se pueden usar los argumentos generales add, main, log, bty y mar.
III.5. Gráficos de telarañas Este tipo de gráficos se puede representar con la función «radial.plot()» del paquete “plotrix” (Lemon, 2012). Las instrucciones están en el script III.6.R y como ejemplo se usan datos de metales en sedimentos a distintas profundidades, que están en el archivo Metales.csv. El argumento «rp.type» define si se pone en forma de polígono "p", en formar radial "r" o con símbolos "s". Con «radlab» se especifica si se rotan las etiquetas. Con «label.prop» se define cuanto se separan las etiquetas del gráfico. El argumento «show.grid.labels» define la posición de los números de la escala de los ejes. Con «grid.col» y «grid.bg» se definen los colores de la trama interior y si «rp.type="p"» el color del polígono, respectivamente. Por último, «add=T» hace que el gráfico se dibuje sobre el anterior y no sea uno nuevo.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
132 ¾ ¾ ¾ ¾
¾ ¾ ¾ ¾
library(plotrix) Datos<-read.csv2("Metales.csv", header=TRUE, encoding="latin1") attach(Datos) radial.plot(Datos[,2], labels=Metal, rp.type="p", main="Metales en sedimentos (ppm)", line.col="red", show.grid=T, lwd=2, lty=1, radial.lim=c(0,70), radlab=F, label.prop=1.1, show.grid.labels=2, grid.col= "grey", grid.bg="transparent") radial.plot(Datos[,3],labels=Metal,rp.type="p",line.col="blue",show.grid=T, lwd=2, radial.lim=c(0,70),label.prop=1.1,show.grid.labels=2, add=T) radial.plot(Datos[,4],labels=Metal,rp.type="p",line.col="green",show.grid= T, lwd = 2, radial.lim=c(0,70),label.prop=1.1,show.grid.labels=2, add=T) radial.plot(Datos[,5],labels=Metal,rp.type="p",line.col="orange",show.grid= T, lwd=2, radial.lim=c(0,70), label.prop=1.1,show.grid.labels=2, add=T) legend("topleft", c("1 cm", "50 cm", "100 cm", "200 cm"), bty="y", pch = c(15,15,15,15), col=c("red", "blue","green","orange")) Metales en sedimentos (ppm) Ni 1 cm 50 cm 100 cm 200 cm
Co
Cu
70
60
50
40
30
20
10
0
Cr
Ga
Al
Pb
GRÁFICOS AVANZADOS
133
Función radial.plot (paquete plotrix) lengths: vector numérico o matriz. Si es una matriz, las filas se consideran vectores independientes. radial.pos: vector numérico, variable o matriz, con las posiciones en radianes: radial.pos=NULL. labels: etiquetas de las variables. label.pos: posición de las etiquetas en radianes: label.pos=NULL. radlab: si es TRUE se rotan las etiquetas: radlab= FALSE. start: posición de inicio de la primera variable: start=0. clockwise: define si las variables van en el sentido o en contra de las agujas del reloj: clockwise=FALSE. rp.type: define si se pinta un polígono "p", radios "r" o símbolos "s": rp.type="r". label.prop: define la separación de las etiquetas: label.prop=1.15. line.col: color de las líneas. mar: define los márgenes del gráfico. mar=c(2,2,3,2). show.grid: si es TRUE se muestra la trama interior de líneas circulares: show.grid=TRUE. show.grid.labels: se especifica la posición de los números de la escala: show.grid.labels =4. show.radial.grid: si es TRUE se muestra la trama interior de radios: show.radial.grid= TRUE. show.centroid: si es TRUE se muestran los centroides: show.centroid=FALSE. grid.col y grid.bg: definen los colores de la trama interior y si rp.type=”p” el color del relleno de la trama interior: grid.col = "gray" y grid.bg = "transparent". grid.left: si es TRUE se colocan las etiquetas de la trama en el lado izquierdo: grid.left=FALSE. grid.unit: descripción de las unidades: grid.unit= NULL. points.symbols y points.col: símbolos con el formato pch y su color: point.symbols=NULL y point.col=NULL. radial.lim y radial.labels: límites y etiqueta de la trama radial: radial.lim= NULL y radial.labels=NULL. poly.col: color de relleno si se representan polígonos; NA para no rellenar con color: poly.col = NULL. Se pueden usar los argumentos generales lty, lwd, main, add, xlab e ylab.
III.6. Diagrama de eventos Este gráfico muestra la evolución de una serie de eventos en el tiempo. Se realiza con la función «event.chart()» del paquete “Hmisc” (Dubin y col., 1997; Lee y col., 2000; Dubin y col., 2001; Harrell, 2010). Las instrucciones están en el script III.7.R. También es necesario el paquete “chron” (James, 2012) para convertir fechas a días julianos, es decir, el número de días que han pasado desde una determinada fecha que se toma como referencia.
134
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Como ejemplo se utilizan datos de la fecha de nacimiento y las fechas en las que accedieron a la enseñanza primaria, secundaria, universidad y trabajo diferentes hombres y mujeres. En el script están las instrucciones para trabajar con días julianos y con fechas (día/mes/año). En el archivo Trabajo.csv los datos están en formato d/m/año y en el archivo TrabajoJ.csv en días julianos. En el archivo de datos es conveniente poner primero las variables que sirven como etiquetas, por ejemplo en este caso el sexo, y luego todas las variables que sean fechas, en este caso fecha de nacimiento y las fechas de acceso a la primaria, secundaria, universidad y al trabajo. En el caso del script para el formato de datos no juliano, después de cargar los paquetes, al importar los datos es necesario pasar las variables de factor a carácter con el argumento «colClasses="character"», porque la función «event.chart()» trabaja con este tipo de datos.
¾ library(chron) ¾ library(Hmisc) ¾ datos<-read.csv2("Trabajo.csv", colClasses = "character")
header=TRUE,
encoding=
"latin1",
Posteriormente, se transforman las fechas a días julianos. Para ello se utiliza la función «dates()» del paquete “chron”. Es necesario definir la columna primera «c1» y última «c2» que tienen las variables con las fechas de los eventos, en este caso de la 2 a la 6. Con la función «options()» se especifica la fecha que se considera como referencia para el cálculo de los días julianos, en este caso 1/1/1940. Después de calcular los días julianos con la función «dates()», se pasan a datos numéricos con la función «as.numeric()». La nueva matriz creada se guarda en «datos1».
¾ ¾ ¾ ¾ ¾ ¾ ¾
c1<-2 c2<-6 h<-c1+1 options(chron.origin = c(day=1, month=1, year=1940)) datos1<-as.numeric(dates(datos[,c1],format = c(dates = "d/m/y"))) for (i in h:c2){ x<-as.numeric(if (datos[,i]=="NA") x<-datos[,i] else dates(datos[,i], format = c(dates = "d/m/y"))) datos1<-cbind(datos1,x) } En las siguientes instrucciones se anexan con «cbind()» las columnas del archivo original que no eran fechas de eventos al archivo creado con los días, es decir, se anexa la variable sexo, y se colocan los encabezados del archivo original con la función «colnames()».
¾ datos2<-cbind(datos[,1],datos1) ¾ colnames(datos2)<-colnames(datos) Por último, se realiza el gráfico con la función «event.chart()». Con «y.var» se especifica la variable que se usa para escalar el eje y, en este caso los días que han pasado desde 1/1/1940 hasta la fecha de nacimiento de la persona. Con
GRÁFICOS AVANZADOS
135
«subset.c» se eligen las variables con eventos a representar. El argumento «line.by» especifica la variable en función de la cual se pondrán diferentes líneas a cada grupo de esa variable, en este caso para diferenciar hombres de mujeres. Con «legend.location="i"» se especifica que la posición de la leyenda sea interior. En el argumento «legend.point.text» se pone el texto de la leyenda de los diferentes eventos y en «legend.line.text» el texto de la leyenda de los diferentes grupos de la variable especificada en «line.by». Con «legend.point.at» y «legend.line.at» se definen las posiciones de la leyenda de los eventos y la de las líneas. Con «date.orig» se especifica la fecha de referencia, en este caso 1/1/1940.
¾ event.chart(datos2, y.var="Nacimiento", subset.c=c("Nacimiento", "Primaria", "Secundaria", "Universidad", "Trabajo"), x.lab = "Fecha", y.lab="Días hasta nacimiento desde fecha referencia 01/01/1940", titl="Acceso a los estudios y al trabajo", point.pch=c(15,16,17,18,19), point.col = rep(10,5), line.by = "Sexo", line.lty=c(1,3), line.lwd = rep(1,2), line.col = rep(1,2), point.cex = rep(1.5,5), legend.plot =TRUE, legend.location="i", legend.cex=1.3, legend.point.text = c("Nacimiento", "Primaria", "Secundaria", "Universidad", "Trabajo"), legend.point.at = list(c(500, 8000), c(15000, 10600)), legend.bty= "o", legend.line.at = list(c(17000, 25000), c(4000, 2000)), legend.line.text=c("Hombres", "Mujeres"), date.orig = c(1, 1, 1940), y.var.type="n")
14000 4000
6000
8000
10000
12000
Nacimiento Primaria Secundaria Universidad Trabajo
Hombres Mujeres
2000
Días hasta nacimiento desde fecha referencia 01/01/1940
Acceso a los estudios y al trabajo
9/30/42
6/17/59
3/2/76 Fecha
11/17/92
8/4/09
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
136
El siguiente gráfico utiliza el archivo TrabajoJ.csv que tiene los datos en días julianos. La variación con el anterior es que con «y.var.type="d"» se define que el eje y sea en días julianos desde la fecha de referencia, con «x.reference ="Nacimiento"» se define que la variable x sea el nacimiento, con «x.julian=T» que el eje x se muestre en días julianos y con «x.scale=365» los días julianos se pasan a años en el eje x.
¾ datos<-read.csv2("TrabajoJ.csv",header=TRUE, encoding= "latin1") ¾ event.chart(datos, y.var="Nacimiento", subset.c=c("Nacimiento", "Primaria", "Secundaria", "Universidad", "Trabajo"), x.lab = "Ead hasta el evento", y.lab="Fecha de nacimiento", titl="Acceso a los estudios y al trabajo", point.pch=c(15,16,17,18,19), point.col=rep(10,5), line.by="Sexo", line.lty=c(1,3), line.lwd=rep(1,2), line.col=rep(1,2), point.cex=rep(1.5,5), legend.plot=TRUE, legend.location="i", legend.cex= 1.3, legend.point.text= c("Nacimiento", "Primaria", "Secundaria", "Universidad", "Trabajo"), legend.point.at = list(c(21.9, 32), c(5000, 800)), legend.bty="o", legend.line.at = list(c(21.9, 32), c(7100, 5200)), legend.line.text= c("Hombres", "Mujeres"), date.orig = c(1, 1, 1940), y.var.type= "d", x.reference="Nacimiento", x.julian=T, x.scale=365)
7/1/61 2/15/52
Hombres Mujeres Nacimiento Primaria Secundaria Universidad Trabajo
9/30/42
Fecha de nacimiento
11/16/70
4/2/80
Acceso a los estudios y al trabajo
0
5
10
15
20
Edad hasta el evento
25
30
GRÁFICOS AVANZADOS
137
Función event.chart (paquete Hmisc) data: matriz o data frame con los datos. subset.r y subset.c: selección de unas filas o columnas de la matriz original, respectivamente. sort.by: variable en base a la que ordenar los datos. Por defecto es NA, y se ordenan por el orden de fila. sort.ascending: si es TRUE el orden es ascendente: sort.ascending = TRUE. sort.na.last: si es TRUE los valores NA se ponen en la última posición: sort.na.last = TRUE. sort.after.subset: en el supuesto de que se seleccionen determinadas filas con subset.r, si es FALSE la ordenación de los datos se hará antes de las selección de las filas: sort.after.subset = TRUE. y.var: variable que se usa para escalar el eje y. En caso de no poner nada, se deja el mismo espacio entre datos: y.var = NA. y.var.type: tipo de variable con la que se escala el eje y: "d" es una fecha y "n" es numérica: y.var.type = "n". y.jitter: si es TRUE, en el caso de existir solapamiento en el eje y, se separarían los datos: y.jitter = FALSE. y.jitter.factor: valor numérico de desplazamiento en el eje y si y.jitter = TRUE: y.jitter.factor = 1. y.renum: si es FALSE y se ha realizado una selección de filas, éstas aparecerán en y con el número de fila que tienen en la matriz de datos: y.renum = FALSE. NA.rm: si es TRUE los valores NA no se tendrán en cuenta: NA.rm = FALSE. x.reference: variable temporal que se usa en el eje x: x.reference = NA. now: fecha que se usará como valor máximo en el eje y en el diagrama de Goldman. Para hacer un diagrama de Goldman hay que definir una variable en x.reference y debe ser y.var=x.reference: now = max(data[, subset.c], na.rm = TRUE). now.line: si es TRUE y se ha seleccionado un diagrama de Goldman, éste será cuadrado y dibujará una recta con pendiente -1: now.line = FALSE. now.line.lty, now.line.lwd y now.line.col: tipo, grosor y color de la línea now.line: now.line.lty = 2, now.line.lwd = 1 y now.line.col = 1. date.orig: en caso de usar días julianos, es la fecha que se considera como origen: date.orig = c(1, 1, 1960). titl: título principal del diagrama: titl = "Event Chart". y.idlabels: variable con las etiquetas del eje y: y.idlabels = NA. y.axis: argumento lógico para las etiquetas del eje y: si es "auto" se ponen automáticamente y si es "custom" las especifica el usuario: y.axis = "auto". y.axis.custom.at y y.axis.custom.labels: en el caso de que y.axis= "custom", se especifica con un vector la posición y las etiquetas del eje y, respectivamente: y.axis.custom.at = NA e y.axis.custom. labels = NA.
138
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Función event.chart (Continuación) y.julian: si es FALSE se ponen fechas en vez de días julianos en el eje y. Para utilizarlo debe ser y.var.type="d" e y.axis="custom": y.julian = FALSE. y.lim.extend: un vector con dos números que indica el incremento en los extremos del eje y: y.lim.extend = c(0, 0). y.lab: leyenda del eje y. x.axis.all: si es FALSE los límites del eje x se basan en los datos seleccionados con subset.r, si es TRUE en todos los datos: x.axis.all = TRUE. x.axis: etiquetas del eje x, si es "auto" se ponen automáticamente y si es "custom" las especifica el usuario: x.axis = "auto". x.axis.custom.at y x.axis.custom.labels: en el caso de que x.axis= "custom", se especifica con un vector la posición y las etiquetas del eje x, respectivamente: x.axis.custom.at = NA y x.axis.custom. labels = NA. x.julian: si es FALSE se ponen fechas en vez de días julianos en el eje x. Para utilizarlo deber ser x.axis="auto". Si se pone una variable en x.reference debe ser TRUE: x.julian = FALSE. x.lim.extend: un vector con dos números que indica el incremento en los extremos del eje x: x.lim.extend = c(0, 0). x.scale: factor de multiplicación para el eje x. Por ejemplo, si la escala está en días y el factor es 365, pasaría a estar en años: x.scale = 1. x.lab: leyenda del eje x: x.lab = ifelse(x.julian, "Follow-up Time", "Study Date"). line.by: variable en función de la cual se pondrían diferentes líneas a cada grupo de esa variable: line.by = NA. line.lty, line.lwd y line.col: vectores con el tipo, grosor y color de las líneas, respectivamente, si se define una variable en line.by. Los vectores deben tener tantos números como grupos en la variable: line.lty = 1, line.lwd = 1 y line.col = 1. line.add: una matriz 2xk con k = número de pares de segmentos de línea adicionales para agregar. Por ejemplo, para dibujar trazos que conecten los eventos 1-2 y 2-3, un argumento line.add adecuado sería la matriz (c ('first.event', 'second.event', 'second.event', 'third.event'), 2, 2). Un segmento de línea se establecería entre first.event y second.event, y un segmento de la segunda línea se establecería entre second.event y third.event. Diferentes tipos de línea, grosores y colores se especifican con los argumentos que vienen a continuación: line.add = NA. line.add.lty, line.add.lwd y line.add.col: vectores con el tipo, grosor y color de las líneas, respectivamente, si se define una matriz en line.add: line.add.lty = NA, line.add.lwd = NA y line.add.col = NA. point.pch, point.cex y point.col: tipo, tamaño y color de los símbolos: point.pch = 1:length(subset.c), point.cex = rep(0.6, length(subset.c)) y point.col = rep(1, length(subset.c)).
GRÁFICOS AVANZADOS
139
Función event.chart (Continuación) point.cex.mult: valor numérico en función del cual se escala el tamaño de los símbolos. Por ejemplo, point.cex.mult=0.00007: point.cex.mult = 1. point.cex.mult.var: variable en función de la cual se escala el tamaño de los símbolos con el valor definido en el argumento anterior. Por ejemplo, si point.cex.mult.var="Nacimiento", todos los símbolos se escalan en función de las fechas de nacimiento de las personas: point.cex.mult.var = NA. extra.points.no.mult: vector con el nombre de las variables que no se tienen en cuenta para la escala definida en point.cex.mult: extra.points.no.mult = rep(NA, length (subset.c)). legend.plot: si es TRUE se muestra la leyenda: legend.plot = FALSE. legend.location: posición de la leyenda: "i" interior, "o" exterior y "l" usa la opción locator: legend.location = "o". legend.titl y legend.titl.cex: texto y tamaño de letra de la leyenda: legend.titl = titl y legend.titl.cex = 3. legend.titl.line: posición de la leyenda utilizando la escala de mtext: legend.titl.line = 1. legend.point.at, legend.point.pch, legend.point.text y legend.cex: posición, tipo de símbolos, etiquetas de los diferentes eventos y tamaño de la etiquetas en la leyenda: legend.point.at = list(x = c(5, 95), y = c(95, 30)), legend.point.pch = point.pch, legend.point.text = ifelse(rep(is.data.frame(data), length (subset.c)), names(data[, subset.c]), subset.c) y legend.cex = 2.5. legend.bty: si es "o" se pone un marco a la leyenda y si es "n" no se pone marco: legend.bty = "n". legend.line.at, legend.line.text y legend.line.lwd: posición, etiquetas del texto y grosor de las líneas de la leyenda de los diferentes grupos de la variable especificada en line.by: legend.line.at = list(x = c(5, 95), y = c(20, 5)), legend.line.text = names(table (as.character(data[, line.by]), exclude = c("", "NA"))) y legend.line.lwd = line.lwd. legend.loc.num: número que se usa para el argumento de localización cuando legend.location = "l": 1 significa que solamente se define el borde superior izquierdo del cuadro de la leyenda, 2 significa que el usuario define el borde superior izquierdo y el borde inferior derecho de la leyenda. Si se especifica variable en line.by hay que hacerlo para las dos leyendas: legend.loc.num = 1. Se puede usar el argumento general pch.
III.7. Matrices de gráficos Este tipo de gráficos permiten representar todas las variables, unas con otras, de un conjunto de datos. Es necesario tener instalado el paquete “lattice”
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
140
(Sarkar, 2008; Sarkar, 2012). Las instrucciones están en el archivo III.8.R. En este ejemplo usaremos los datos de clorofila, afloramiento, temperatura y nutrientes de diferentes zonas costeras del mundo, los cuales están en el archivo Producción primaria.csv. Después de cargar la librería e importar los datos, se seleccionan solamente las variables clorofila y los tres nutrientes. Se utiliza la función «pairs()», en la cual simplemente hay que especificar el conjunto de datos que contiene las variables a representar, que debe ser una matriz o un data frame.
¾ library(lattice) ¾ datos<-read.csv2("Producción primaria.csv", header = TRUE, encoding = "latin1") ¾ datos1<-datos[,c("Clorofila","Fosfato","Nitrato","Silicato")] ¾ pairs(datos1,main="Clorofila y nutrientes",cex.main=2, cex=1.5, pch=15, cex.labels = 2.8)
Clorofila y nutrientes 1.0
1.5
2
4
6
8
10
3
4
0.5
1.0
1.5
0
1
2
Clorofila
2 4 6 8 10
14
0.5
Fosfato
8
10
Nitrato
2
4
6
Silicato 0
1
2
3
4
2
4
6
8 10
14
La diferencia del segundo gráfico con el anterior es que se le añaden colores a los puntos. Es necesario el paquete “vcd” (Meyer y col., 2012) para usar la función «grid_legend()» y poner la leyenda. El argumento «frame=FALSE» es para que no represente el marco de la leyenda. Es necesario poner las cuatro leyendas de las columnas por separado. El argumento «unclass» transforma el factor «Area» (una lista de categorías) en un listado de 1, 2, 3 y 4.
GRÁFICOS AVANZADOS
141
¾ library(vcd) ¾ pairs(datos1, pch=21, bg=c("red","blue","cyan","yellow") [unclass(datos $Area)], cex=1.8) ¾ grid_legend(0.2, 0.99, pch=c(19), col=c("red"),c("Benguela"), title="", frame= FALSE) ¾ grid_legend(0.4, 0.99, pch=c(19), col=c("blue"),c("California"),title="", frame = FALSE) ¾ grid_legend(0.6, 0.99, pch=c(19), col=c("cyan"),c("Humbolt"), title="", frame =FALSE) ¾ grid_legend(0.8, 0.99, pch=c(19), col=c("yellow"),c("Humbolt"), title="", frame=FALSE) Benguela
California 1.0
Humbolt
Mauritania
1.5
2
4
6
8
10
3
4
0.5
1.0
1.5
0
1
2
Clorofila
8 10
14
0.5
Fosfato
8
10
2
4 6
Nitrato
2
4
6
Silicato
0
1
2
3
4
2
4
6
8 10
14
En el tercer gráfico se combinan gráficos de barras, que muestran la distribución de las distintas variables, con gráficos de dispersión. Es necesario tener instalados los paquetes “MASS” (Ripley y col., 2012), “ellipse” (Murdoch, 2009) y “SciViews” (Grosjean, 2012). El gráfico se barras se hace con la función «panel.hist()» del paquete “SciViews”. Otras funciones de este paquete son «panel.boxplot()», «panel.density()» y «panel.qqnorm()».
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
142
Con los argumentos «diag.panel», «lower.panel» y «upper.panel» es posible definir gráficos diferentes en la diagonal, por debajo, y por encima de la diagonal, respectivamente. En la diagonal se representan los histogramas que muestran las frecuencias de las variables, lo cual se ha definido con una función y se ha asignado a «panel.hist» En los gráficos inferiores se muestran los modelos de regresión suavizada y en los que están por encima de la diagonal el modelo de regresión lineal. Para poder hacer esta figura con otro tipo de datos, simplemente hay que sustituir en el script «datos1» por la matriz con la que se trabaje.
¾ library(SciViews) ¾ panel.hist <- function(x, ...) { usr <- par("usr"); on.exit(par(usr)) par(usr = c(usr[1:2], 0, 1.5)); h <- hist(x, plot = FALSE) breaks <- h$breaks; nB <- length(breaks) y <- h$counts; y <- y/max(y) rect(breaks[-nB], 0, breaks[-1], y, col="cyan", ...) } ¾ pairs(datos1, main="Clorofila y nutrientes",cex.main=2, lower.panel= panel.smooth, upper.panel=panel.reg, cex = 1.2, pch=24, bg="light blue", diag.panel = panel.hist, cex.labels = 2, font.labels=2)
Clorofila y nutrientes 1.0
1.5
2
4
6
8
10 4
0.5
0
1
2
3
Clorofila
14
0.5
1.0
1.5
Fosfato
10
2 4 6 8 10
Nitrato
2
4
6
8
Silicato
0
1
2
3
4
2
4
6
8 10
14
GRÁFICOS AVANZADOS
143
Función pairs (paquete graphics) x: matriz o data frame donde están las variables que se van a representar o una fórmula del tipo ~ x + y + z. data: data frame donde están las variables, en el caso de usar una fórmula. labels: nombre de las variables. panel: función donde se especifican las características del panel gráfico: points, lines, panel.boxplot, panel.hist, panel.density, panel. qqnorm, etc.: panel = points. lower.panel: función específica para definir las características del panel gráfico inferior, por debajo de la diagonal: lower.panel = panel. upper.panel: función específica para definir las características del panel gráfico superior: upper.panel = panel. diag.panel: función específica para definir las características de la diagonal como por ejemplo poner histogramas diag.panel = panel.hist: diag.panel = NULL. label.pos: valor numérico con la posición en la diagonal de las etiquetas de las variables representadas: label.pos = 0.5 + has.diag/3. cex.labels: tamaño de letra de las etiquetas de la diagonal: cex. labels = NULL. font.labels: estilo de letra de las etiquetas de la diagonal: font. labels = 1. row1attop: si es TRUE la diagonal va de izquierda a derecha y si es FALSE va de derecha a izquierda: row1attop = TRUE. gap: distancia entre los gráficos interiores en líneas de margen: gap = 1.
Contenidos del argumento diag.panel (paquete SciViews) panel.boxplot(x, col = par("col"), box.col = "cornsilk", ...) panel.density(x, adjust = 1, col = par("col"), lwd = par("lwd"), line.col = col, line.lwd = lwd, ...) panel.hist(x, breaks = "Sturges", hist.col = "cornsilk", hist.border = NULL, hist.density = NULL, hist.angle = 45, ...) panel.qqnorm(x, pch = par("pch"), col = par("col"), bg = par("bg"), cex = par("cex"), lwd = par("lwd"), qq.pch = pch, qq.col = col, qq.bg = bg, qq.cex = cex, qqline.col = qq.col, qqline.lwd = lwd, ...)
x: variable o vector numérico. col: color de los símbolos. box.col: color de relleno en boxplots: box.col = "cornsilk". adjust: grosor de banda en density: adjust = 1. line.col: color de la línea. line.lwd: grosor de la línea. breaks: número de barras, el nombre del algoritmo o un vector con los puntos de corte de las barras en el histograma: breaks = "Sturges". hist.col: color de relleno de las barras del histograma: hist.col = "cornsilk".
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
144
Contenidos del argumento diag.panel (Continuación) hist.border: color del borde de las barras en el histograma: hist.border = NULL. hist.density: densidad de las líneas de relleno de las barras en el histograma. hist.angle: ángulo de las líneas del relleno de las barras en el histograma: hist.angle = 45. pch, bg y cex: tipo de símbolo, color de relleno y tamaño de los símbolos, respectivamente. qq.pch: tipo de símbolo en los QQ-gráficos. qq.col: color de los símbolos en los QQ-gráficos. qq.bg: color de relleno de los símbolos en los QQ-gráficos. qq.cex: tamaño de los símbolos en los QQ-gráficos. qqline.col: color de las líneas en los QQ-gráficos. qqline.lwd: grosor de las líneas en los QQ-gráficos. Otra función que se puede utilizar para este tipo de gráficos es «splom()», que también requiere tener instalado el paquete “lattice” (Sarkar, 2012), se muestra en el gráfico 4 y tiene un formato un poco diferente.
¾ datos2<-datos[,c("Temperatura","Fosfato","Nitrato","Silicato")] ¾ splom(~ datos2,main="Temperatura y nutrientes",cex.main=2, col= "black") Temperatura y nutrientes 6
10
8
10
Silicato
6
8 6
4 2 14 12 10 8
8 10 12 14
Nitrato
0 2 4 6
6 4 2 0
1.0
1.5 1.0
1.5
Fosfato 1.0 0.5
0.5 20 16
18
20
18 16Temperatura 16 14 12
14
16 12
1.0
4
6
2
GRÁFICOS AVANZADOS
145
Esta misma función permite otro formato de representación (gráfico 5 en el script), que se muestra a continuación, en el cual cada grupo, en este caso las diferentes zonas costeras, se pone en una gráfica diferente. Es necesario indicar los datos con los grupos, con «datos2|Area» en lugar de «datos2». El argumento «pscales» permite ajustar el tamaño de las leyendas interiores de los ejes y nombres de las variables. Con el argumento «between» se define el espacio que se deja entre los gráficos, en los ejes x e y.
¾ splom(~datos2|Area, layout = c(2,2), pscales = 0, varnames = c("Temp", "Fosfato","Nitrato","Silicato"), main="Temperatura y nutrientes", cex.main = 1.8, between=list(x=0.5,y=0.5))
Temperatura y nutrientes Humbolt
Mauritania Silicato
Silicato
Nitrato
Nitrato
Fosfato
Fosfato
Temp
Temp Benguela
California Silicato
Silicato
Nitrato
Nitrato
Fosfato
Temp
Fosfato
Temp
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
146
Por último, en el gráfico 6 se muestra otra variante de este tipo de gráficas con la función «xyplot()». Se seleccionan las áreas de Mauritania, Benguela y California con la función «subset()». Las variables que se van a representar se introducen por pares, y es posible especificar una variable de agrupación, de nuevo las diferentes áreas. El argumento «auto.key» permite poner la leyenda de los símbolos. Las modificaciones que se quieran realizar de las etiquetas y formato de las divisiones de los ejes, se deben introducir con una lista en el argumento «scales». El argumento «aspect» define la proporción ancho/alto de las figuras. El argumento «layout» es una lista de 2 ó 3 números que definen el número de columnas, filas y páginas respectivamente.
¾ datos3<-subset(datos, Area %in% c("Mauritania", "Benguela","California")) ¾ xyplot( Clorofila + Fosfato ~ Nitrato + Silicato | Area, data = datos3, scales = list(cex=c(1,1), font=2), layout = c(2, 2), auto.key = list(x = 0.6, y = 0.7, corner = c(0, 0)), aspect=1) Mauritania 4 3
Clorofila + Fosfato
2
Clorofila * Nitrato Clorofila * Silicato Fosfato * Nitrato Fosfato * Silicato
1 0 Benguela
California
4 3 2 1 0 2
4
6
8
10
12
Nitrato + Silicato
GRÁFICOS AVANZADOS
147
Función splom (paquete lattice) x: data frame con las variables a representar o fórmula del tipo ~ x | g1 * g2 *… donde x es el data frame o matriz de datos y g1, g2, … son factores opcionales o variables de agrupación. data: matriz con los datos. between: define el espacio entre gráficos en el eje x y en el eje y: between = list(x = 0.5, y = 0.5). aspect: valor numérico que da el aspecto (relación ancho/alto) del panel. A medida que el valor es más pequeño es más ancho que alto: aspect = 1. pscales: valor numérico o lista que permite modificar las etiquetas y formato de las marcas de los ejes: pscales = 5. varnames: carácter o expresión con los nombres de las variables. Los otros argumentos: allow.multiple, aspect, outer, auto.key, panel, prepanel, etc., son comunes a la mayoría de las funciones del paquete “lattice” y se explicaron en los cuadros de la funciones bwplot(), wireframe() y/o cloud() del Capítulo II.
Función xyplot (paquete lattice) x: data frame con las variables a representar o fórmula del tipo y ~ x | g1 * g2 *... (o equivalente, y ~ x | g1 + g2 +...), indicando que los gráficos con las variables x e y deben realizarse para los grupos definidos en las variables g1, g2,... Los otros argumentos: allow.multiple, aspect, outer, auto.key, panel, prepanel, etc., son comunes a la mayoría de las funciones del paquete “lattice” y se explicaron en los cuadros de las funciones bwplot(), wireframe(), cloud() y/o splom().
III.8. Gráficos de matrices de correlaciones La función «corrplot()» del paquete con el mismo nombre “corrplot” (Wei, 2012) es muy útil para representar matrices de correlaciones (Murdoch y Chow, 1996; Friendly, 2002). Las instrucciones están en el script III.9.R. Los datos, que están en el archivo Morfología.csv, son medidas morfométricas de peces. Después de importar los datos se selecciona solo un grupo de peces y las variables que están en las columnas 5 a 25, que se guardan en «datos1». Es importante seleccionar solamente variables numéricas para poder hacer las correlaciones. En «cor.mtest» se guarda una función que permite calcular correlaciones, con la que solamente hay que indicar el objeto que tiene los datos, en este caso «datos1». La función utiliza un nivel de confianza de 0,95 para los intervalos, que se puede modificar.
148 ¾ ¾ ¾ ¾ ¾
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R library(corrplot) datos<-read.csv2("Morfología.csv",header=TRUE,encoding="latin1") attach(datos) datos1 <- datos[Orden=="Perciformes",5:25] cor.mtest <- function(datos1, conf.level = 0.95){ datos1 <- as.matrix(datos1) n <- ncol(datos1) p.mat <- lowCI.mat <- uppCI.mat <- matrix(NA, n, n) diag(p.mat) <- 0 diag(lowCI.mat) <- diag(uppCI.mat) <- 1 for(i in 1:(n-1)){ for(j in (i+1):n){ tmp <- cor.test(datos1[,i], datos1[,j], conf.level = conf.level) p.mat[i,j] <- p.mat[j,i] <- tmp$p.value lowCI.mat[i,j] <- lowCI.mat[j,i] <- tmp$conf.int[1] uppCI.mat[i,j] <- uppCI.mat[j,i] <- tmp$conf.int[2]}} return(list(p.mat, lowCI.mat, uppCI.mat))}
Con la función «cor()» se calculan todas las correlaciones entre las variables y luego con la función creada «cor.mtest» se calculan las probabilidades los contrastes de nulidad. Con la función «corrplot()» hacemos el primer gráfico que utiliza la matriz de correlaciones que se ha calculado anteriormente y se guardó como «corr». El argumento «type» define si el gráfico es completo "full", solo la mitad superior "upper" o la mitad inferior "lower", como en el primer caso. Con «method» se define si se pone un símbolo o un número en cada correlación. En el primer caso se ponen los coeficientes de correlación con «method= "number"». Con «order» se especifica como ordenar las variables. Con «addtextlabel» se define la posición de las etiquetas de las variables. El argumento «p.mat» especifica cual es la matriz con los datos de las probabilidades, que en este caso se guardaron anteriormente en «res1» y lo que hace en el gráfico es poner una marca en aquellas correlaciones que no sean significativas (en ese caso una cruz), con el nivel de significación utilizado para «res1». Con «sig.level» podemos cambiar el nivel de significación, sin tener que volver a calcular «res1». La segunda vez que se utiliza «corrplot()» se pone un valor de «sig.level=0.001» para ver, por encima de la diagonal, las diferencias con el gráfico anterior (por debajo de la diagonal); algunas correlaciones dejan de ser significativas, ya que anteriormente el nivel de significación era 0,05. En este gráfico superior el argumento «method="square"» y, por ello, se pintan cuadrados y no las correlaciones.
¾ corr<-cor(datos1) ¾ res1<-cor.mtest(datos1,0.95) ¾ corrplot(corr, type="lower", method="number", order="original", addtextlabel= "lt", p.mat = res1[[1]], sig.level=0.05) ¾ corrplot(corr,add=TRUE, method="square", order="original", type="upper", addtextlabel="lt", p.mat = res1[[1]], sig.level=0.001) ¾ text(11,24, "Correlación entre variables morfométricas",cex=1.5)
GRÁFICOS AVANZADOS
149
M2
26 100
M4
52 68 100
M5
-14 28 42 100
M6
65 30 36 12 100
M7
42 55 57 45 80 100
M8
43 31 54 60 39 46 100 43 20 27 21 49 44 61 100
M10
M22
M21
M20
M19
M18
M17
M16
M15
M14
M13
M12
M11
1
100
M3
M9
M10
M9
M8
M7
M6
M5
M4
M3
M2
Correlación entre variables morfométricas
0.8
0.6
0.4
0.2
8 34 21 38 28 48 46 74 100
M11
20 78 81 58 34 67 49 29 43 100
M12
-11 67 58 53 -8 30 37 6 34 78 100
M13
24 78 79 52 26 57 54 31 42 93 84 100
M14
-12 -26 -13 -19 -40 -44 -15 -28 -31 -31 -3 -10100
M15
-22 60 46 52 -1 36 24 -7 23 75 84 70 -13100
0
-0.2
M17
-2 69 55 57 27 60 38 18 41 85 73 74 -55 85 100 -5 -41 -16 7 -20 -24 -6 -11 -25 -35 -37 -34 20 -47 -45100
M18
29 67 59 44 28 48 69 43 48 71 65 77 -21 56 66 -34100
M19
33 50 43 42 32 43 64 41 47 51 46 52 -35 45 58 -30 80 100
M20
12 60 73 61 20 53 46 15 29 82 73 81 -12 60 63 -14 50 34 100
M21
21 59 47 51 37 55 58 35 47 65 52 59 -50 59 77 -36 81 86 44 100
M22
-11 60 39 44 20 50 19 7 34 71 65 57 -57 82 93 -54 50 49 48 67 100
M16
-0.4
-0.6
-0.8
-1
El segundo gráfico se hace completo «type="full"», se ponen círculos «method=circle», se ordenan las variables en función del primer factor de un Análisis de Componentes Principales «order="FPC"» y con «outline= T» se especifica que se ponga un borde a los símbolos. Al final con «res1[3]» se muestran las correlaciones.
¾ corrplot(corr, type="full", method="circle", order="FPC", addtextlabel="lt", p.mat = res1[[1]], sig.level=0.01, outline=T) ¾ text(11,24, "Correlación entre variables morfométricas", cex=1.5) ¾ res1[3]
M2
M17
M14
M15
M12
M22
M16
M20
M5
M13
M11
M3
M21
M18
M4
M19
M7
M10
M8
M6
M9
M2
Correlación entre variables morfométricas 1
M9 M6
0.8
M8 M10
0.6
M7 M19
0.4
M4 M18
0.2
M21 M3
0
M11 M13
-0.2
M5 M20
-0.4
M16 M22
-0.6
M12 M15
-0.8
M14 M17
-1
150
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R Función corrplot (paquete corrplot)
corr: matriz de correlaciones. define si se pone un símbolo ("circle", "square", "color", "shade", "ellipse" o "pie") o un número en cada correlación ("number"): method = "circle”. type: especifica si se pinta todo el gráfico "full", la parte inferior "lower" o la parte superior "upper": type = "full". title: título del gráfico: title = "". diag: si es TRUE se representa la diagonal: diag = TRUE. outline: especifica si se pinta el borde del símbolo: outline = FALSE. addgrid.col: color de la trama: addgrid.col = "gray". order: orden de las variables: "original", "alphabet", en función de la primera componente principal "FPC" y orden de clasificación jerárquica si order = "hclust": order = "original". hclust.method: método del dendograma si order = "hclust": hclust.method = "complete". addrect: número de rectángulos de dendograma si order = "hclust": addrect = NULL. rect.col y rect.lwd: color y grosor de las líneas de los rectángulos si order = "hclust", respectivamente: rect.col ="black" y rect.lwd = 2. addtextlabel: posición de las etiquetas de las variables donde "lt" es arriba/izquierda, "ld" es izquierda/diagonal, "td" arriba/diagonal, "d" es diagonal y "no" no se muestran las etiquetas: addtextlabel = "lt". tl.cex, tl.col y tl.offset: tamaño, color y separación de las etiquetas de las variables, respectivamente: tl.cex = 1, tl.col = "red" y tl.offset = 0.4. addcolorlabel: posición donde representa la barra con el rango de colores de las correlaciones: "right", "bottom" o "no": addcolorlabel = "right". cl.length, cl.cex, cl.ratio, cl.align.text y cl.offset: número de etiquetas, tamaño de las etiquetas, proporción de la barra con respecto al gráfico, alineación de las etiquetas (izquierda "l", centro "c" o derecha "r") y separación de las etiquetas en la barra de correlaciones, respectivamente: cl.length = 11, cl.cex = 0.8, cl.ratio = 0.15, cl.align.text= "c" y cl.offset =0.5. addshade: si method="shade" con "all" todas las correlaciones se sombrean, con "positive" las positivas y con "negative" las negativas: addshade = "negative". shade.lwd y shade.col: grosor y color de la línea de sombra, respectivamente: shade.lwd = 1 y shade.col = "white". p.mat: matriz con los valores de probabilidad. Si es NULL, los argumentos sig.level, insig, pch, pch.col, pch.cex no se utilizan: p.mat = NULL. sig.level: nivel de significación que se utiliza para definir que correlaciones se marcan como no significativas en el gráfico. Si valor de probabilidad en p.mat es mayor que sig.level, la correlación se señala como no significativa: sig.level = 0.05. insig: método para señalar las correlaciones no significativas: con un símbolo "pch", se dejan en blanco "blank" o no se hace nada "no": insig = "pch".
method:
GRÁFICOS AVANZADOS
151
Función corrplot (Continuación) pch, pch.col y pch.cex: tipo, color y tamaño del símbolo que se pone si la correlación es no significativa: pch = 4, pch.col = "black" y pch.cex = 3. plotCI: modo de representar el intervalo de confianza que puede ser "no", "square", "circle" o "rect": plotCI = "no". lowCI.mat y uppCI.mat: matrices con los valores inferiores y superiores del intervalo de confianza: lowCI.mat = NULL y uppCI.mat = NULL. Se pueden usar los argumentos generales mar, add y col. La función «SplomT()» del paquete “cwhmisc” (Hoffmann, 2012) hace una representación semejante, pero añade el diagrama de dispersión para cada par de variables. Las instrucciones están el script III.10.R. Se usa es mismo ejemplo de antes con medidas morfométricas de peces, cuyos datos están en el archivo Morfología.csv. Después de importar los datos se selecciona solo la familia de peces Sphyraenidae y las variables que están en las columnas 5 a 15, que se guardan en «datos1». Con el argumento «hist="b"» se especifica que el gráfico de la diagonal sea un histograma y la curva de densidad de los datos. Con «cex.diag» y «h.diag» se define el tamaño y la posición vertical de las etiquetas que muestran las variables en la diagonal. Con «cex.diag» se define el color de las barras del histograma. Con «colYonX» y «colXonY» se definen los colores de la línea de suavizado que se representa para las variables x e y, respectivamente.
¾ ¾ ¾ ¾ ¾
library(cwhmisc) datos<-read.csv2("Morfología.csv",header=TRUE,encoding="latin1") attach(datos) datos1 <- datos[Familia=="Sphyraenidae",5:15] SplomT(datos1, mainL = "Familia Sphyraenidae", xlabL="Variables morfométricas", hist="b", cex.diag = 0.6, h.diag=0.4, hist.col="green", colYonX = "red", colXonY = "blue") Función SplomT (paquete cwhmist)
data: data frame con las variables a correlacionar. mainL: título del gráfico. xlabL: leyenda del eje x. hist: tipo de gráfico de la diagonal: "h" es histograma, "d" es curva de densidad y "b" son ambos gráficos: hist = "h". hist.col: color de las barras del histograma. cex.diag: tamaño de las etiquetas que muestran las variables en la diagonal: cex.diag = 1. h.diag: posición vertical de las etiquetas que muestran las variables en la diagonal: h.diag=0.4. adjust: factor de ajuste de suavizado en la curva de densidad: adjust = 1. colYonX y colXonY: color de la línea de suavizado para la variable y sobre x, y de x sobre y: colYonX = "red" y colXonY = "blue".
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
152
Familia Sphyraenidae
M2
-0.41
0.41
0.37
-0.23
-0.38
0.69
-0.49
-0.49
0.4
-0.07
M3
-0.71
-0.23
0.69
0.54
-0.46
0.66
0.58
-0.52
-0.19
M4
0.17
-0.76
-0.69
0.49
-0.82
-0.79
0.72
0.24
-0.02
-0.06
0.65
-0.06
-0.03
-0.12
-0.36
M6
0.78
-0.24
0.83
0.79
-0.58
-0.4
M7
-0.39
0.88
0.93
-0.57
-0.38
M8
-0.41
-0.43
0.33
-0.16
M9
0.97
-0.75
-0.38
M10
-0.72
-0.38
M11
0.24
M5
M12 III.9. Diagramas de Venn y Euler Estos diagramas se usan para mostrar gráficamente la agrupación entre conjuntos, representando cada conjunto mediante un círculo o una elipse. La posición relativa en el plano de tales círculos muestra la relación entre los conjuntos. Se puede usar la función «venneuler()» del paquete “venneuler” y, para su correcto funcionamiento, quizás sea necesario instalar tambien el paquete “rJava” (Urbanek, 2012), si no lo hace automáticamente. Las instrucciones están en el script III.11.R. La forma más fácil de realizar el diagrama es como se muestra a continuación. Simplemente hay que definir en un vector, el tamaño relativo de los conjuntos, por ejemplo «A=0.1», y el grado de solapamiento ente cada uno de ellos, por ejemplo «"C&D"=0.4». Debido a que el dispositivo (device) de exportación a la pantalla «windows()» a veces no reconoce la semi-transparencia, si se exporta el
GRÁFICOS AVANZADOS
153
gráfico a la pantalla, como hacemos siempre por defecto, luego al copiar como metafile o bitmap y pegarlo en otro sitio, no se verá el gráfico debido al problema de la semi-transparencia. Por ello, en este caso se especifica que se exporte a otro dispositivo, en concreto a un archivo png, del cual se puede importar el gráfico posteriormente desde cualquier otro programa (véase el Capítulo I para más información sobre los tipos de dispositivos de exportación de gráficos).
¾ library(venneuler) ¾ vd <- venneuler(c(A=0.1, B=0.5, C=1.1, D=3.4, "A&B"=0, "A&C"=0.1, "B&C"=0.5, "C&D"=0.4)) ¾ png(filename="Venn y Euler.png", units="px", width = 1200, height = 1200, pointsize=24) ¾ plot(vd,main="Diagrama de Venn y Euler",cex.main=2.2) ¾ dev.off()
III.10. Gráficos de variables cualitativas en función de variables cuantitativas La función «plot.freqMAP()» del paquete “freq.MAP” (Payami y col. 2009; McCulloch, 2012) permite representar frecuencias en función de una variable
154
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
cuantitativa, y comparar la razón de ventajas (odds ratio) para ver si existen diferencias significativas. Las instrucciones están en el script III.12.R. El ejemplo, el cual está en el archivo Color.csv, contiene datos del color del cuerpo (rojo y azul) y del pico (rojo y azul), y la combinación de ambos en lo que se define como patrón de color, de dos especies de aves. Después de cargar los paquetes e importar los datos, con la función «write.dbf()» del paquete “foreign” (DebRoy y Bivand, 2012), se graban los datos en otro archivo con extensión dbf para pasar las variables que son factor a carácter. Posteriormente con la función «read.dbf()» se vuelve a cargar ese archivo con extensión dbf y se guarda como «datos1». Con la función «freqMAP()» se convierten los datos en un objeto con la estructura que requiere la función «plot.freqMAP()». Se hace un objeto para la especie 1 «fm.Sp1» y otro para la especie 2 «fm.Sp2», usando la variable cualitativa patrón de color, que combina color del cuerpo y del pico, y la cuantitativa latitud. En el primer panel gráfico se evalúan las diferencias en el patrón de color, es decir, la combinación de color del cuerpo y del pico a lo largo de diferentes latitudes. En la función «plot.freqMAP()», el argumento lógico «show.p.value. legend» define si se ponen en una leyenda los niveles de significación empleados. El método utiliza un procedimiento bayesiano para estimar los parámetros de la distribución multinomial, que luego le sirve para encontrar los límites de confianza y valores p mediante un algoritmo que utiliza técnicas de remuestreo (bootstrap), es decir, genera un número elevado de muestras aleatorias (aparentemente 100.000) y calcula con ellas los límites y valores p. Con «type» se define el tipo de gráfico que puede ser "freq" o "or". El argumento «p.value.bar.alpha» es un vector con dos valores que son las probabilidades de corte que se usan para contrastar la significanción y se muestran en las barras inferiores. En este ejemplo se representan tres grupos: CuerpoAPicoR, CuerpoRPicoA y CuerpoRPicoR.
¾ ¾ ¾ ¾ ¾ ¾
library(foreign); library(freqMAP) datos<-read.csv2("Color.csv",header=TRUE,encoding= "latin1") write.dbf(datos, "Color.dbf", factor2char = TRUE, max_nchar = 254) datos1<-read.dbf("Color.dbf",as.is=TRUE) attach(datos1) fm.Sp1 <- freqMAP(datos1[Especie=="Sp1",c("Lat","Patrón")], x=seq(0,20, by=5), x.label="Latitud",hw=5) ¾ fm.Sp2 <- freqMAP(datos1[Especie=="Sp2",c("Lat","Patrón")], x=seq(0,20, by =5), x.label="Latitud",hw=5) ¾ windows(9,12) ¾ plot.freqMAP(fm.Sp1, fm.Sp2, legend=c("Especie 1", "Especie 2"), show.p.value.legend=TRUE, type="freq", p.value.bar.alpha = c(0.05, 0.01), cex=2, cex.axis=1.6, cex.lab= 1.6, cex.main =2, pch.x=17, pch.y=16, cex.legend=1.5) El panel gráfico que se obtiene muestra que hay diferencias entre las dos especies en el gradiente latitudinal, en el patrón de color cuerpo azul/pico rojo, y en el patrón cuerpo rojo/pico azul. Sin embargo, la proporción de individuos fue igual (sin diferencia estadísticamente significativa) lo largo del gradiente latitudinal en el patrón cuerpo rojo/pico rojo.
GRÁFICOS AVANZADOS
155
Especie 1 Especie 2
0.4 0.0
Freq.
0.8
"CuerpoAPicoR"
p < 0.05 p < 0.01
0
5
10
15
20
15
20
15
20
Latitud
0.0 0.2 0.4 0.6 0.8
Freq.
"CuerpoRPicoA" Especie 1 Especie 2
p < 0.05 p < 0.01
0
5
10 Latitud
Especie 1 Especie 2
0.4 0.0
0.2
Freq.
0.6
0.8
"CuerpoRPicoR"
p < 0.05 p < 0.01
0
5
10 Latitud
Si en el script anterior se usa «type="or"» en vez de «type="freq"» se obtiene el segundo panel gráfico en el que se representan las OR (odds ratio o razón de predominios) para cada par de categorías de la variable de recuento, comparando las dos especies. Hay que eliminar también el argumento «legend» ya que no se utiliza cuando «type="or"». Así, en el primer gráfico del panel se muestra la relación de predominios entre las categorías cuerpo rojo/pico azul y cuerpo azul/pico rojo entre la especie 1 y la especie 2. Un valor OR > 1 indica que en la especie 1 predomina la primera categoría sobre la segunda (cuerpo rojo/pico azul sobre cuerpo azul/pico rojo) en mayor medida que en la especie 2. El trazo gris claro (nivel de significación 0,05) u oscuro (nivel de significación 0,01) en la parte baja del gráfico muestra que la OR es significativamente distinta de 1 y, por lo tanto, el patrón de colores está relacionado con la especie, para algunos valores de la variable continua, en este caso la latitud, pero no para otros. Las líneas continuas de color rojo muestran los límites de confianza para la OR, que ayudan a interpretar los resultados. Cuando el valor OR=1, el trazo
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
156
grueso horizontal está dentro del intervalo, podemos aceptar que el patrón de colores de cuerpo y pico no está relacionado con la especie.
1e-02
OR
1e+02
"CuerpoRPicoA" vs. "CuerpoAPicoR"
p < 0.05 p < 0.01
0
5
10
15
20
Latitud
1e-02
OR
1e+02
"CuerpoRPicoR" vs. "CuerpoAPicoR"
p < 0.05 p < 0.01
0
5
10
15
20
Latitud
1e-02
OR
1e+02
"CuerpoRPicoR" vs. "CuerpoRPicoA"
p < 0.05 p < 0.01
0
5
10
15
20
Latitud
En el tercer panel gráfico se cuantifican los cambios considerando los colores de cuerpo y pico por separado, de nuevo a lo largo del gradiente latitudinal. En primer lugar se estructura la matriz de datos de tal forma que las variables color del cuerpo y color del pico se ponen en una sola variable que se denomina «Patrones» y ese nuevo conjunto de datos se asigna a «datos2».
¾ datos2 <- rbind(cbind(datos1[,c("Lon", "Lat", "Especie")], Patrones = Cuerpo, stringsAsFactors= FALSE), cbind(datos1[,c("Lon", "Lat", "Especie")], Patrones= Pico, stringsAsFactors=FALSE)) ¾ attach(datos2)
GRÁFICOS AVANZADOS
157
¾ fm1.Sp1 <- freqMAP(datos2[Especie=="Sp1",c("Lon","Patrones")], x=seq(0,20, by=5), x.label = "Latitud",hw=5) ¾ fm1.Sp2 <- freqMAP(datos2[Especie=="Sp2",c("Lon","Patrones")], x=seq(0,20, by=5), x.label="Latitud",hw=5) ¾ windows(10,12) ¾ plot.freqMAP(fm1.Sp1,fm1.Sp2,legend=c("Especie 1","Especie 2"), show.p.value.legend=FALSE, type="freq", p.value.bar.alpha = c(0.05, 0.01), cex=2,cex.axis=1.6, cex.lab= 1.6, cex.main =2, pch.x=17, pch.y=16, cex.legend=1.5) Ahora no se observan diferencias significativas en el color del pico o del cuerpo entre las dos especies. Por lo tanto, es la combinación de colores del cuerpo y pico lo que cambia entre especies en el gradiente latitudinal y no los colores por separado.
0.2
Especie 1 Especie 2
0.0
Freq.
0.4
"CuerpoA"
0
5
10
15
20
15
20
15
20
15
20
Latitud
0.5
Especie 1 Especie 2
0.2
Freq.
"CuerpoR"
0
5
10 Latitud
0.4
Especie 1 Especie 2
0.1
Freq.
"PicoA"
0
5
10 Latitud
0.4
Especie 1 Especie 2
0.1
Freq.
"PicoR"
0
5
10 Latitud
158
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Función plot.freqMAP (paquete freq.MAP) x,y: objetos freqMAP, generalmente obtenidos con la función freqMAP(). legend: vector que puede tener dos caracteres con la leyenda de x e y, que no se utiliza si type=”or”: legend = NULL. show.p.value.legend: si es TRUE se muestran los valores p bayesianos en una leyenda: show.p.value.legend = FALSE. type: tipo de gráfico que puede ser "freq" o "or": type = "freq". p.value.bar.alpha: un vector con dos valores que son las probabilidades de corte que se usan para contrastar la significación y se muestran en las barras inferiores: p.value.bar.alpha = c(0.05, 0.01). p.value.bar.color: colores de las probabilidades que se muestran en las barras inferiores: p.value.bar.color=c("gray90","darkgray"). pch.x: tipo de símbolo de x: pch.x=2. lty.x: tipo de línea para los intervalos de confianza de x: lty.x=1. lwd.x: grosor de línea para los intervalos de confianza de x: lwd.x=1. col.x: color de los símbolos de x: col.x="red". pch.y: tipo de símbolo de y: pch.y=1. lty.y: tipo de línea para los intervalos de confianza de y: lty.y=2. lwd.y: grosor de línea para los intervalos de confianza de y: lwd.y=1. col.y: color de los símbolos de y: col.y="blue". cex.legend: tamaño de texto de la leyenda: cex.legend=1. layout.matrix: estructura del panel. Por ejemplo, si antes se pone la función par(ask=TRUE), layout.matrix=c(1,1) graficaría solamente una figura de cada vez, en vez de poner todas las figuras en la misma ventana. En caso de no especificar nada, se muestran todas las figuras en forma vertical: layout.matrix = NULL. Se pueden usar los argumentos generales cex, cex.axis, cex.lab, cex.main, xlim e ylim.
III.11. Distribuciones de variables cualitativas La función «cd_plot()» permite representar como varía una variable cualitativa en función de una variable cuantitativa. La función «spine()» también permite ver la distribución de una variable cualitativa en base a cambios en una cuantitativa, mostrando ésta en forma de intervalos. Ambas funciones están en el paquete “vcd” (Meyer y col., 2012). Las instrucciones están en el archivo III.13.R. Se usa el ejemplo del archivo Tabla de vida.csv, en el cual hay datos de la edad a la que murieron mujeres y hombres en Vigo (España) en el año 2010. Para el primer gráfico en la función «cd_plot()» se pone la fórmula con las variables a representar, donde la primera variable es la categórica. Con el argumento «bw» se especifican parámetros para la obtención de la función de densidad y las distintas opciones disponibles se pueden consultar en la función
GRÁFICOS AVANZADOS
159
«density()». En la representación se observa como hasta los 78 años la proporción de sexos es más o menos equilibrada pero, a partir de esa edad, mueren más hombres que mujeres y el porcentaje de mujeres es claramente superior.
library(vcd) datos<-(read.csv2("Tabla de vida.csv", header=TRUE, encoding= "latin1")) attach(datos) cd_plot(Sexo ~ Edad, data = datos, main="TABLA DE VIDA", bw = 3, xlab="Edad (años)") TABLA DE VIDA 1
Mujer
0.8
0.6 Sexo
0.4
Hombre
¾ ¾ ¾ ¾
0.2
0 30
40
50
60
70
80
90
100
Edad (años)
Función cd_plot (paquete vcd) x e y: variables a representar. También se puede poner una fórmula del tipo y ~ x. data: opcionalmente se puede indicar el data frame con los datos. ylab_tol: valor numérico para separar etiquetas en el eje y si solapan: ylab_tol = 0.05. n: número de puntos espaciados equidistantemente para los cuales se estima la densidad: n = 512. bw: tipo de alisado en la estimación de la función de densidad. Las distintas opciones disponibles se pueden consultar en el menú de ayuda de la función density(): bw = "nrd0".
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
160
Función cd_plot (Continuación) from y to: extremos izquierdo y derecho que limitan el rango para calcular la densidad: from = NULL y to = NULL. margins: márgenes del gráfico: margins = c(5.1, 4.1, 4.1, 3.1). gp: parámetro que permite con la función gpar() modificar el patrón de colores: gp = gpar(). newpage: si es TRUE es un gráfico nuevo que elimina cualquier otro anterior: newpage = TRUE. pop: si es TRUE las características de la ventana de visualización se quitan después de crear el gráfico: pop = TRUE. Se pueden usar los argumentos generales main, xlab e ylab.
En el segundo gráfico se usa la función «spine()», en la cual con el argumento «break» se define el número de intervalos en la variable del eje x.
¾ spine(Sexo ~ Edad, data = datos, main="TABLA DE VIDA", xlab="Edad (años)", breaks = 10) TABLA DE VIDA 1
Mujer
0.8
Sexo
0.6
Hombre
0.4
0.2
0 20 50
60
70
80 Edad (años)
90
100
GRÁFICOS AVANZADOS
161
Función spine (paquete vcd) x e y: variables a representar. También se puede poner una fórmula del tipo y ~ x. breaks: número de intervalos que se desea en la variable del eje x: breaks = NULL. off: desplazamiento vertical entre barras (en porcentaje): off = NULL. name: nombre del gráfico: name = "spineplot". El resto de argumentos ylab_tol, margins, gp, newpage y pop se explicaron en la función cd_plot(). Se pueden usar los argumentos generales main, xlab, ylab e ylim.
III.12. Gráficos para tablas de contingencia Otra función para variables cualitativas es «assoc()» del paquete “vcd” (Meyer y col., 2003; Meyer y col., 2006; Meyer y col., 2012), que permite representar tablas de contingencia 2xk. En el archivo Fumador.csv hay datos del grado en que fuman hombres y mujeres, en diferentes centros de trabajo y en función de sí los padres fumaban o no. Las instrucciones están en el archivo III.14.R. Después de importar los datos y cargarlos en memoria, con la función «with()» se transforman en una tabla. Con esta función se puede poner el orden que se desee en la tabla, independientemente del orden de las variables en los datos. Posteriormente se genera la tabla de contingencia con «margin.table()» en la cual se ha seleccionado la variable que indica si los padres fuman (columna 3 en la tabla anteriormente creada) y el grado de fumador (columna 4 en la tabla anteriormente creada). En la función «assoc()» se introduce la tabla de contingencia, en este caso «TC». El paquete “vcd” (Meyer y col., 2003; Meyer y col., 2006; Meyer y col., 2012) tiene una forma particular de modificar la posición, tipo de letra, tamaño de letra, etc. de los títulos y leyendas de los ejes. Por ejemplo, para modificar el tipo y tamaño de letra del título, leyenda de las variables y leyenda de las categorías de las variables se usan los argumentos «main_gp», «gp_varnames» y «gp_labels», respectivamente. En todos ellos se debe hacer con «gpar» si se introducen varias modificaciones. La posición y rotación de los textos se modifica con «labeling_args». Para la posición se utiliza «offset_» seguido de «varnames» o «labels» si es para las leyendas de las variables o de las categorías de las variables, respectivamente. Para la rotación «rot_» y de nuevo seguido de «varnames» o «labels».
¾ library(vcd) ¾ datos<-(read.csv2("Fumador.csv", header=TRUE, encoding="latin1")) ¾ attach(datos)
162
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
¾ tabla<-with(datos, table(Sexo, Trabajo, Padres, Grado)) ¾ TC <- margin.table(tabla, c(3, 4)) ¾ assoc(TC,main = "RELACIÓN ENTRE GRADO FUMADOR Y PADRES FUMADORES", main_gp=gpar(fontsize = 20, fontface = 2), gp_varnames = gpar(fontsize = 20, fontface = 2), gp_labels=gpar(fontsize = 17, fontface = 2), labeling_args = list(offset_varnames = c(left = -0.5,top = -0.5), offset_labels = c(top=-0.3), rot_labels = c(left=0))) En el gráfico 1, las barras indican si la categoría está por debajo o por encima de la media (línea discontinua). Se observa como el número de no fumadores en los padres que no fuman es muy superior al de fumadores. Además se observa que en todas las categorías que fuman, el número de individuos es menor en el caso de padres no fumadores. Por tanto, parece ser que el hecho de que los padres no fumen favorece que tampoco fumen los hijos. RELACIÓN ENTRE GRADO FUMADOR Y PADRES FUMADORES Grado 1 a 10 cigarrillos
11 a 20 cigarrillos
De 1 a 2 cajetillas
Más de 2 cajetillas
No fuma
Padres
No
Si
El grafico 2 es exactamente igual al anterior, con la simple modificación de introducir el argumento «shade=TRUE». Con este argumento se consigue que aparezcan los resultados de estadístico F2 de Pearson, y se sombrean las categorías que son significativamente diferentes. Se confirma que el número de no fumadores es significativamente mayor en el grupo de padres no fumadores.
¾ assoc(TC, shade=TRUE, main = "RELACIÓN ENTRE GRADO FUMADOR Y PADRES FUMADORES", main_gp=gpar(fontsize = 20, fontface = 2), gp_varnames = gpar(fontsize = 20, fontface = 2), gp_labels=gpar(fontsize = 17, fontface = 2), labeling_args = list(offset_varnames = c(left = -0.5,top = -0.5), offset_labels = c(top=-0.3), rot_labels = c(left=0)))
GRÁFICOS AVANZADOS
163
RELACIÓN ENTRE GRADO FUMADOR Y PADRES FUMADORES Grado 1 a 10 cigarrillos
11 a 20 cigarrillos
De 1 a 2 cajetillas
Más de 2 cajetillas
No fuma Pearson residuals: 5.26
4.00
No
Padres
2.00
0.00
-2.00
Si
-4.10 p-value = 2.4744e-11
En el gráfico 3 se comprueba la capacidad de la función «assoc()» para representar tablas de contingencia 2xk, ya que se representan las tres variables: si los padres fuman, el grado de fumador y los centros de trabajo. El único argumento nuevo es «tl_», el cual se resalta en negrita, y que define si se representan o no las leyendas de variables «varnames» y/o de categorías «labels».
¾ assoc(aperm(tabla), expected = ~ (Grado + Padres) * Trabajo, main = "RELACIÓN ENTRE GRADO FUMADOR, PADRES FUMADORES Y CENTROS DE TRABAJO", main_gp=gpar(fontsize = 20, fontface = 2), gp_varnames = gpar(fontsize = 20, fontface = 2), gp_labels=gpar(fontsize = 12, fontface = 2), labeling_args = list(just_labels = c(Grado = "left"), offset_labels = c(right = 0.5), offset_varnames = c(right = 1.5,left=-0.5,top=0.5), rot_labels = c(right = 0), tl_varnames = c(Grado = TRUE)))
Más de 2 cajetillas De 1 a 2 cajetillas 11 a 20 cigarrillos 1 a 10 cigarrillos
No
Si Centro 1 Centro 2 Pearson Centro 3 residuals: 4.27 Centro 4 4.00
Centro 1 Centro 2 Centro 3 Centro 4
Centro 1
2.00
Centro 3 Centro 4
Centro 1 Centro 2
Trabajo
Centro 2
0.00
Centro 3 Centro 4
Centro 1 No fuma
Grado
RELACIÓN ENTRE GRADO FUMADOR, PADRES FUMADORES Y CENTROS DE TRABAJO Padres
Centro 2 Centro 3 Centro 4 Hombre
Mujer
Hombre
Mujer
-2.00 -2.42 p-value = 4.1155e-12
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
164
En el gráfico 4, se observa que con la función «mosaicplot()» del paquete “graphics” es posible obtener una representación similar. Con el argumento «type» se especifica el tipo de residuo que se quiere mostrar. Con «cex.axis» se puede modificar el tamaño de las etiquetas de las variables. El argumento «dir» es un vector que indica si se representa primero en vertical «"v"» u horizontal «"h"». Con «off» se especifica el espacio entre los niveles del mosaico.
¾ par(cex.lab=1.5) ¾ mosaicplot(Padres ~ Grado, main="RELACIÓN ENTRE GRADO FUMADOR Y PADRES FUMADORES", shade = TRUE, type="pearson", cex.axis=0.8, dir=c("v","h"), off=c(5,15)) RELACIÓN ENTRE GRADO FUMADOR Y PADRES FUMADORES Si
0:2 <-4
-4:-2
-2:0
Más de 2 cajetillas De 1 a 2 cajetillas
Standardized Residuals:
No fuma
Grado
11 a 20 cigarrillos
2:4
>4
1 a 10 cigarrillos
No
Padres
GRÁFICOS AVANZADOS
165
Función assoc (paquete vcd) x: tabla de contingencia. row_vars: vector con las variables de las filas: row_vars = NULL. col_vars: vector con las variables de las columnas: col_vars = NULL. compress: si es TRUE el espacio entre filas y columnas es fijo: compress = TRUE. xlim e ylim: vector con el número de columnas y filas: xlim = NULL e ylim = NULL. spacing: función que define los espacios entre los elementos del gráfico: spacing = spacing_conditional(sp = 0). spacing_args: lista de argumentos para la función a colocar en spacing: spacing_args = list(). split_vertical: si es TRUE se despliega la variable en columnas, si es FALSE en filas : split_vertical = NULL. keep_aspect_ratio: si es TRUE la razón de aspecto se mantiene constante: keep_aspect_ratio = FALSE. xscale e yspace: añade espacios adicionales entre los rectángulos: xscale = 0.9 e yspace = unit(0.5, "lines").
Función mosaicplot (paquete graphics) x: tabla de contingencia o fórmula. sort: vector para ordenar las variables: sort = NULL. off: vector indicando el porcentaje de separación entre los niveles del mosaico: off = NULL. dir: vector con el orden de orientación, primero vertical y luego horizontal c("v", "h") o viceversa: dir = NULL. color: vector con los colores para el sombreado: color = NULL. shade: si es TRUE se ponen los valores de los residuos: shade = FALSE. margin: lista de vectores con los valores de los márgenes en un modelo logarítmico: margin = NULL. cex.axis: tamaño de letra de las etiquetas de las variables: cex.axis = 0.66. type: define el tipo de residuos: "pearson" (Chi cuadrado de Pearson), "deviance" (razón de verosimilitud Chi cuadrado), o "FT" (residuos de Freeman-Tukey).
III.13. Gráficos para grandes conjuntos de datos Uno de los problemas que se plantea al realizar una gráfica cuando hay muchos datos es que no es posible tener una idea de cuantos datos hay en las zonas en las que hay solapamiento. El paquete “IDP.misc” (Locher y col., 2012) tiene varias funciones para realizar diferentes tipos de gráficos específicos para series con muchos datos.
166
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
III.13.1. DISPERSIÓN Se utiliza la función «iplot()» del paquete “IDP.misc” (Locher y col., 2012). Las instrucciones están en el script III.15.R. Los datos, que están en el archivo Clima.csv, son valores mensuales de temperatura del agua y del aire, y la intensidad del viento de este a oeste (Viento.X) y de sur a norte (Viento.Y) a 42º norte y 10º oeste, desde 1925 a 1997. En primer lugar se representa un gráfico en el cual la barra de colores no tiene una escala del número de datos que se solapan. En la función «iplot()», el argumento «pixs» define el tamaño del píxel en mm y «d.main» la distancia del título al gráfico. A la vez que se representa este primer gráfico, ya se calcula el número máximo de datos que se solapan por píxel y se guarda en «zmax».
¾ ¾ ¾ ¾
library(IDPmisc) datos<-read.csv2("Clima.csv", header=TRUE, encoding="latin1") attach(datos) zmax<-iplot(Temperatura.agua,Temperatura.aire, pixs=3, d.main=1, xlab= "Temperatura del agua (ºC)", ylab="Temperatura del aire (ºC)", cex.lab=1.5, main="42º Norte 10º Oeste", cex.main=1.7)
En el siguiente gráfico, con el argumento «zmax=zmax» se define el máximo valor en la escala de colores del número de datos que se solapan por píxel. Con «border=T» se especifica que se represente un borde separando cada color en la barra de colores.
GRÁFICOS AVANZADOS
167
¾ iplot(Temperatura.agua,Temperatura.aire,zmax=zmax, pixs=3, d.main=1, xlab="Temperatura del agua (ºC)", ylab="Temperatura del aire (ºC)", cex.lab=1.5,main="42º Norte 10º Oeste", cex.main=1.7, border=T)
III.13.2. MATRICES DE GRÁFICOS Se utiliza la función «ipairs()» del paquete “IDP.misc” (Locher y col., 2012). Las instrucciones están en el script III.16.R. Se utilizan de nuevo los datos climáticos que están en el archivo Clima.csv. Después de importar los datos se seleccionan las variables de temperatura y viento, en las columnas 3 a 6. Al igual que antes, en primer lugar se representa un gráfico en el cual la barra de colores no tiene una escala del número de datos que se solapan.
¾ ¾ ¾ ¾ ¾ ¾
library(IDPmisc) datos<-read.csv2("Clima.csv", header=TRUE, encoding="latin1") attach(datos) datos1<-datos[ ,3:6] zmax <- ipairs(datos1, pixs=2, main="42º Norte 10º Oeste", d.main=1) ipairs(datos1, pixs=2, zmax=zmax, main="42º Norte 10º Oeste",d.main=1, border=T)
168
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
GRÁFICOS AVANZADOS
169
Funciones iplot e ipairs (paquete IDP.misc) x, y: variables para los ejes x e y. pixs: tamaño del píxel en mm: pixs = 1. zmax: máximo número de puntos que se solapan por píxel: zmax = NULL. ztransf: función para transformar el número de puntos por pixel para definir los colores: ztransf = function(x){x}. colramp: escala de colores de la barra: colramp = IDPcolorRamp. d.main: distancia vertical entre el título y el gráfico: d.main = 1. legend: si es TRUE se muestra la barra de colores: legend = TRUE. d.legend: distancia horizontal entre la leyenda y el borde derecho del gráfico: d.legend = 1. nlab.yaxis y nlab.xaxis: número de marcas de etiquetas en los ejes: nlab.xaxis = 5 y nlab.yaxis = 5. minL.axis: longitud mínima de las abreviaturas de los niveles del factor, que se utiliza para etiquetar los ejes: minL.axis = 3. border: si es TRUE se pinta un borde separando cada color en la barra de colores: border = FALSE. En el caso de la función ipairs() se pone una matriz o data frame en vez de los valores de x e y, se utiliza nlab.axis en vez de nlab.yaxis y nlab.xaxis y se añaden los siguientes argumentos: lab.diag: etiquetas de las columnas de la matriz, que se ponen en la diagonal. cex.diag: tamaño de las etiquetas de la diagonal en relación al valor de cex. Se pueden usar los argumentos generales main, cex, cex.main, cex.lab, cex.axis, xlab, ylab, las, tcl y mgp.
III.13.3. ESPECTROS Los espectros suelen también tener muchos datos y a veces es necesario identificar picos, lo cual se puede hacer con la función «peaks()» del paquete “IDP.misc” (Locher y col., 2012). Las instrucciones están en el script III.17.R. Los datos, que están en el archivo Espectro.csv, consisten en un cromatograma usando HPLC de pigmentos de la especie Alexandrium minutum. Después de importar los datos, en el primer gráfico se carga el paquete y se seleccionan solamente aquellos pigmentos que tengan una absorbancia mayor de 0,0003 y menor de 0,01 y se guardan en «MS1». En la función «peaks()», el argumento «minPH» define la absorbancia mínima, «minPW» la anchura mínima y «thr» el umbral mínimo por debajo del cual la señal no se procesa. Los textos que identifican cada uno de los picos se ponen con la función «text()», en la cual las coordenadas que posicionan los textos se especifican usando la información obtenida con la función «peaks()».
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
170 ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
datos<-read.csv2("Espectro.csv", header=TRUE, encoding="latin1") attach(datos) library(IDPmisc) MS1 <- (datos[Abs>0.0003&Abs<0.01,]) Peaks <- peaks(MS1, minPH=0.0005, minPW=0.06, thr=0.0005) plot(Tiempo, Abs, type="l", xlab="Tiempo (minutos)", ylab="Absorbancia a 440 nm", cex.lab=1.5, ylim=c(0,0.01), cex.axis=1.3) points(Peaks,pch=21, bg="green", cex=1.5) text(Peaks[c(1,2,3,6),],labels=c(expression(paste("Chl ",c["2"])), "Peridina", "Diadinoxantina", "Chl a"), pos=3, offset=0.6) text(Peaks[c(4,5),], labels = c("Diadinoxantina", "Dinoxantina"), pos=4, offset=0.6) mtext(text = expression(paste("Pigmentos de ", italic("Alexandrium minutum"))), cex=2.3, line=0.6)
0.008
Chl a
0.006
Peridina
Diadinoxantina
0.004
Chl c2
0.002
Absorbancia a 440 nm
0.010
Pigmentos de Alexandrium minutum
Diadinoxantina
0.000
Dinoxantina
0
10
20
30
40
Tiempo (minutos) En el segundo gráfico se utiliza la función «DrawChromatogram()» del paquete “OrgMassSpecR” (Dodder, 2012), la cual permite colorear los picos. El inconveniente que presenta esta función es que hay que especificar los intervalos de tiempo de cada uno de los picos que se quiere colorear con el argumento «range». Para poner un color a cada pico es necesario especificar el mismo número de colores que de picos. En caso de poner solamente un color, todos los picos tendrán el color especificado. Para poner los textos que indentifican cada pico se utiliza la información obtenida con la función «peaks()» del paquete mostrado anteriormente.
GRÁFICOS AVANZADOS
171
¾ library(OrgMassSpecR) ¾ DrawChromatogram(Tiempo, Abs, range = list(start = c(10.85, 13, 23.8, 24.5, 25.7, 33.2), stop = c(11.4, 14.5, 24.5, 25.5, 26.2, 34.5)), xlab="Tiempo (minutos)", ylab="", color=c("green", "gold1", "goldenrod3", "goldenrod2", "goldenrod1", "green"), main=expression(paste("Pigmentos de ", italic("Alexandrium minutum"))), cex.main=2, cex.lab=1.3) ¾ mtext("Absorbancia a 440 nm",2, cex=1.3, line=3.2) ¾ text(Peaks[c(1,2,3,6),],labels=c(expression(paste("Chl ", c["2"])), "Peridina", "Diadinoxantina", "Chl a"), pos=3, offset=0.6) ¾ text(Peaks[c(4,5),], labels=c("Diadinoxantina", "Dinoxantina"), pos=4, offset=0.6)
Pigmentos de Alexandrium minutum Chl a 0.008
Absorbancia a 440 nm
Peridina
0.006 Diadinoxantina Chl c2
0.004
Diadinoxantina
0.002 Dinoxantina
0.000 0
10
20
30
40
Tiempo (minutos)
III.13.4. GRÁFICOS POLARES Los datos climáticos o ambientales, en general, son a menudo series con muchos datos, ya que se pueden tomar diariamente, incluso cada hora en muchos casos. Los datos que se usan en el ejemplo son de la Agencia Estatal de Meteorología de España (http://www.aemet.es) y están en el archivo Clima España.csv. Son valores medios diarios de temperatura (ºC) y velocidad del viento en m s-1, así como la precipitación diaria en mm, la duración de la insolación en horas y las presiones mínimas y máximas en hPa, en tres ciudades de España en los años 1990 y 2000. Los datos de temperatura, precipitación y presión por años, meses
172
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
o ciudades se pueden representar facilmente con el gráfico de telaraña mostrado anteriormente. Los datos de intensidad y dirección del viento se representan mejor con gráficos polares. Para ello, usaremos la función «polar.plot()» del paquete “plotrix” (Lemon, 2012). Las instrucciones están en el script III.18.R. Después de cargar el paquete e importar los datos, se realiza una selección de los datos en cuatro data frames de tal forma que se coge solamente el año 1990, las ciudades de Vigo y Huelva, y haciendo la diferenciación entre los meses de Junio a Agosto (verano) y Diciembre a Enero (invierno). Posteriormente se realizan cuatro gráficos con los cuatro data frames creados anteriormente. En la función «polar.plot()» con el argumento «start=90» se define que el primer eje comience a los 90º, y así de esta forma el norte queda hacia arriba en el gráfico (0º). Con «clockwise» se puede indicar si los grados van cambiando en el sentido de las agujas del reloj o a la inversa. Con «radial.lim» se definen los límites de los radios. Después del tercer gráfico se introduce la función «mtext()» para poner el texto en el lado izquierdo. Con los argumentos «at» y «padj» se definen la posición en el gráfico donde queremos escribir el texto y el ajuste del texto perpendicular a la dirección de lectura, respectivamente. De esta forma conseguimos que el título quede centrado en el panel, entre los cuatro gráficos.
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
library(plotrix) datos<-read.csv2("Clima España.csv", header=TRUE, encoding="latin1") attach(datos) datos1<-subset(datos[Año==1990 & Ciudad=="Vigo" & Mes %in% c("6","7","8") ,]) datos2<-subset(datos[Año==1990 & Ciudad=="Huelva" & Mes %in% c("6","7","8"),]) datos3<-subset(datos[Año==2000 & Ciudad=="Vigo"& Mes %in% c("12","1","2"),]) datos4<-subset(datos[Año==2000 & Ciudad=="Huelva" & Mes %in% c("12","1","2"),]) par(mfrow=c(2,2)) polar.plot(datos1$Vel.Viento,datos1$Dir.Viento,main="Vigo (Junio, Julio y Agosto)", start=90, clockwise=TRUE, lwd=3, line.col=4, radial.lim=c(0,8)) polar.plot(datos2$Vel.Viento,datos2$Dir.Viento,main="Huelva (Junio, Julio y Agosto)", start=90,clockwise=TRUE,lwd=3,line.col=4,radial.lim=c(0,8)) polar.plot(datos3$Vel.Viento, datos3$Dir.Viento, main="Vigo (Diciembre, Enero y Febrero)", start=90, clockwise=TRUE, lwd=3, line.col=4, radial.lim= c(0,8)) mtext(paste("Viento",sep="\n","m/s"), 3, 1, at=11.5, las=1, cex=1.7, font=2, padj=-0.5) polar.plot(datos4$Vel.Viento,datos4$Dir.Viento, main="Huelva (Diciembre, Enero y Febrero)", start=90, clockwise=TRUE, lwd=3, line.col=4, radial.lim= c(0,8))
GRÁFICOS AVANZADOS Huelva (Junio, Julio y Agosto) 0 340 20 320 40
Vigo (Junio, Julio y Agosto) 0 340 20 320 40 300
300
60
280 0
2
4
6
260 240
80 8 100 120
220
140 200
180
Vigo (Diciembre, Enero y Febrero) 0 340 20 320 40 60
280
80 0
2
4
6
260 240
8 100 120
220
140 200
180
160
60
280 0
2
4
6
260 240
Viento m/s
160
300
173
80 8 100 120
220
140 200
180
160
Huelva (Diciembre, Enero y Febrero) 0 340 20 320 40 300
60
280
80 0
2
4
6
260 240
8 100 120
220
140 200
180
160
Función polar.plot (paquete plotrix) lengths: vector numérico o variables a representar. polar.pos: vector numérico con posiciones en un rango de 0 a 360º: polar.pos=NULL. labels: etiquetas en la periferia del círculo exterior. label.pos: posición de las etiquetas en grados: label.pos=NULL. start: posición de inicio de la primera variable: start = 0. clockwise: si es TRUE los ángulos se incrementan en el sentido de las agujas del reloj: clockwise=FALSE. rp.type: define si se pinta un polígono "p", radios "r" o símbolos "s": rp.type="r". Se pueden usar también los argumentos de la función radial.plot().
III.14. Gráficos para pruebas aleatorias Las pruebas aleatorias o pruebas permutacionales se basan en la asignación aleatoria. El estadístico de contraste se obtiene de forma repetida para un número elevado de permutaciones aleatorias de los datos experimentales originales. La proporción de valores mayores o iguales al valor obtenido en el
174
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
experimento constituyen el valor p del contraste. Pueden ser uni, bi o multivariados. La función «biv.test()» del paquete “adehabitat” (Calenge, 2012) permite hacer pruebas aleatorias bivariadas. Las instrucciones están en el script III.19.R. En el ejemplo se usan datos de medidas de diferentes peces, que están en el archivo Morfología.csv, y se selecciona un grupo determinado. Luego se comprueba si los individuos que están en el archivo Morfología1.csv pertenecen a la población seleccionada, utilizando los valores de dos variables para el contraste. Después de cargar el paquete e importar los datos, se seleccionan los individuos del género Pagellus. Es necesario crear un data frame con las variables que se van a usar para determinar si el individuo pertenece a la población, en este caso las variables M6 y M12. Posteriormente se importa el archivo, donde están los individuos, tres casos, para los que queremos contrastar si pertenecen a esa población. Con «length()» obtenemos información del número de filas de este archivo que usaremos luego para delimitar el bucle. El argumento «par(ask=T)» da la instrucción de que se pregunte antes de representar el gráfico, por ello hay que ir pulsando enter para que vayan saliendo las diferentes gráficas. En el bucle, en primer lugar se asigna el valor para «point» que son los valores de M6 y M12 de cada uno de los tres casos que hay en el archivo Morfología1.csv. En primer valor de «point» será el eje x y el segundo valor el eje y en el gráfico. En la función «biv.test()» el argumento «point» tiene los valores de las variables, en este ejemplo M6 y M12, del individuo que se quiere comprobar si pertenece a la población. Con «points=T» se especifica que se muestren los puntos en el diagrama de dispersión, que pertenecen en nuestro ejemplo a los valores de M6 y M12 de las especies del género Pagellus. Con el argumento «br» se define el número de barras del histograma.
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
library(adehabitat) datos<-read.csv2("Morfología.csv",header=TRUE,encoding="latin1") datos1 <- datos[datos$Género=="Pagellus",] attach(datos1) dfxy <- data.frame(M6, M12) datos2<-read.csv2("Morfología1.csv",header=TRUE,encoding="latin1") attach(datos2) n<-length(M12) par(ask=T) for (i in 1:n){ point = c(datos2[i,"M6"], datos2[i,"M12"]) sub= paste("Género", sep="\n", datos2[i,"Género"]) biv.test(dfxy, point, points=TRUE, Pcol="red", col="lightblue", br=20, sub=sub, side= "top")}
Se obtienen 3 gráficos. En todos ellos el gráfico de dispersión representa los valores de las variables M6 y M12 de las especies seleccionadas del género Pagellus, junto con el histograma y la función de densidad. En el primer caso, que es un individuo del género Roeboides, se observa que sus valores de M6 y M12, que se representan por el punto rojo, quedan por fuera de los valores de la población y, por ello, el test concluye que el individuo no pertenece a la población con una p < 0,05 para ambas variables. Es decir, no sería un individuo del género Pagellus, como efectivamente es el caso ya que pertenece al género
GRÁFICOS AVANZADOS
175
Roeboides. En el gráfico dx es la separación entre lineas horizontales y dy la separación entre líneas verticales de la trama interior del gráfico. p = 0.012
Género Roeboides p = 0.012
dx = 0.0048 dy = 0.0048
El segundo individuo que pertenece al género Boops, la probabilidad es menor de 0,005 en el caso de la variable M12 y, por tanto, se concluye que no pertenece a la población de Pagellus. p = 0.106
Género Boops dx = 0.0048 dy = 0.0048
p = 0.035
El tercer y último gráfico, cuyo individuo pertenece al género Pagellus, la probabilidad es mayor de 0,05 para ambas variables y, por tanto, se concluye que si pertenece a la población.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
176
p = 0.188
Género Pagellus dx = 0.0048 dy = 0.0048
p = 0.494
Función biv.test (paquete adehabitat) dfxy: data frame con los valores de las dos variables. point: valores de las dos variables anteriores para el individuo a contrastar. br: número de barras del histograma: br = 10. points: si es TRUE se muestran los puntos de las coordenadas: points = TRUE. density: si es TRUE se muestra la curva de densidad en el histograma: density = TRUE. kernel: si es TRUE se muestra la función de densidad bivariada: kernel = TRUE. o.include: si es TRUE se incluye el origen en la figura: o.include = FALSE. Pcol: color del punto que muestra la posición en la figura del individuo que se está contrastando. h: vector con el ancho de banda para los estimadores de densidad de x e y. side: define la posición de las leyendas dx (valor de la separación entre líneas verticales) y dy (valor de la separación entre líneas horizontales), que puede ser "top", "bottom" o "none". La función «biv.plot()» tiene los mismos argumentos a excepción de Pcol, ya que no se analiza la probabilidad de pertenencia a la población de ningún individuo y, por ello, no se representa la posición del individuo en la figura. Se pueden usar los argumentos generales pch, cex y col.
GRÁFICOS AVANZADOS
177
III.15. Diagrama de Taylor Este tipo de representación permite comparar modelos, por ejemplo varios modelos de regresión, para determinar cual de ellos es más predictivo. Se utiliza mucho con modelos climáticos. Para representarlo se puede utilizar la función «taylor.diagram()» del paquete “plotrix” (Lemon, 2012). Las instrucciones están en el script III.20.R. El ejemplo, que está en el archivo Modelos.csv, consiste en los valores observados y las predicciones de cuatro modelos de la temperatura mensual a lo largo del año. En este caso es necesario explicar primero la gráfica antes de pasar a ver los argumentos de la función. En el diagrama de Taylor los modelos se comparan en base al coeficiente de correlación, la amplitud de su variación (desviación estándar) y el error cuadrático medio (RMS). El coeficiente de correlación se muestra en el arco externo derecho del gráfico (valores de 0 a 1). Los arcos punteados muestran los valores de la desviación estándar (valores de 0 a 10 en este ejemplo). El arco que no es punteado con un valor aproximado de 6,35, muestra la desviación estándar de los valores observados y se usa como referencia. Por último, los arcos que en este ejemplo tienen valores de 10 y 5, son los RMS. El modelo mejor será aquel que tenga un coeficiente de correlación mayor, un valor de RMS más pequeño y que su desviación estándar esté más cerca de la desviación estándar de los valores observados, que en este ejemplo es la línea que muestra la desviación estándar de 6,35. Por tanto, el modelo con el símbolo naranja, el modelo 3, es el más predictivo. En la función simplemente hay que poner la variable que tiene los valores observados y la variable que tiene los valores predichos. El argumento «pos.cor» si es «TRUE» representa la gráfica solamente con los coeficientes de correlación positivos. En la segunda gráfica del script se muestra como representar el diagrama con los valores negativos y positivos del coeficiente de correlación. Con «show.gamma» se indica si representa los arcos de los RMS. El argumento «sd.arcs» define si se representan los arcos de las desviaciones estándar. El argumento «ref.sd» indica si se pinta el arco de la desviación estándar de los valores observados que se usa como referencia. Con «pcex» se define el tamaño de los símbolos. Con «normalize» se especifica si se tipifican los datos, de tal forma que la desviación estándar de los valores observados, que se usa como referencia, tenga un valor de 1. En el script se usa la función «polygon()» para tapar textos en inglés, que no se pueden modifican, y reemplazarlos por textos en castellano con la función «text()».
¾ ¾ ¾ ¾
library(plotrix) Datos<-read.csv2("Modelos.csv", header=TRUE, encoding="latin1") attach(Datos) taylor.diagram(Observado,Modelo1, main="Modelos de predicción de temperatura", pos.cor=T, show.gamma=T, sd.arcs=T, ref.sd=T, pcex=2, normalize=F, xlab= "Desviación estándar (ºC)", ylab="Desviación estándar (ºC)") ¾ taylor.diagram(Observado,Modelo2, main="", pos.cor=T, show.gamma=T, sd.arcs=T, ref.sd=T, pcex=2, normalize=F, xlab="",ylab="", add=T, col="blue",pch=15)
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
178
¾ taylor.diagram(Observado,Modelo3, main="", pos.cor=T, show.gamma=T, sd.arcs=T, ref.sd=T, pcex=2, normalize=F, xlab= "", ylab="",add=T, col="orange",pch=17) ¾ taylor.diagram(Observado,Modelo4, main="", pos.cor=T, show.gamma=T, sd.arcs=T, ref.sd=T, pcex=2, normalize=F, xlab="", ylab="",add=T, col="green",pch=18) ¾ polygon(x = c(7.7,8,10,10.4), y = c(8.8,11.2,9.2,8.1), col = "white", border = NA) ¾ text(9,9.5,paste("Coeficiente de",sep="\n", "correlación")) Modelos de predicción de temperatura 0.1
0.2
0.3 0.4
10
0.5 0.6
6
0.8
0.9
4
5
0.95
2
Desviación estándar (ºC)
8
10
Coeficiente de correlación Correlation 0.7
0
0.99
0
2
4
6
8
10
Desviación estándar (ºC)
El segundo gráfico es solamente con el modelo 1 y sirve para mostrar como se hace si hay correlaciones negativas en los modelos. Para ello hay que cambiar el argumento lógico «pos.cor» y ponerlo como «FALSE».
¾ par(cex=1.2) ¾ taylor.diagram(Observado, Modelo1, main="", pos.cor=F, show.gamma=F, sd.arcs = T, ref.sd=T, pcex=2) ¾ polygon(x = c(-4,-4,4,4), y = c(12.05,13,13,12.05), col = "white", border = NA) ¾ text(0,12.6,paste("Coeficiente de correlación"))
GRÁFICOS AVANZADOS
179
¾ polygon(x = c(-4,-4,4,4), y = c(-2,-0.7,-0.7,-2), col = "white", border = NA) ¾ text(0,-1,"Desviación estándar (ºC)",col="blue") ¾ text(0,-2,"Error cuadrático medio (RMS)",col="green4") Coeficiente deCoefficient correlación Correlation 0
-0.2
0.2
-0.4
0.4
-0.6
0.6
-0.8
0.8
-0.9
0.9
-0.95
0.95 17
16
15
-0.99
-1
11
8.5
14
12
5.7
11
10
9
2.8
0.99 7.9
6.8
5.7
0
4.5
3.4
2.3
2.8
1.1 5.7
8.5
11
1
Standardestándar Deviation (ºC) Desviación Centered RMS Difference Error cuadrático medio (RMS)
Función taylor.diagram (paquete plotrix)
ref: variable con los valores observados. model: variable con los valores predichos por el modelo. col: color de los símbolos. pos.cor: si es TRUE representa la gráfica solamente con los coeficientes de correlación positivos: pos.cor=TRUE. show.gamma: indica si representa los arcos de los RMS. show.gamma=TRUE. ngamma: indica cuantos arcos RMS se representan: ngamma =3. gamma.col: color de los arcos RMS: gamma.col=8. sd.arcs: define si se representan los arcos de las desviaciones estándar: sd.arcs=0. ref.sd: indica si se pinta el arco de la desviación estándar de los valores observados que se usa como referencia: ref.sd=FALSE. grad.corr.lines: permite poner las etiquetas de los coeficientes de correlación: grad.corr.lines= c(0.2,0.4,0.6,0.8,0.9). pcex: define el tamaño de los símbolos: pcex=1. normalize: especifica si se tipifican los datos, de tal forma que la desviación estándar de los valores observados, que se usa como referencia, tenga un valor de 1: normalize=FALSE.
Se pueden usar los argumentos generales add, mar, main, pch, xlab e ylab.
180
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
III.16. Curvas de supervivencia y regresión de Cox La variable de interés es a menudo el tiempo transcurrido hasta que ocurre un evento: aparición de una enfermedad (o su curación), fallecimiento, avería de una máquina, éxito deportivo, etc. El evento puede ser favorable o desfavorable, y en los datos disponibles existirán casos que ya lo han alcanzado y otros que no, en los cuales el tiempo no se ha completado y se trata de observaciones incompletas (censuradas). En cada instante se puede estimar la tasa de supervivencia, o porcentaje de casos que no han alcanzado el evento para cualquier tiempo transcurrido. Su representación gráfica es la curva de supervivencia, que generalmente muestra el tiempo en el eje horizontal y la tasa de supervivencia o porcentaje de casos que no han alcanzado el evento en el vertical. Para la estimación de la curva de supervivencia se suele utilizar el método de Kaplan-Meier, que calcula la tasa mediante una fórmula recursiva. En cada periodo la supervivencia se calcula como un cociente cuyo denominador es el número de elementos expuestos al riesgo, siendo el numerador el mismo número del que se han restado los elementos que alcanzaron el evento durante ese tiempo; las tasas así obtenidas se van multiplicando sucesivamente en los distintos periodos. Con R existen varios paquetes para obtener la función de supervivencia, de los cuales el más básico es “survival” (Therneau, 2012), con las funciones «Surv()», que construye un objeto de supervivencia a partir de los datos, y «survfit()» que crea los valores de la curva. Veremos un ejemplo, cuyos datos están en el archivo Adictos.csv, consistente en 240 casos de pacientes de un centro de atención a drogo-dependientes. Contiene tres variables: edad en el momento actual o en el fallecimiento, fallecido que es si ha muerto o no (1/0), y adicto que puede ser si o no (1/0). Los no adictos se han tomado de una muestra aleatoria en la misma zona geográfica con una proporción similar de fallecidos. El objetivo es construir una función de supervivencia para los adictos y otra para los no adictos, de forma que podamos comparar ambas curvas. Las instrucciones están en el archivo III.21.R
¾ ¾ ¾ ¾ ¾ ¾ ¾
library(survival) datos<-read.csv2("Adictos.csv", header=TRUE, encoding="latin1") attach(datos) fit <- survfit(Surv(edad, fallecido) ~ adicto, data = datos) fit plot(fit, lty = 2:3, col=c("green","red"),xlab="Edad", cex.lab=1.8) legend("topright", .8, c("NO ADICTO", "ADICTO"), lty = 2:3, col = c("green","red"))
GRÁFICOS AVANZADOS
181
1.0
El objeto fit contiene información de interés. La mediana, edad superada por la mitad de la población en cada grupo, es de 36 años en los adictos y 77 en los no adictos. Se muestran también intervalos de confianza al 95% para ambas medianas: (35 – 38) y (76 – 80).
0.0
0.2
0.4
0.6
0.8
NO ADICTO ADICTO
0
20
40
60
80
Edad Como se puede apreciar en el gráfico anterior, se representan dos curvas de supervivencia (adictos y no adictos), ya que en la función «surfit()» se hace depender la curva del carácter de adicto. En el eje horizontal se representa la edad, y en el vertical la tasa de supervivencia. Para los adictos, la curva cae rápidamente. A los 30 años de edad sobrevive el 80%, a los 40 años el 20%, y a los 50 años de edad prácticamente el 0%. Entre los no adictos, estos porcentajes de supervivencia son mucho más elevados: a los 70 años de edad sobrevive más del 60% y a los 80 años más del 30%. En la última parte del script se realiza una regresión de Cox, también conocida como modelo de riesgos proporcionales. Se trata de un modelo similar al de regresión logística, pero adaptado al caso en el que una de las variables explicativas es el tiempo transcurrido hasta que ocurre un evento, por lo que suele usarse para evaluar los riesgos en el análisis de supervivencia. Para el cálculo de la regresión de Cox se puede utilizar la función «coxr()» del paquete “coxrobust” (Bednarski, 1993; 2012). El argumento «f.weight» permite definir el tipo de función de ponderación, la cual puede ser "linear", "quadratic" (por defecto) o "exponential". Con «trunc» se especifica el nivel de recorte para el estimador robusto. El argumento lógico «singular.ok» define cómo manejar la colinealidad. Si es TRUE, el programa no incluirá en el modelo las variables que son combinaciones lineales de variables anteriores. De existir variables que muestren colinealidad, los coeficientes serán NA y la matriz de varianzas contendrá ceros. Por último, el argumento lógico «model» define si la variable de resultado debe incorporar los valores de la variable temporal y de las variables explicativas. En este ejemplo solamente se evalúa el efecto de la
182
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
adicción o no adicción, pero es posible incluir en el modelo más variables, separadas con el símbolo «+».
¾ cox <- coxr(Surv(edad, fallecido) ~ adicto, data = datos, f.weight = "quadratic", trunc = 0.95, singular.ok = TRUE, model = FALSE) ¾ cox
Se estima el modelo de regresión mediante dos métodos: máxima verosimilitud parcial y método robusto. Éste último es menos sensible a las observaciones atípicas o extremas, por lo que puede ser utilizado con carácter general, ya que proporciona las estimaciones más prudentes y estables. De los resultados que se presentan, el de mayor interés es exp(coef), que muestra la HR (hazard ratio), equivalente en cierto modo a la OR (odds ratio) de la regresión logística (Guisande y col., 2011). HR es un cociente o razón de dos tasas de riesgo (hazard rate), tasas instantáneas que miden la probabilidad (en relación al intervalo de tiempo) de que se produzca el evento, condicionada a que no haya ocurrido con anterioridad. El valor observado de 23,4 significa que el riesgo de fallecimiento es 23,4 veces mayor en los adictos que en los no adictos y, como se trata de un promedio a lo largo del tiempo, debe asumirse que la relación entre los riesgos de ambos grupos se mantiene de forma aproximada a lo largo del tiempo, o supuesto de “riesgos proporcionales” habitual en la regresión de Cox. El valor p, prácticamente igual a cero en nuestro ejemplo, sirve para rechazar la hipótesis nula de que HR = 1, o que no existe diferencia en el riesgo de ambos grupos. Finalmente el test de Wald, con su valor p prácticamente nulo, nos permite afirmar que el modelo de regresión es significativo. Por tanto, la adicción tiene una clara influencia negativa en la supervivencia.
III.17. Análisis de varianza El análisis de varianza (ANOVA) es uno de los métodos más usados para contrastar la homogeneidad de variables (Guisande y col., 2011). Las funciones «granova.1w()» y «granova.2w()» del paquete “granova” (Pruzek, 2012) realizan una representación gráfica de un ANOVA de un factor y de dos factores, respectivamente.
GRÁFICOS AVANZADOS
183
El ejemplo utiliza datos del índice de precios al consumo (IPC) de los alimentos de los años 2011 y 2010, en las 19 regiones o comunidades autónomas de España, publicados por el Instituto Nacional de Estadística (www.ine.es), los cuales están en el archivo IPC.csv. El índice toma como base el año 2006, en el que su valor es 100. Las instrucciones están en el script III.22.R. El primer gráfico representa un ANOVA con dos factores. En la función «granova.2w()» se especifica la variable dependiente (columna 3) y los factores, que son la región (columna 1) y el año (columna 4). El argumento «fit» especifica si el ajuste de la superficie debe ser «"linear"» (opción por defecto), «"quadratic"» o «"smooth"».
¾ ¾ ¾ ¾
require(granova) datos<-read.csv2("IPC.csv",header=TRUE,encoding="latin1") attach(datos) granova.2w(datos[, c(3, 1, 4)], fit="quadratic")
El gráfico muestra la variabilidad residual del IPC en sentido vertical, y se trata de un gráfico activo: moviendo el ratón con el botón izquierdo pulsado se cambia el punto de vista del observador. La bola de color gris indica la media de cada casilla (combinación de niveles de los factores), y los dos ejes horizontales representan los dos factores (año y región). La inclinación del plano de ajuste muestra un índice creciente en el tiempo y también diferencias importantes entre las regiones. En cada combinación de factores la variabilidad residual es aparentemente simétrica y equilibrada, lo que puede indicar un razonable cumplimiento de la hipótesis de normalidad exigida por el método ANOVA.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
184
El segundo gráfico representa un ANOVA con un factor y más información que el anterior. En la función «granova.1w()» con el argumento «data» se especifica la variable dependiente y con «group» el factor. Con «h.rng» y «v.rng» se definen las distancias horizontal y vertical entre los grupos del factor (más distancia a medida que los valores son más pequeños). Con «kx» se define el tamaño de las etiquetas. El argumento «size.line» define la posición vertical de los números que indican el tamaño de los grupos y las etiquetas de los mismos.
2 La Rioja
2 Navarra
10 Castilla-La Mancha 2 Islas Baleares 2 Cantabria 2 Asturias 8 Galicia 2 Madrid 16 Andalucía
8 Cataluña
4 18 Extremadura Castilla y León
6 Aragón
6 C. Valenciana
2 Melilla
2 Murcia
2 Ceuta
6 País Vasco
4 Islas Canarias
¾ granova.1w(data=IPC, group=Región, h.rng=1, v.rng=0.15,kx=1.3, size.line=-3.5,main="", ylab="IPC de alimentos", xlab="Coeficientes de contraste basados en las medias y errores de los grupos")
|
|
||
|
|
|
|
|
|
|
|
|
|
110.6
111.5 111.2 110.9 110.6 110.4
109.4 109.2 109.0 108.9 108.8
108.6
gm+sdw
| ||
107.7 107.6 107.5 107.4 106.7
107.2 106.8 106.6
104.3
gm-sdw
IPC de alimentos
115.1
Group Sizes:
2.85
2.59
1.99
1.80
0.80
0.55
0.32 0.33
0.14
-0.89
-1.21 -1.12 -1.05
-1.43 -1.42 -1.38
-1.85
-2.07
2.29
MS-within MS-between F-statistic = 2.58
Group Means Grand Mean
0
Coeficientes de contraste basados en las medias y errores de los grupos
El gráfico muestra los distintos niveles del factor ordenados por el valor medio de la variable (representado por un triángulo rojo) de izquierda a derecha. Las comunidades de La Rioja o Navarra tienen los valores más bajos del IPC, y País Vasco e Islas Canarias los más altos. Están espaciados en el gráfico de tal modo que los valores medios o estimaciones del efecto del factor sobre la variable dependiente forman una línea recta. En los márgenes del gráfico se muestran en la parte superior las etiquetas de los niveles y el número de casos, en la inferior la desviación del valor medio con respecto a la media general (o estimación del efecto), y en la derecha la media de cada nivel. Para cada nivel del factor se muestra la variabilidad residual en vertical, lo que permite apreciar la posible existencia de distribución asimétrica o valores atípicos (no existen en nuestro ejemplo), así como la homogeneidad de varianzas, o dispersión similar a lo largo de todo el gráfico, para los distintos niveles del factor.
GRÁFICOS AVANZADOS
185
El gráfico permite entender como funciona el análisis de la varianza. Se compara la variabilidad debida al factor (variabilidad entre los valores medios de los niveles), representada por el área del cuadrado rojo, con la variabilidad residual, la que permanece dentro de cada nivel, representada por el área del cuadrado azul. El cociente entre ambos cuadrados medios es el valor F del contraste, cuya probabilidad o valor p nos permite decidir si existe o no un efecto significativo. Cuanto más grande sea el cuadrado rojo en comparación con el azul, mayor será el efecto del factor (comunidad autónoma) sobre la variable dependiente (índice de precios).
Función granova.1w (paquete granova) data: puede ser un data frame (conjunto de variables o columnas) o un vector (es decir una variable). En el primer caso debe ponerse group = NULL y las distintas columnas de data son los valores de la variable dependiente para cada nivel del factor, siendo los grupos necesariamente de igual tamaño. Si data es un vector (es la variable dependiente) debe añadirse un factor con distintos niveles en group, lo que permite grupos de distinto tamaño. group: variable que es el factor en el ANOVA: group = NULL. dg: número de decimales: dg = 2. h.rng: define la distancia horizontal entre grupos. A medida que es más pequeño los grupos se separan más: h.rng = 1.25. v.rng: define la distancia vertical entre puntos. A medida que es más pequeño los puntos se separan más: v.rng = 0.2. box: si es TRUE se pinta un marco: box = FALSE. jj: define la separación horizontal entre puntos cuando se solapan: jj = 1. kx: tamaño de texto en las etiquetas: kx = 1. px: tamaño de los números en los ejes: px = 1. size.line: posición vertical de los números que indican el tamaño de los grupos y las etiquetas de los mismos: size.line = -2.5. top.dot: altura del límite superior de las líneas verticales punteadas: top.dot = 0.15. trmean: si es TRUE se señala la media acotada al 20% de cada grupo (como una X) y muestra los valores en la ventana de salida: trmean = FALSE. resid: si es TRUE se representan los residuos en el margen derecho: resid = FALSE. dosqrs: si es TRUE se representan dos cuadrados con áreas proporcionales a la varianza entre grupos (varianza explicada) y a la varianza interna o intra-grupos (varianza residual): dosqrs = TRUE. ident: si es TRUE pulsando con el ratón sobre cualquier punto, sale su valor, lo cual permite identificar cada uno de los puntos. Con el botón derecho del ratón se para esta instrucción: ident = FALSE. pt.lab: se pueden especificar con un vector las etiquetas de los puntos. Si es NULL se usan las etiquetas de fila o rownames (si existen) o el número de caso: pt.lab = NULL. Se pueden usar los argumentos generales main, xlab e ylab.
186
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
III.18. Gráficos de diagnóstico en modelos lineales Se trata de un conjunto de gráficos utilizados para valorar los supuestos (Normalidad, homogeneidad e independencia) en los modelos lineales. Se pueden obtener fácilmente con la función «plot()». Las instrucciones están en el script III.23.R. El ejemplo, cuyos datos están en el archivo ANCOVA.csv, son datos de altura y peso de hombres y mujeres de diferentes países y ciudades. El objetivo es determinar si existen diferencias en el peso de las mujeres entre las diferentes ciudades, tomando la altura como covariable. Para ello realizamos un análisis de covarianza y obtenemos los gráficos de diagnóstico. Después de cargar los paquetes e importar los datos se seleccionan solamente a las mujeres. Se realiza el ANCOVA y con los resultados se realizan los gráficos. Con el argumento «which=1:6» se define que se representen los seis gráficos de diagnóstico. Con el argumento «mfrow=c(3,2)» combinamos los seis gráficos en un único conjunto, con dos columnas y tres filas. Para representar cada gráfico por separado, solo tenemos que utilizar «which=1» y anular la función «par()»
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
require(lawstat) require(e1071) require(car) require(nortest) require(multcomp) datos<-read.csv2("ANCOVA.csv",header=TRUE,encoding="latin1") datos1 <- datos[datos$Sexo=="Mujer",] attach(datos1) modelo <- lm(datos1$Peso.Kg ~ datos1$Altura.cm + factor(datos1$Ciudad)) summary(modelo, type=3) par(mfrow=c(3,2), mar=c(3,5,3,3)) plot (modelo, add.smooth=FALSE, which=1:6)
El gráfico 1 son los residuos frente a valores ajustados (residuals vs fitted). Sirve para valorar la hipótesis de homogeneidad. La dispersión debe ser similar a lo largo de todo el recorrido de valores ajustados. El gráfico 2 es la Normal Q-Q. Representa los residuos en transformación Normal. Si siguen una distribución Normal el gráfico debe ajustarse a una línea recta (la diagonal), como en el ejemplo. Suele aceptarse una pequeña desviación en los extremos. El gráfico 3 es Scale-location. Representa la raíz cuadrada del residuo frente a los valores ajustados. Se utiliza para diagnosticar problemas de homogeneidad. El gráfico 4 es la distancia de Cook frente a número de caso. La distancia de Cook mide el efecto global que ejerce sobre el ajuste la eliminación de cada caso o fila. Sirve para identificar los casos (atípicos, outliers) con mayor influencia, los datos a los que se debe prestar más atención. Se considera en general que un valor de la distancia de Cook mayor que 1 debe ser estudiado -no hay ninguno en nuestro ejemplo- y los valores más altos, correspondientes a los datos de las filas 14 y 15, apenas llegan a 0,35.
GRÁFICOS AVANZADOS Normal Q-Q
14
0
1 0 -1 -3
-2
Residuals
1
16
Standardized residuals
2
16
-1
3
Residuals vs Fitted 14
-2
15
60
1.4
Scale-Location
1.2
15 14
0.4
0.6
0.8
Cook's distance
1.0
16
0.0
55
60
65
Cook's distance
1 0 -1 -2
15
0.3
0.4
2
15
14
5
0.00 0.05 0.10 0.15 0.20 0.25 0.30
0.5
0.5
0.2
1
Cook's distance
2 1.5
5
0.1
0
10
15
Cook's dist vs Leverage hii
14
0.0
-1
5
Residuals vs Leverage
Cook's distance
15
-2
0.2
Standardized residuals
65
0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35
55
Standardized residuals
187
1
20
1 hii
15
0 14
5
0 0.15
0.25 0.3
0.35
0.4
0.45
El gráfico 5 representa los residuos frente a valores del estadístico de influencia (leverage). En el gráfico se muestran con líneas discontinuas los lugares correspondientes a iguales valores de la distancia de Cook (etiquetados con el valor correspondiente); como norma general, los residuos deben estar distribuidos al azar, sin mostrar una estructura o patrón. Si los valores de influencia son constantes, como ocurre a menudo con diseños equilibrados en el análisis de la varianza, el gráfico utiliza combinaciones de los niveles de los factores (ordenados
188
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
por el valor ajustado) en lugar del estadístico de influencia, lo que permite valorar la falta de homogeneidad, o diferente dispersión, en los distintos niveles de los factores; la dispersión debe ser similar para todos los niveles de los factores. El gráfico 6 es la distancia de Cook frente al estadístico de influencia (leverage). El estadístico de influencia mide la distancia entre los valores de las variables explicativas para cada caso y los valores medios de la muestra. Los casos con mayor valor de ese estadístico pueden tener un efecto importante sobre la predicción de los valores de la variable dependiente. En el contexto del análisis de la varianza los valores de influencia son típicamente pequeños. Este gráfico, de interpretación compleja, se utiliza a menudo para descartar algunas observaciones o algún patrón de covariables. Las líneas discontinuas que pasan por el origen en el gráfico muestran los lugares que corresponden al error tipificado de igual magnitud (la magnitud aparece como etiqueta de cada línea). En general debe prestarse atención a los puntos con mayores valores de distancia de Cook, mayor valor de influencia, y mayor magnitud de error. En nuestro ejemplo no existe ningún valor problemático, ya que todos ellos son pequeños.
III.19. Gráficos de medidas de riesgo de extinción Se generan con la función «CSEGriskfigure()» del paquete “MARSS” (Holmes y Ward, 2010; Holmes y col., 2012). Esta función elabora un panel con seis gráficos, representando diferentes medidas utilizadas en Análisis de Viabilidad de Poblaciones (PVA). Como ejemplo utilizaremos un conjunto de datos de descargas de sardina durante un periodo aproximado de 100 años que están en el archivo Sardinas.csv. Las descargas de sardina en puerto es un buen indicador de la densidad de la población (Guisande y col., 2001). Las instrucciones están en el script III.24.R. En la función «CSEGriskfigure()» el argumento «te=100» indica el número de periodos de predicción. Con «threshold» se define el umbral de cuasi extinción, el cual si es una fracción del total de la población actual se pone «absolutethresh=FALSE».
¾ ¾ ¾ ¾
library(MARSS) datos<-read.csv2("Sardinas.csv", header=TRUE, encoding="latin1") attach(datos) CSEGriskfigure(datos, te=100, threshold=0.1, absolutethresh=FALSE)
El primer gráfico muestra los cambios en la población de la especie a lo largo del tiempo. Se observa como durante los últimos 100 años los valores oscilan, con una ligera tendencia decreciente. El segundo gráfico es una función de distribución acumulada (CDF) de la variable “tiempo hasta alcanzar el umbral de extinción”. Muestra la probabilidad de que la especie representada alcance el valor umbral indicado de cuasi extinción en un tiempo igual o inferior al representado. Se incluyen en el gráfico los intervalos de confianza al 90% y 75%. El umbral por defecto es el 10% (puede indicarse otro valor en la función). Por lo tanto, la probabilidad de que la sardina alcance el umbral del 10% en los próximos 20 años se sitúa –de acuerdo con estos datos- alrededor del 25%, y en los próximos 100 años por encima del 60%. El umbral del 10% se calcula sobre las capturas estimadas en el último
GRÁFICOS AVANZADOS
189
periodo de los datos disponibles y, en este caso, es de 336 unidades, como se indica también en el gráfico. u est = -0.014 (95% CIs -0.095 , 0.068 ) Q est = 0.16
0.8
95% CI 75% CI
0.4
0.6
mean
0.0
0.2
probability to hit threshold
30000 10000 0
Pop. Estimate
1.0
Prob. to hit 336
1905 1919 1933 1947 1961 1975 1989
0
20
40
60
80
100
time steps into future
0.8 0.6 0.4
90% threshold
0.0
0.2
0.005
0.010
probability to hit threshold
0.015
1.0
Prob. of hitting threshold in 100 time steps
0.000
probability to hit threshold
PDF of time to threshold given it IS reached
100
200
300
400
500
200
300
400
500
600
time steps into future
Number of ind. at Ne
Sample projections
time steps = 98 mu = -0.014 s2.p = 0.16
0 0
20
40
60
time steps into the future
80
100
-0.5 -1.0
50%
90%
-1.5 -2.0
1000000
N
xe = log10(N0/Ne)
2500000
0.0
0
99% 20
40
60
80
100
Projection interval T time steps
El tercer gráfico es una función de densidad de probabilidad (PDF) de la variable anterior. En el ejemplo se muestra una función aproximadamente exponencial, muy habitual en este tipo de datos, que indica una alta probabilidad de extinción en los próximos 100 años.
190
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
El cuarto gráfico muestra la probabilidad asociada a distintos valores de población al cabo del periodo de predicción (por defecto 100 periodos). Se muestra con una línea roja vertical el umbral del 10% (es decir reducción del 90%). En el ejemplo se comprueba que la probabilidad de que el número de sardinas descargadas dentro de 100 años se sitúe entre 200 y 600, tiene probabilidades similares para los distintos valores. El quinto gráfico muestra las estimaciones de la variable pronosticada para todo el periodo de predicción. Representa -en diferentes colores- 10 proyecciones simuladas de la evolución de la población, obtenidas a partir de las probabilidades estimadas previamente. El hecho de que las diferentes simulaciones sean muy distintas entre sí, como en este ejemplo, indica la escasa fiabilidad de las proyecciones a medio y largo plazo. Este gráfico es distinto en cada ejecución, ya que se trata de simulaciones. El último gráfico es la Incertidumbre Teórica Mínima (TMU). Muestra la incertidumbre de las predicciones. En el eje horizontal se representa el periodo de predicción, y en el vertical el umbral de extinción en escala logarítmica decimal (1 es el 10%; -2 el 1%). Un trazo horizontal muestra los umbrales de reducción de la población del 50%, 90%, y 99%. Los diferentes tonos de gris en el gráfico muestran los niveles de incertidumbre: cuanto más oscuro menos fiable es la predicción. La zona más oscura corresponde a intervalos de confianza de amplitud (error de estimación) superior a 0,80, y la más clara a valores de la probabilidad de alcanzar el umbral inferiores a 0,05 o superiores a 0,95 (amplitud intervalo de confianza <5%). En el ejemplo, las estimaciones son fiables en un periodo inferior a 20 años, y tanto menos fiables dentro de este tiempo cuanto más alto (menor pérdida) sea el umbral de extinción utilizado.
Función CSEGriskfigure (paquete MARSS) data: matriz con dos columnas en la que el tiempo es la primera y la otra columna es la abundancia de la especie. te: periodo de predicción: te = 100. threshold: umbral de extinción que puede ser un entero o una fracción de la población: threshold = 0.1. absolutethresh: si es TRUE se especifica que threshold es un número entero: absolutethresh = FALSE. CI.method: método para calcular el intervalo de confianza que puede ser "hessian", "parametrc", "innovations" o "none": CI.method = "hessian". CI.sim: número de simulaciones en el cálculo de los intervalos de confianza bootstrap: CI.sim = 1000.
III.20. Graficos para análisis multivariante III.20.1. BIPLOT En el análisis multivariante se trabaja con muchos tipos diferentes de variables y existen algunos gráficos útiles para estos casos. La función «biplot()» del paquete “stats” permite representar dos matrices de datos en un solo gráfico y
GRÁFICOS AVANZADOS
191
es útil para análisis factoriales, de componentes principales, de correspondencias y correlación canónica. Las instrucciones están en el script III.25.R. Los datos, que están en el archivo Correspondencias.csv, son las puntuaciones de un análisis de correspondencias realizado a una encuesta para estudiar la frecuencia de cuatro marcas de automóvil (identificadas como A, B, C y D) en distintos países europeos. Después de importar los datos y cargarlos en memoria, es necesario especificar las dos variables a representar en el set de datos x y la dos variables del set de datos y. Si se van a poner etiquetas a los datos, también es conveniente especificar los datos que son etiquetas de los datos x y las que son de los datos y. El argumento lógico «var.axes» especifica si se pintan flechas en el grupo de variables y. Con «col» se definen los colores de las variables x e y. Los argumentos «xlabs» e «ylabs» sirven para definir las variables que se usaran como etiquetas de los datos. Con «cex» se define el tamaño de las etiquetas. El argumento «expand» es un coeficiente de la proporción entre las variables y con respecto a las variables x. Por ejemplo, un valor de 2 significa que los ejes de las variables y se expanden el doble que las variables x. Con «arrow.len» se define el tamaño de la punta de las flechas de las variables y.
¾ Datos<-read.csv2("Correspondencias.csv", header=TRUE, encoding= "latin1") ¾ attach(Datos) ¾ x<-Datos[1:14,2:3]; y<-Datos[15:18,2:3] ¾ EtiquetaX<-Datos[1:14,1]; EtiquetaY<-Datos[15:18,1] ¾ biplot(x,y,xlab="Dimensión 1",ylab="Dimensión 2",var.axes=T, col= c("black","red"), xlabs= EtiquetaX, ylabs=EtiquetaY, cex=1, font.lab=2, cex.lab=1.5,main="Análisis de correspondencias",font.main= 2, cex.main =1.7, ylim=c(-1.6,0.6), xlim=c(-1.5,2), expand=1, arrow.len= 0.1)
Función biplot (paquete stats) x: primer conjunto con dos variables a representar, generalmente asociado a los casos. y: segundo conjunto a representar, generalmente asociado a las variables. var.axes: si es TRUE el segundo conjunto se representa con flechas: var.axes = TRUE. col: vector con los dos colores de ambos conjunto de datos. cex: tamaño de letra de las etiquetas. xlabs: etiquetas del primer conjunto de datos: xlabs = NULL. ylabs: etiquetas del segundo conjunto de datos: ylabs = NULL. expand: coeficiente de expansión de las variables del conjunto de datos y con respecto a las variables del conjunto x: expand = 1. arrow.len: tamaño de la punta de las flechas de las variables del conjunto y: arrow.len = 0.1. Se pueden usar los argumentos generales xlim, ylim, main, sub, xlab e ylab.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
192
Análisis de correspondencias -1
0
1
2
3 1.0
-2
0.5
0.5
Grecia Portugal España Serbia
0.0
B
-0.5
-0.5
Polonia Finlandia Noruega C
-1.5
-1.0
Rusia
-2.5
-1.5
-2.0
-1.0
Dimensión 2
0.0
A Hungría Suíza Rep. Checa Bélgica
Inglaterra D Irlanda -1.5
-1.0
-0.5
0.0
0.5
1.0
1.5
2.0
Dimensión 1 III.20.2. ANÁLISIS DISCRIMINANTE La función «scatterplot()» del paquete “car” (Fox y Weisberg, 2012) es también útil para representar las salidas de análisis multivariante. En el archivo Discriminante.csv están las puntuaciones de un análisis discriminante aplicado a variables morfométricas de cuatro especies de serpientes. Las instrucciones están en el script III.26.R. Con el argumento lógico «reg.line=lm» se representaría una recta de regresión lineal, aunque en este caso no se representa y se pone «reg.line= FALSE». Con «smooth» se indica una curva de regresión no paramétrica, en cuyo caso con «spread=T» se muestran los límites de confianza y el argumento «span» define la amplitud. Con «grid» se puede indicar que se representen las cuadriculas interiores en el gráfico. Con «legend.coords» se indica la posición de la leyenda. Con «legend.plot=FALSE» se omite la leyenda. Con «boxplots» se puede representar en el margen un diagrama de cajas para "x", "y" o "xy". Con «by.groups=TRUE» las regresiones y elipses se hacen para cada grupo. Con el argumento «ellipse=TRUE» se dibuja una elipse para cada grupo.
GRÁFICOS AVANZADOS ¾ ¾ ¾ ¾
193
library(car) Datos<-read.csv2("Discriminante.csv", header=TRUE, encoding= "latin1") attach(Datos) scatterplot(Función.2~Función.1 | Especie, data=Datos, reg.line= FALSE, smooth=F, spread=F, span=1, grid=F, legend.coords="bottomleft", boxplots=F, by.groups=T, ellipse=T, font.lab=2, pch=c(15,16,17,18), col=c("black","red","green","blue"), main= "Análisis discriminante", font.main=2,cex.main=2, cex.lab=1.5, xlab="Función 1", ylab="Función 2")
0 -2 -4
Función 2
2
Análisis discriminante
Especie 1 2 3 4 -4
-2
0
2
4
Función 1
Función scatterplot (paquete car) x, y: variables a representar o fórmula del tipo y ~ x o bien y ~ x | z data: data frame donde están las variables a representar.
194
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Función scatterplot (Continuación) smooth: si es TRUE se traza una curva de regresión no paramétrica para cada conjunto de datos: smooth=TRUE. spread: si es TRUE y el anterior es TRUE, se pintan los intervalos de la regresión no paramétrica: spread=!by.groups. span: amplitud de la regresión no paramétrica. span=.5. loess.threshold: suprime la regresión no paramétrica si el número de datos es menor que el valor dado: loess.threshold=5. reg.line: regresión lineal: reg.line=lm. boxplots: si no se representa por grupos se puede representar un diagrama de cajas en "x", "y" o "xy": boxplots=if (by.groups) "" else "xy". lwd: valor numérico del grosor de línea de las rectas de regresión, curvas de regresión no paramétrica "lwd.smooth" e intervalos "lwd.spread". lty: tipo de línea de las rectas de regresión, curvas de regresión no paramétrica "lty.smooth" e intervalos "lty.spread". labels: vector con las etiquetas de los puntos. id.method, id.n, id.cex, id.col: argumentos para las etiquetas de los puntos: id.method = "mahal", id.n = if(id.method[1]== "identify") length(x) else 0, id.cex = 1, id.col = palette()[1]. groups: una variable que indica los grupos a realizar. by.groups: si es TRUE las regresiones y elipses se hacen para cada grupo: by.groups=!missing(groups). legend.title y legend.coords: título y coordenadas de la leyenda. legend.plot: si es FALSE no se representa la leyenda. ellipse: si es TRUE dibuja la elipses de concentración de los grupos: ellipse=FALSE. levels: niveles de significación para las elipses: levels=c(0.5, 0.95). robust: si es TRUE se usa la función cov.trob para calcular el centro y la matriz de covarianzas de las elipses: robust=TRUE. legend.plot: si es TRUE se muestra una leyenda con los grupos: legend.plot= !missing(groups). reset.par: si es FALSE se pueden añadir parámetros gráficos, por ejemplo líneas: reset.par=TRUE. grid: si es TRUE se representan las cuadrículas interiores del gráfico: grid=TRUE. Se pueden usar los argumentos generales pch, col, las, log, cex, cex.axis, cex.lab, cex.main, cex.sub, xlim, ylim, main, sub, xlab e ylab.
La función «candisc()» del paquete “candisc” (Friendly, 2007; Friendly y Fox, 2012) combina varios gráficos relacionados con el Análisis Discriminante. Como ejemplo usaremos la abundancia de varios grupos de algas del fitoplancton que aparecen en diferentes lagos del Neotrópico, cuyos datos están en el archivo Fitoplancton.csv. Las instrucciones están en el script III.27.R. En primer lugar se realiza un modelo de regresión lineal con la función «lm()». Se introducen por un lado los grupos de algas y las concentraciones de
GRÁFICOS AVANZADOS
195
nutrientes y, por otro lado, el lago y el sitio de muestreo. El modelo obtenido se introduce en la función «candisc()». En el primer gráfico solamente se representa la primera función discriminante canónica y, para ello, se especifica el argumento «ndim=1». Si se pusiera 2, se estaría indicando que se guarden las dos primeras funciones discriminantes. Con el argumento «term» se indica la variable de agrupación, en este ejemplo los diferentes lagos. Por último, con la función «summary()» se puede obtener información sobre las medias, las puntuaciones, etc., de cada uno de los ejes.
¾ ¾ ¾ ¾ ¾
library(candisc) datos<-read.csv2("Fitoplancton.csv",header=TRUE,encoding="latin1") datos<-na.exclude(datos) attach(datos) mod <- lm(cbind(Cianophyceae, Euglenophyceae, Clorophyceae, Zygophyceae, Bacillariophyceae, Crysophyceae, Cryptophyceae, Dinophyceae, Xanthophyceae, NO2, NO3, NH4, SiO2) ~ Lago+Area, data=datos) ¾ can <- candisc(mod, term="Lago", data=datos, ndim=1) ¾ plot(can,titles.1d = c("Puntuación canónica", "Estructura")) ¾ summary(can, means = FALSE, scores = TRUE, coef = c("std"), digits = 2) En el primer gráfico que se obtiene se observa que el primer eje canónico absorbe el 67,2% de la variación y que el lago de Tota se diferencia claramente del resto de lagos. Los grupos taxonómicos que más diferencian el lago de Tota del resto son las clorofitas y cianofitas. Estructura
Fuquene
Guatavita
Iguaque
Momil
Purísima Sebastián Tarapoto
Tota
NH4 NO3
Dinophyceae
Xanthophyceae
Crysophyceae
Cryptophyceae
Zygophyceae
Bacillariophyceae
Euglenophyceae Cianophyceae
-10
Correo
Clorophyceae
0 -5
Can1 (67.2%)
5
NO2
SiO2
10
Puntuación canónica
Yahuarcaca
Lago
Si en vez de Lago se pone Región en el modelo de regresión «lm()» y en la función «candisc()», entonces se obtendría el siguiente gráfico, en el cual se observa que la primera función discriminante absorbe el 80% de la varianza y diferencia la región de los Andes de las otras dos regiones.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
196
Estructura
Andes
Zygophyceae Bacillariophyceae Crysophyceae Cryptophyceae Dinophyceae Xanthophyceae
Cianophyceae Euglenophyceae Amazonas
Clorophyceae
0 -4
-2
Can1 (80%)
2
NO3
4
NH4
NO2
SiO2
6
Puntuación canónica
Caribe
Región
En el segundo gráfico se representan varios ejes canónicos o funciones discriminantes; en concreto se ha especificado que se guarden 4 ejes «ndim=4», y podemos representar cualquier par de ellos, aunque en general los dos primeros son los que permiten una mejor descripción al concentrar una mayor parte de la variabilidad. El paquete “vcd” (Meyer y col., 2012) se utiliza para poner una leyenda con la función «grid_legend()», que ya se ha usado anteriormente en varios ejemplos. Con la función «rep()» se asignan 10 colores, tantos como lagos, y se especifica posteriormente cuantos datos hay para cada color. Es necesario tener en cuenta que como se han eliminado las filas donde falte algún caso con la función «na.exclude()», hay que especificar el número de datos reales de cada lago después de la exclusión. En concreto solamente se ha perdido un caso del lago Fuquene. El proceso se repite para asignar símbolos a todos los lagos. En el caso de no querer ningún símbolo se usaría el argumento «type="n"» en vez de «pch» y «col» en la función «plot()». En la función «plot()» con «which=c(2,3)» se especifica que se representen los ejes canónicos II y III. Con el argumento «conf» se define el nivel de confianza, que viene representado por un círculo para cada grupo en el gráfico; el nivel indica la probabilidad de que un elemento de esa clase esté dentro del círculo. Los círculos separados, sin solapamiento, indican clases bien definidas o identificables. Con «scale» se puede modificar el espacio que ocupan las variables vector, en este ejemplo los grupos de algas y nutrientes, en el gráfico.
GRÁFICOS AVANZADOS
197
4
¾ can <- candisc(mod, term="Lago",data=datos,ndim=4) ¾ library(vcd) ¾ col <- rep(c("red", "orange", "brown", "green", "yellow", "blue", "cyan", "wheat", "lightblue", "skyblue"), c(9, 12, 24, 6, 6, 4, 15, 2, 4, 4)) ¾ pch <- rep(c(1,2,5,6,7,15,16,17,18,19), c(9, 12, 24, 6, 6, 4, 15, 2, 4, 4)) ¾ plot(can, which=c(2,3),col=col, pch=pch, conf = 0.95, var.col = "blue", var.lwd =1, prefix = "Can", suffix=TRUE, scale=10) ¾ grid_legend(0.95, 0.7, pch=c(1,2,5,6,7,15,16,17,18,19), col = c("red", "orange", "brown", "green", "yellow", "blue", "cyan", "wheat", "lightblue", "skyblue"), frame = FALSE, c("Correo", "Tarapoto", "Yahuarcaca", "Fuquene", "Guatavita", "Iguaque", "Tota", "Momil", "Sebastián", "Purísima"), title = "LAGOS", hgap=10,vgap=0.5, gp=gpar(fontface=1, fontsize=12)) LAGOS Correo Cryptophyceae Tarapoto SiO2 Momil Yahuarcaca Yahuarcaca Guatavita Fuquene Zygophyceae Guatavita Tarapoto NO2 Tota Iguaque Cianophyceae Clorophyceae NH4 Tota Crysophyceae Fuquene Purísima Momil Correo Sebastián Purísima Dinophyceae Xanthophyceae Bacillariophyceae Euglenophyceae
2
+
+
+
-2 -4
Can3 (6%)
0
+
+
+
+ +
+
-6
Iguaque
+
-8
Sebastián NO3
-10
-5
0
5
10
Can2 (16.6%)
En el tercer gráfico utilizaremos las funciones «heplot()» y «candiscList()» del paquete “candisc” (Friendly, 2007; Friendly y Fox, 2012), con las cuales se construyen elipses en el espacio discriminante canónico, que representan la variabilidad correspondiente a las hipótesis y a los residuos del modelo lineal. La diferencia entre las funciones «candiscList()» y «candisc()» es que la primera realiza un análisis discriminante para todos los términos del modelo, mientras que la segunda, como se vió anteriormente, se realiza solamente para el término que se especifique. En la función «candiscList()» con «type» se especifica el modo de descomposición o asignación de las sumas de cuadrados entre los distintos términos del modelo, como es habitual en el análisis de la varianza, que puede ser II o III (no tiene ningún efecto si solo utilizamos un factor). En la función «heplot()» con el argumento «fill» se puede especificar si se rellenan o colorean las áreas de las elipses. Debido a que con la función «candiscList()» se ha realizado un análisis canónico discriminante para todos
198
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
los términos del modelo de regresión lineal, si en «term» se pusiera «TRUE» se mostrarían los gráficos para todos los términos, y poniendo «TRUE» en los argumentos «ask» y «graphics» aparece una ventana en la que se puede seleccionar el término a representar.
¾ canL <-candiscList(mod, type="II") ¾ heplot(canL, which = c(1,2), scale=16, var.col = "blue", var.lwd=1, var.cex=1, prefix = "Can", suffix = TRUE, fill=TRUE, term="Lago", ask=FALSE, graphics=FALSE) En el gráfico la elipse de color verde representa la variabilidad de la hipótesis, en este caso la variabilidad explicada por el lago, y la marrón la variabilidad residual. Se comparan los tamaños de ambas elipses, y se observa que el lago explica una gran parte de la variabilidad de las dos primeras funciones discriminantes. También se muestran como vectores las diferentes variables dependientes, es decir, las concentraciones de algas y variables de entorno, por lo que se puede apreciar gráficamente la mayor o menor aportación de cada variable a las funciones discriminantes y, por lo tanto, al proceso de clasificación. Por último, los distintos lagos, representados por puntos en el gráfico, pueden asociarse a las diferentes variables. En el lago Tota predominan las especies Cianophyceae y Clorophyceae y en el lago Sebastián son mayores las concentraciones de NO3 y SiO2.
En el cuarto gráfico se usa la función «heplot3d()», que permite visualizar las elipses en el espacio discriminante canónico pero en 3D, rotando el gráfico con el ratón. Al ser 3D, se ponen tres ejes «which=c(1,2,3)».
¾ heplot3d(canL, which = c(1,2,3), scale=16, term="Lago", ask=FALSE, graphics=FALSE)
GRÁFICOS AVANZADOS
199
III.20.3. GGE BIPLOTS Otra función interesante es «GGEBiplot()» del paquete “GGEBiplotGUI” (Frutos, 2012). Yan y col. (2000) propusieron utilizar los efectos combinados de genotipos (G) y de interacción genotipo-ambiente (IGA) en la evaluación del rendimiento en cultivos de trigo, obteniéndose los gráficos denominados GGE biplot que facilitan la identificación visual de los genotipos y los ambientes de evaluación. Generalmente, los gráficos GGE biplot se confeccionan utilizando las dos primeras componentes principales (CP1 y CP2), derivadas en este caso, de la descomposición de los efectos combinados de G + IGA (Yan y Kang, 2003). La primera componente CP1, cuando se encuentra altamente correlacionada con el efecto principal de genotipo, representa la proporción del rendimiento que se debe solo a las características del genotipo. La segunda componente CP2, representa la parte del rendimiento debida a la interacción genotipo-ambiente (Yan y col., 2001). Los casos se representan por puntos, y las variables mediante flechas o ejes. Esto permite conocer de forma aproximada, a partir del gráfico, los valores de todas las variables para cada caso o punto representado, que serán mayores si están hacia la parte mostrada por la punta de flecha, y menores, incluso negativos, si están situadas en la dirección opuesta. No es necesario un script porque la función trabaja con un menú de ventanas. El ejemplo que vamos a analizar, cuyos datos están en el archivo Países.xls, se trata de un conjunto de 57 países de Europa, África y América. Las variables indican la esperanza de vida masculina y femenina al nacer (en años de vida), las tasas de mortalidad, mortalidad infantil, natalidad, y fertilidad, el producto interior bruto per cápita (en miles de dólares anuales) y la tasa de alfabetización de hombres y mujeres (en porcentaje).
200
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Si se trabaja con versiones anteriores a R-2.15.0, entonces en la ventana de RGUI o en un archivo script se introducen las siguientes instrucciones para cargar el paquete y llamar a la función.
¾ library (GGEBiplotGUI) ¾ GGEBiplot() Se obtienen las siguientes ventanas que permiten comenzar con el programa, abrir el archivo con los datos (Países.xls, archivos Excel con extensión xls) y seleccionar la hoja de trabajo dentro del archivo.
Si se trabaja con la versión R-2.15.0 o superior, entonces en la ventana de RGUI o en un archivo script se introducen las siguientes instrucciones para cargar el paquete, los datos y llamar a la función. En este caso se trabaja con el archivo PaísesGGB.csv, que son los mismos datos mencionados anteriormente, pero en formato csv.
¾ library (GGEBiplotGUI) ¾ Datos<-read.csv2("PaísesGGB.csv", header=TRUE, encoding="latin1") ¾ GGEBiplot(Datos)
GRÁFICOS AVANZADOS
201
Posteriormente se obtiene la siguiente ventana que permite definir las características de la representación. Es necesario elegir tres parámetros u opciones gráficas: SVP, centrado y escalado:
202
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Se puede elegir con SVP (singular value partitioning) si deseamos centrar la atención –y mantener las relaciones de proporcionalidad– en los casos o filas «JK-(Row Metric Preserving)», en las variables o columnas «GH-(Column Metric preserving)» o ambas simultáneamente «HJ-(Dual Metric Preserving)» o «SQSymmetrical». La elección dependerá de la aplicación concreta, y de si deseamos visualizar y obtener conclusiones preferentemente relativas a casos o a variables. La elección del SVP influirá en las distancias entre casos o entre variables, y no afectará en general a las relaciones entre ambos. En este caso dejamos la opción por defecto «GH-(Column Metric preserving)».
Se puede centrar el gráfico en el origen de las variables «Tester-Centered G+GE» (en general la mejor opción), no centrar, o un centrado conjunto «Double-Centered GE». En este caso también dejamos la opción por defecto «Tester-Centered G+GE».
También podemos mantener los datos originales o tipificar dividiendo cada variable por su desviación típica mediante la opción «Scaled (Divided) By». Dividir por la desviación típica suele ser adecuado cuando las variables son heterogéneas y los valores muy desequilibrados (por ejemplo algunas variables toman valores en el rango de milésimas o centésimas, y otras valores en millones
GRÁFICOS AVANZADOS
203
o miles, por efecto de las distintas unidades de medida). Como en nuestro caso las variables son heterogéneas seleccionamos «Std Deviation (SD)».
El gráfico que se obtiene se muestra en la siguiente figura. A menudo las opciones por defecto son adecuadas, pero una vez creado el gráfico, se pueden modificar mediante la entrada de menú «Models». En general trataremos de conseguir el gráfico que nos permita visualizar mejor las relaciones entre casos y variables, a menudo con fines exploratorios.
204
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Los biplots deben interpretarse en términos de distancias entre elementos y orientación de los ejes. En el gráfico anterior, la variable PIB_cap toma valores más altos para Dinamarca, Gran Bretaña, Holanda, y más bajos para los que están en la dirección contraria, Botswana, Somalia, Nicaragua. Burkina Faso, Somalia o Gambia se caracterizan por valores altos de natalidad, fertilidad y mortalidad infantil, y bajos de esperanza de vida y tasas de alfabetización. Uganda y República Centroafricana tienen altas tasas de mortalidad, pero el grupo de países desarrollados (Holanda, Gran Bretaña, Dinamarca, etc.) también se sitúan orientados hacia los valores altos de la tasa de mortalidad (la proyección sobre el eje de mortalidad es similar a Zambia o Tanzania). Costa Rica o Paraguay tienen valores bajos de PIB, y también valores bajos de mortalidad, y altos de esperanza de vida. Además de los ejes 1 y 2, en el menú «Biplot» se puede seleccionar representar otros ejes, como se muestra en la siguiente figura.
En el menú «Biplot», es de gran utilidad la opción «Biplot 3D», ya que se obtiene un gráfico en otra ventana, que se muestra a continuación, el cual se puede rotar con el ratón para tener una mejor visión de donde se ubican los diferentes casos.
GRÁFICOS AVANZADOS
205
La entrada de menú «Biplot Tools» permite examinar una fila o caso «Examine a Genotype», o bien una columna o variable «Examine an Environment» por separado. Por ejemplo se selecciona España; el archivo de datos debe estar ordenado previamente por las etiquetas de filas (nombre de los países).
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
206
En el gráfico que se obtiene se muestran los dos ejes principales en color rojo. La etiqueta del país (en este ejemplo, España) indica el sentido positivo del eje principal. El segundo eje, perpendicular al primero, separa las variables que toman valores por encima de la media (del lado de la etiqueta: PIB, tasas de alfabetización, esperanza de vida) de las variables con valores por debajo de la media (mortalidad –próxima a la media-, mortalidad infantil, fertilidad, natalidad). Por lo tanto, las variables se pueden ordenar de acuerdo con su importancia, influencia, o adecuación. La distancia al eje principal, marcada con líneas punteadas, no debe ser interpretada, ya que corresponde al segundo eje, que explica una proporción mucho menor de variabilidad, y su significado es en general más complejo. Si el caso (país) está situado cerca del origen de coordenadas (Brasil, Bolivia), esta interpretación puede carecer de sentido y no debe ser utilizada.
2.0
Examine a Genotype
Mortalidad
1.0 0.5 AlfabetM 0.0
AXIS2 10.27 %
1.5
PIB_cap
España
Mortin
AlfabetF
-0.5
Fertilida pVidaF spVidaM
-1.5
Natalida
-1.0
-0.5
0.0
0.5
1.0
1.5
AXIS1 81.87 %
Las variables, representadas mediante vectores de color azul en el gráfico que se obtiene con la opción «Relation among Environments», están más correlacionadas entre sí cuanto más próximo a cero o a 180º sea el ángulo que forman. Si el ángulo es pequeño la correlación es positiva (natalidad y fertilidad) y si es grande negativa (mortalidad infantil y esperanza de vida). Si el ángulo es próximo a 90º no están correlacionadas (mortalidad y PIB). Las variables con vectores más grandes (en este caso prácticamente todas) son las que mejor discriminan o distinguen entre casos, y las que están cerca del origen las que menos diferencian los casos (países). No obstante el escalado mediante la desviación típica puede distorsionar esta interpretación. Si la variabilidad explicada por los dos ejes (en este ejemplo 81,87% + 10,27%= 92,14%) fuese pequeña, por ejemplo menor que el 50%, estas interpretaciones no serían válidas, y el biplot en general deja de tener interés práctico.
GRÁFICOS AVANZADOS
207
4
Relationship among environments
0
spVidaM pVidaF AlfabetF AlfabetM
Grecia Portugal Irlanda Islandia España
Natalida Fertilida Mortin
Gambia Burkina Faso Gabon Zambia Tanzania Haiti Ruanda Burundi R.Centroafri
Holanda Finlandia Noruega Francia Gran Bretaña Italia Suecia Bélgica Alemania Suiza Austria Dinamarca
-2
AXIS2 10.27 %
2
Paraguay Costa Rica Honduras Marruecos Panama Nicaragua Venezuela Mexico Ecuador El Salvador Colombia R.Dominicana Chile Botswana Guatemala Cuba Peru Sudáfrica Bolivia Senegal Nigeria Liberia Argentina Kenya UruguayBrasil Camerún Somalia Etiopia Barbados
-4
Uganda
PIB_cap -6
Mortalidad
-5
0
5
AXIS1 81.87 % Utilizando la opción «Compare two Genotypes», se pueden relacionar entre sí dos casos o filas de los datos (dos países) previamente elegidos. En el gráfico aparece una línea uniendo los dos países, en el ejemplo Dinamarca y Paraguay, junto con otra línea perpendicular que pasa por el origen. Esta última línea separa las variables: las que están del lado de cada país tienen valores más altos: Dinamarca tiene mayor PIB, mortalidad, esperanza de vida y tasas de alfabetización, Paraguay tiene mayor natalidad, fertilidad, y mortalidad infantil. Si ambos países están del mismo lado de la recta de separación, el que está más cerca de la línea es el que tiene valores más altos de las variables que se sitúan al otro lado.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
208
4
Compare two Genotypes
2
Paraguay Costa Rica Honduras Marruecos Panama Nicaragua Venezuela Mexico Ecuador Colombia El Salvador R.Dominicana Botswana Chile Guatemala Cuba Peru Sudáfrica Bolivia Senegal Nigeria Liberia Argentina Camerún Uruguay Brasil Kenya Etiopia Somalia Barbados Grecia Gambia Portugal Irlanda Islandia Burkina Faso España Gabon Holanda Zambia Finlandia Tanzania Noruega Francia Haiti Gran Bretaña Italia Suecia Burundi Ruanda Bélgica Alemania R.Centroafri Suiza Austria Dinamarca Uganda
AlfabetF AlfabetM
Natalida Fertilida Mortin
-4
-2
0
AXIS2 10.27 %
spVidaM pVidaF
PIB_cap -6
Mortalidad
-5
0
5
AXIS1 81.87 %
En «Which Won Where/What», es posible trazar líneas entre los marcadores de los casos más alejados del punto de origen (0,0), formando un polígono de forma tal que contenga a los marcadores de los casos restantes. También se dibujan desde el origen radios perpendiculares a los lados del polígono, que delimitan sectores. El caso ubicado en el vértice de cada sector es el que tiene el mayor valor para las variables situadas en él. Por ejemplo en este caso Uganda y la mortalidad, Dinamarca y el PIB_cap, etc. Esta herramienta es especialmente útil para trabajar con el tipo de datos para los cuales se diseñaron en su origen los GGE Biplots, es decir, para ver en que ambientes son más productivos los diferentes genotipos.
4
Discrimitiveness vs. representativenss
AlfabetF AlfabetM
Grecia Portugal Irlanda Islandia España
Natalidad Fertilidad Mortinf
Gambia Burkina Faso
Gabon Zambia Tanzania Haiti Burundi Ruanda R.Centroafri
Holanda Finlandia Noruega Francia Gran Bretaña Italia Suecia Bélgica Alemania Suiza Austria Dinamarca
-2
0
spVidaM spVidaF
-4
Uganda PIB_cap Mortalidad
-6
AXIS2 10.27 %
2
Paraguay Costa Rica Honduras Marruecos Panama Nicaragua Venezuela Mexico Ecuador Colombia El Salvador R.Dominicana Chile Botswana Guatemala Cuba Peru Sudáfrica Bolivia Senegal Nigeria Liberia Argentina Kenya UruguayBrasil Camerún Somalia Etiopia Barbados
-5
0 AXIS1 81.87 %
5
GRÁFICOS AVANZADOS
209
En «Discrimitiveness vs representativeness» se representan todas las variables (columnas) considerando su capacidad para distinguir entre casos (discriminación) y su representatividad. Un pequeño circulito azul indica la variable media, y una línea azul une esa media con la “variable ideal”, en el centro, la que supuestamente permite definir mejor los casos y es más representativa. Los casos aparecen representados mediante etiquetas de color verde. Los círculos concéntricos indican el alejamiento de cada variable de la situación ideal. Cuanto más cerca del centro (variable ideal), más representativa y discriminante es una variable. En este ejemplo no parece haber diferencias importantes entre variables, y todas ellas se alejan de forma muy similar de la “variable ideal”.
4
Discrimitiveness vs. representativenss
0
spVidaM pVidaF AlfabetF AlfabetM
Grecia Portugal Irlanda Islandia España
Natalida Fertilida Mortin
Gambia Burkina Faso
Gabon Zambia Tanzania Haiti Burundi Ruanda R.Centroafri
Holanda Finlandia Noruega Francia Gran Bretaña Italia Suecia Bélgica Alemania Suiza Austria Dinamarca
-2
AXIS2 10.27 %
2
Paraguay Costa Rica Marruecos Honduras Panama Nicaragua Venezuela Mexico Ecuador Colombia El Salvador R.Dominicana Botswana Chile Guatemala Cuba Peru Sudáfrica Bolivia Senegal Nigeria Liberia Kenya Argentina UruguayBrasil Camerún Etiopia Somalia Barbados
-4
Uganda
PIB_cap -6
Mortalidad
-5
0
5
AXIS1 81.87 %
En «Mean vs Stability» el gráfico representa las variables, indicando su media (media de las dos primeras componentes principales) con un circulito azul. Un primer eje verde pasa por esta variable media y por el origen del gráfico biplot. Se representa también otro segundo eje de coordenadas perpendicular a esa línea. Los casos se representan mediante su valor medio para todo el conjunto de variables, de forma que se pueden ordenar de menor a mayor (a lo largo de la línea verde en el sentido de la flecha) según su importancia relativa. Si el punto que representa la variable media está cerca del origen de coordenadas, eso indicará que tiene poco sentido o poco interés la ordenación de casos. El alejamiento de cada caso en el sentido del segundo eje –es decir alejado del primer eje verde- indica mayor variabilidad (a lo largo del conjunto de variables), y, por lo tanto, menor estabilidad de los casos. Los casos con mayor efecto medio y con mayor estabilidad se sitúan cerca del eje verde principal y en el sentido de la flecha.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
210
CostaParaguay Rica Natalida Honduras Marruecos Panama Nicaragua Venezuela Mexico Ecuador Colombia El Salvador R.Dominicana Chile Botswana Guatemala Cuba PeruSudáfrica Bolivia Senegal Fertilida Nigeria Liberia Kenya Argentina Camerún Brasil Etiopia Uruguay Somalia Barbados Gambia Grecia Portugal Irlanda Islandia Burkina Faso Mortin España Gabon Holanda Zambia Finlandia Tanzania Noruega Francia Haiti Gran Bretaña Italia Suecia Ruanda Burundi Bélgica Alemania R.Centroafri Suiza Austria Dinamarca Uganda
spVidaM pVidaF
AlfabetF
-1.0
-0.5
AlfabetM
-1.5
AXIS2 10.27 %
0.0
0.5
Mean vs. Stability
-2.0
PIB_cap Mortalidad
-1.5
-1.0
-0.5
0.0
0.5
1.0
1.5
AXIS1 81.87 % En «Rank Environments/Genotypes» se pueden obtener los dos gráficos que se muestran a continuación, que permiten ordenar las variables (environments) o los países (genotypes) de acuerdo con criterios agregados. Estos criterios no siempre tienen un significado adecuado o racional, y su interpretación dependerá de la aplicación concreta. En la primera figura se ordenan las variables. La “variable ideal” que se representa con una punta de flecha y una línea que la une con el origen de coordenadas, es la variable que en teoría mejor explica las diferencias entre filas o países con mayor discriminación y conservando al mismo tiempo la mayor estabilidad y representatividad. En general, cuanto más cerca estén las variables reales a esa variable ideal, mejor representan los aspectos positivos, y cuanto más alejadas (para eso se representan los círculos concéntricos) más se refieren a los aspectos negativos. En nuestro ejemplo, los aspectos “deseables” están asociados a las variables “positivas” PIB –especialmente-, esperanza de vida y tasa de alfabetización, y los aspectos “indeseables” a las variables “negativas” natalidad, mortalidad infantil y fertilidad, y a mitad de camino entre ambos extremos la variable mortalidad. El conjunto de variables utilizadas en este ejemplo definen globalmente el nivel de desarrollo, y las variables positivas o negativas lo son en relación con esa interpretación; así, una mortalidad elevada está asociada simultáneamente con países subdesarrollados y países avanzados, ya que existen causas de mortalidad relacionadas con altos niveles de desarrollo, lo que explica que la variable mortalidad no aparezca como claramente negativa.
GRÁFICOS AVANZADOS
211
Natalida Fertilida
AlfabetF AlfabetM
Mortin
-2
0
spVidaM pVidaF
-4
AXIS2 10.27 %
2
4
Ranking Environments
PIB_cap -6
Mortalidad
-5
0
5
AXIS1 81.87 %
En la segunda figura se ordenan los países o filas (genotypes). Se comparan de nuevo con el perfil ideal: el país ideal es el que tiene mejores resultados, y al mismo tiempo mayor estabilidad o equilibrio. Cada país se puede comparar con ese “país ideal”, de forma que cuanto más cerca esté, mejores serán los valores de las variables que lo definen. Los círculos concéntricos ayudan a establecer las distancias al perfil ideal con más precisión. En nuestro ejemplo los países más próximos a la situación ideal son los del grupo de Dinamarca, Holanda o Gran Bretaña. La línea verde perpendicular que pasa por el origen separa los países (genotypes) con buena y mala situación en relación con el significado global del conjunto de variables (en este ejemplo desarrollo económico-social).
4
Ranking Genotypes
AlfabetF AlfabetM
-4
-2
0
spVidaM spVidaF
PIB_cap Mortalidad
-6
AXIS2 10.27 %
2
Paraguay Costa Rica Honduras Marruecos Panama Nicaragua Venezuela Mexico Ecuador Colombia El Salvador R.Dominicana Botswana Chile Guatemala Cuba Peru Sudáfrica Bolivia Senegal Nigeria Liberia Argentina Camerún Kenya Uruguay Brasil Somalia Etiopia Barbados Grecia Gambia Portugal Irlanda Islandia Burkina Faso España Gabon Holanda Zambia Finlandia Tanzania Noruega Francia Haiti Gran Bretaña Italia Suecia Burundi Ruanda Bélgica Alemania R.Centroafri Suiza Austria Dinamarca Uganda
-5
0 AXIS1 81.87 %
5
Natalidad Fertilida Mortinf
212
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Por último, en «Format» se puede cambiar el título del gráfico y los colores de fondo, de las etiquetas y del título.
III.20.4. GRÁFICOS COMBINANDO ANÁLISIS DE COMPONENTES PRINCIPALES Y ANÁLISIS DISCRIMINANTE La función «dapc()» del paquete “adegenet” (Jombart y col., 2010; Jombart, 2012) realiza en primer lugar un Análisis de Componentes Principales (PCA) y, posteriormente, con los resultados del PCA realiza un Análisis Discriminante. Ambos análisis se combinan en un solo gráfico. Es necesario el paquete “ade4” (Chessel y col., 2012) para hacer el PCA. El PCA permite transformar el conjunto de variables originales en otro conjunto reducido de variables, las componentes, que conservan la mayor parte de la información sobre la variabilidad de los datos, pero siendo pocas (a menudo 2) permiten una representación gráfica de los elementos de la muestra que sería inviable con las variables originales en su conjunto. El Análisis Discriminante se utiliza para separar los elementos de la muestra en grupos o clases conocidas. Al combinar ambos métodos se obtiene una descripción gráfica más completa para el análisis de los datos, adecuada cuando tenemos muchas variables correlacionadas entre sí y un criterio de clasificación que queremos asociar a aquellas variables. Como ejemplo se utilizan los datos del apartado anterior con variables de un conjunto de 57 países de Europa, África y América. Las variables indican la esperanza de vida masculina y femenina al nacer (en años de vida), las tasas de mortalidad, mortalidad infantil, natalidad, y fertilidad, el producto interior bruto per cápita (en miles de dólares anuales), y la tasa de alfabetización de hombres
GRÁFICOS AVANZADOS
213
y mujeres (en porcentaje). Los datos están en el archivo Países.csv y las instrucciones en el script III.28.R. En la función «dapc()» se definen las variables que se quieren analizar, en este caso de la columna 3 a la 11. Con el argumento «grp» se especifica cual es la variable que se utiliza como agrupación. Con «n.pca» y «n.da» se define el número máximo de ejes que se guarda para el PCA y para el Análisis Discriminante, respectivamente.
¾ ¾ ¾ ¾ ¾
library(ade4) library(adegenet) datos<-read.csv2("Países.csv",header=TRUE,encoding="latin1") attach(datos) dapc1 <- dapc(datos[,3:11], grp=Continente, n.pca=60, n.da=30)
Con la instrucción «dapc1» se muestra la estructura de los resultados obtenidos, donde por ejemplo se observa que la contribución de cada variable original a las componentes principales se puede ver con la instrucción «dapc1$var.contr», las puntuaciones del PCA se podrían ver con la instrucción «dapc1$pca.loadings», etc.
¾ dapc1 ¾ dapc1$var.contr
214
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
A continuación, se realiza el gráfico combinado con la función «scatter.dapc()», donde «dapc1» es el resultado generado con la función anterior. Los argumentos «xax» y «yax» definen que ejes se representan (por defecto «xax=1» y «yax=2»). Con «solid» se especifica el grado de transparencia en una escala de 0 a 1 (0 indica máxima transparencia). Con «lab» se indica un vector de etiquetas para los casos (países). Si se pone NULL se utilizan los nombres de fila (x$tab, si existen) en el gráfico. Con los argumentos «scree.da=F» y «scree.pca=F» se especifica que no se representen los gráficos de sedimentos (scree plot) con los autovalores o varianzas de los ejes del DA y del PCA, respectivamente. Si los queremos representar indicaremos su posición con los argumentos «posi.pca» y «posi.da», y su tamaño relativo con respecto al gráfico actual con «ratio.pca» y «ratio.da». Por último, la función «text()» permite poner las etiquetas con los nombres de los países a cada uno de los puntos, usando las coordenadas del PCA del eje I «dapc1$ind.coord[,1]» y del eje II «dapc1$ind.coord[,2]». Con el argumento «srt» se especifica el ángulo de la etiquetas.
¾ scatter.dapc(dapc1,xax=1, yax=2, col=c("red","blue","green"), bg="white", solid=1, scree.da=F, scree.pca=F, legend=T, posi.leg="topright", cex.lab=2, lab=NULL) ¾ par(new=T) ¾ text(dapc1$ind.coord[,1], dapc1$ind.coord[,2], labels=País, pos=4, str=0) En el gráfico se muestran los elementos (países) formando grupos –definidos por la clase (continente) a la que pertenecen– que se identifican por el color. Para cada grupo se representa el centroide o punto medio, a partir del cual se dibujan radios vectores a cada uno de los países. Un elipsoide de variabilidad permite apreciar la forma de asociación de los elementos de cada clase (dentro del elipsoide está el 95% de los elementos del grupo), y averiguar cuales son los elementos que parecen diferenciarse del resto de su grupo. Así, en el grupo de países americanos, Guatemala y Haití, los menos desarrollados del conjunto, parecen acercarse al conjunto africano; Tanzania, Senegal o Uganda, entre los más pobres de este continente, se alejan de la media en sentido opuesto, mientras Gabón, con importantes recursos petrolíferos, se acerca ligeramente hacia el grupo europeo. Dentro de éste último grupo, algunos países (Grecia, Portugal, Irlanda, España, por este orden) parecen anunciar dificultades futuras en el desarrollo de la crisis que vendrá, con datos anticipados en más de una década. Las variables que mayor influencia tienen en esta agrupación son las de contribución más alta: Tasa de natalidad, Tasa de mortalidad, y Esperanza de vida.
GRÁFICOS AVANZADOS
215
El hecho de que los países de cada clase (en este caso cada continente) se agrupen formando conjuntos homogéneos y diferenciados a partir de las variables socioeconómicas (sin utilizar en ningún momento para la clasificación o para el gráfico criterios geográficos) indica que el desarrollo económico se produce por zonas, y que el avance de un país no es ajeno al de sus vecinos. Por el contrario, si los grupos que se muestran en el gráfico estuvieran solapados o mezclados, ello querría decir que el criterio de clasificación no está relacionado, o lo está en escasa medida, con el conjunto de variables cuantitativas utilizado en la aplicación del método. Africa América Europa Tanzania Senegal Uganda
Botswana
Gabon Ruanda Sudáfrica Burkina Faso Gambia Somalia Marruecos R.Centroafri Nigeria Burundi Camerún Etiopia Kenya Liberia
Suiza
Guatemala Zambia
Islandia Dinamarca Holanda Francia Austria GranNoruega Bretaña Suecia Alemania Bélgica Italia Finlandia
Irlanda Portugal España Grecia
Haiti
BoliviaPeru El Salvador Honduras Nicaragua Mexico Brasil Barbados Venezuela Uruguay Ecuador Colombia Cuba Paraguay ChileArgentina R.Dominicana Panama Costa Rica
Función dapc (paquete adegenet) x: un data.frame, una matriz o un objeto del tipo genind con las variables a representar, que tienen que ser cuantitativas. grp: variable de agrupación. n.pca y n.da: definen el número máximo de ejes que se guarda para el PCA y para el Análisis Discriminante, respectivamente. Si es NULL la selección es interactiva: n.pca=NULL y n.da=NULL. center: si es TRUE las variables se centran a una media de cero: center=TRUE.
216
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Función dapc (Continuación) scale: si es TRUE se escalan las variables dividiendo por su desviación típica estimada: scale=FALSE. var.contrib: si es TRUE se guardan las contribuciones de cada variable original a las funciones discriminantes: var.contrib=TRUE. pca.info: si es TRUE se guarda en los resultados la información del PCA: pca.info=TRUE. pca.select: carácter indicando el modo de selección de los ejes en el PCA. Con "nbEig" el usuario define el número de ejes en el argumento n.pca y con "percVar" se especifica que el criterio es alcanzar un determinado porcentaje de varianza explicada que se define en el argumento perc.pca: pca.select="nbEig". perc.pca: porcentaje de varianza explicada por los ejes que sirve para definir cuantos ejes del PCA se seleccionan: perc.pca=NULL.
III.21. Modelo de efectos principales aditivos e interacción multiplicativa (AMMI) Otro método que permite relacionar genotipo y ambiente es el modelo de efectos principales aditivos e interacción multiplicativa (AMMI, Zobel y col., 1988; Gauch y Zobel, 1988; 1996). Son necesarios los paquetes “agricolae” (de Mendiburu, 2012) y “klaR” (Roever y col., 2012). El procedimiento AMMI consiste en combinar las técnicas del análisis de varianza y el análisis de componentes principales (PCA) en un solo modelo, donde el análisis de varianza permite estudiar los efectos principales de los genotipos y ambientes y los análisis de CP la interacción GxA la cual es tratada de forma multivariada para su interpretación. Como ejemplo se usarán los valores del rendimiento de grano (kg ha-1) de 16 híbridos de maíz evaluados en 6 ambientes diferentes (Alejos y col., 2006). Los datos están en el archivo AMMI.csv y las instrucciones en el script III.29.R. En la función «AMMI()» es necesario especificar qué variables son el ambiente «ENV=», genotipo «GEN=», las réplicas «REP=» y la variable que se usa para cuantificar las diferencias entre genotipos en los diferentes ambientes «Y=», la cual en este ejemplo es el rendimiento del grano de maíz. Con el argumento «number=FALSE» se especifica que no salgan números y se pongan los códigos de cada uno de los genotipos.
¾ ¾ ¾ ¾ ¾ ¾
library(agricolae) library(klaR) datos<-read.csv2("AMMI.csv",header=TRUE,encoding="latin1") attach(datos) par(cex=1.1) model<- AMMI(ENV=Area, GEN=Genotipo, REP=Réplica, Rendimiento, graph="biplot", number=FALSE, xlim=c(-50,40))
Y=
Se obtienen los resultados de un ANOVA, el resumen del PCA y un gráfico biplot. Para más detalles sobre ANOVA y PCA véase Guisande y col. (2011), y para las conclusiones del trabajo véase Alejos y col. (2006).
GRÁFICOS AVANZADOS
PC
217
%
Yaritagua-1 FONAIAP-2004
20
1 37.2 2 26.9
HS-9 HS-3G
La Virgen
FONAIAP-2002 0
PC 2
Yaritagua-2
D-3160
SK-202 MTC-93225 FONAIAP-104 X-1409BW HS-11 D-2562 Las Velas
HIMECA-3002
MTC-93224 Camunare TOCORÓN-370
-20
HS-13
-40
HIMECA-2020
Guarabao -40
-20
0
20
40
PC 1
El gráfico biplot muestra la relación entre ambientes y genotipos. Se representan las dos primeras componentes principales de la variable rendimiento a través del conjunto de ambientes, y se acepta que hay interacción entre ambos (ambiente y genotipo) cuando la variabilidad explicada por las dos primeras
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
218
componentes representadas supera el 50%, como en el ejemplo (37,2 + 26,9 = 64,1%). Los ambientes aparecen representados mediante flechas de color rojo, y los genotipos en azul. Los ambientes próximos entre sí (La Virgen, Yaritagua 2) son similares, y los genotipos próximos a ellos son los que se desarrollan más favorablemente –con mayor rendimiento– en esos ambientes (FONAIAP-2004). Para obtener el segundo gráfico simplemente se sustituye «graph="biplot"» por «graph="triplot"» y se quitan los límites del eje x.
¾ model<- AMMI(ENV=Area, GEN=Genotipo, Rendimiento, graph="triplot", number=FALSE) PC
REP=Réplica,
Y=
%
1 37.2 2 26.9 3 19.6
FONAIAP-2004 Yaritagua-2
PC2
PC3
Yaritagua-1 SK-202 D-2562 FONAIAP-2002HS-11 Las Velas HS-9 HIMECA-3002 HS-3G MTC-93225 FONAIAP-104 D-3160 TOCORÓN-370
La Virgen
X-1409BW MTC-93224 Camunare HIMECA-2020 HS-13
PC1 Guarabao
En el gráfico triplot se representan las tres primeras componentes principales utilizando los ejes situados como lados de un triángulo equilátero. La primera componente se mide hacia el vértice izquierdo (desde el lado opuesto), la segunda hacia el vértice superior, y la tercera hacia el vértice derecho. La interpretación es igual que en el gráfico anterior, buscando la asociación por proximidad entre ambientes, entre genotipos, y entre ambientes y genotipos, aunque la ventaja de este gráfico es que se conserva un mayor porcentaje de variabilidad (83,7%) al emplear una componente más. En la interpretación del gráfico no se debe olvidar que cada eje tiene una importancia distinta, en proporción a la variabilidad explicada y, por lo tanto, las distancias entre puntos deben matizarse de acuerdo con la dirección.
GRÁFICOS AVANZADOS
219
III.22. Gráficos de inferencia en coste/eficacia El paquete “ICEinfer” (Obenchain, 2012) está dedicado al análisis y representación gráfica de relaciones de coste frente a eficacia o rendimiento, cuantificando y modelizando la incertidumbre asociada a los datos obtenidos por muestreo, así como otras posibles fuentes de incertidumbre (Obenchain y col., 1997: Obenchain, 1999). La inferencia estadística se realiza mediante técnicas no paramétricas de remuestreo (bootstrap). Este tipo de análisis se aplica a menudo en el ámbito de la medicina. Un nuevo tratamiento, más costoso que el anterior, puede presentar una mayor eficacia. Aquellos que deben financiar o pagar el servicio sanitario (como las empresas aseguradoras o los administradores de la sanidad pública) estarán quizás preocupados por los aspectos de incremento de coste, y los pacientes y sus familiares, o los médicos, lo estarán sobre todo por los aspectos de incremento de eficacia. ¿Justifica un pequeño aumento de eficacia un elevado coste adicional? Para visualizar esta relación entre las dos dimensiones del problema se suele representar en el eje horizontal el aumento de eficacia y en el vertical el incremento de coste (plano ICE). El ejemplo consiste en un ensayo clínico doble-ciego aleatorizado en el que 91 pacientes con depresión grave recibieron un tratamiento nuevo (duloxetina) y 87 pacientes otro estándar (paroxetina). El archivo de datos tiene 178 casos y 3 variables: eficacia (idb), coste (ru) y tratamiento (dulx). No hay archivo de datos ya que estos vienen en el paquete “ICEinfer”. Las instrucciones están en el script III.30.R. En el primer gráfico, con la función «ICEuncrt()» se generan muestras aleatorias mediante remuestreo. Con el argumento «df» se indica el data frame con las tres variables necesarias. El argumento «trtm» es para especificar la variable tratamiento; el valor 1 indica el tratamiento nuevo (duloxetina) y el 0 la ausencia de tratamiento o el tratamiento antiguo (paroxetina). Con el argumento «xeffe» se especifica la variable con la información de la eficacia del tratamiento. Con «ycost» se especifica la variable con el coste del tratamiento. Con «lambda», cuyo valor por defecto es 1, se introduce el valor del coste implícito (shadow price), o incremento de coste que la sociedad o los usuarios aceptarán por una unidad de aumento de eficacia, y equivale a una tasa de sustitución. Con «R=25000» se especifica que se generen 25.000 muestras aleatorias mediante remuestreo. Por último, con el argumento «seed=0» se establece el inicio del generador de números aleatorios. Este análisis se guarda en «dpunc» y, posteriormente, se representa el gráfico con la función «plot()».
¾ library(ICEinfer) ¾ data(dulxparx) ¾ dpunc <- ICEuncrt(df=dulxparx, trtm=dulx, xeffe=idb, ycost=ru, lambda=1, R = 25000, seed = 0) ¾ plot(dpunc) Las líneas horizontales y verticales en el medio de la figura indican el valor medio de las diferencias en coste (eje y) y eficacia (eje x) del tratamiento nuevo (trazo discontinuo) en relación con el antiguo (trazo continuo). La distribución aleatoria generada mediante remuestreo permite estimar con intervalos de confianza cualquier estadístico de interés. Se observa que la mayoría de los puntos
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
220
se sitúan en las posiciones correspondientes a menor coste (más abajo) y mayor eficacia (más a la derecha) del tratamiento nuevo.
0 -20
-10
Cost Difference
10
20
ICE Alias Uncertainty for Lambda = 1
-20
0
20
Effectiveness Difference Units = cost : Bootstrap Reps = 25000
La recta representada en diagonal en el plano ICE con trazo discontinuo tiene pendiente lambda, y representa los puntos de igual preferencia o igual beneficio neto BN (curva de indiferencia) y, como pasa por el origen, corresponde a un BN nulo, es decir, las situaciones en las que el mayor rendimiento está compensado exactamente por el incremento de coste. Los puntos en la recta de igual BN muestran la disposición de los usuarios a pagar más –WTP- por una mayor eficacia (hacia arriba a la derecha) o a aceptar una eficacia menor –WTA- a cambio de un coste más bajo (abajo a la izquierda). Un punto situado por debajo y a la derecha de la recta es siempre preferible a otro por encima y a la izquierda, ya que indica menor coste por la misma eficacia o mayor eficacia por el mismo coste. El valor de lambda debe estar razonablemente entre los límites (WTA, WTP), y una opción habitual es tomar la media geométrica de ambos valores. El primer objetivo es estimar la relación R= Incremento de Coste/Incremento de Eficacia del nuevo medicamento en relación con el antiguo a partir de los datos de la muestra. La posición de los puntos que representan ambas situaciones (coste/eficacia antigua y nueva) nos permite visualizar la relación: si el nuevo punto está a la derecha y por debajo del antiguo, eso indicará que el nuevo es mejor. Por lo tanto, es posible utilizar el ángulo que forma la línea que une ambos puntos con la horizontal en sustitución de R. Esta transformación angular (R por el ángulo) es más fácil de visualizar en el gráfico y presenta ventajas especialmente cuando el incremento de eficacia (el denominador) es muy pequeño,
GRÁFICOS AVANZADOS
221
ya que en ese caso el estimador de R es muy inestable. Naturalmente, los intervalos de confianza para la estimación de R se transforman en un ángulo a ambos lados del eje o dirección estimada para R. En la figura siguiente se muestra la estimación (línea punteada) de la relación coste/eficacia junto con los ángulos que representan los límites de confianza (en este caso el intervalo es muy grande, mayor que 180 grados).
¾ data(dpunc) ¾ dpwdg <- ICEwedge(dpunc, conf = 0.95) ¾ plot(dpwdg)
0 -20
-10
Cost Difference
10
20
Wedge-Shaped ICE Region with Confidence = 95 %
-10
-5
0
5
10
Effectiveness Difference Units = cost ; lambda = 0.26 ; Angles = alibi
El segundo objetivo del análisis, más ambicioso, consiste en representar en el gráfico las relaciones de preferencia coste/eficacia. En el caso más sencillo, si suponemos que la tasa de sustitución lambda refleja realmente la situación de equivalencia para cualquier punto del plano, podemos utilizar la recta con pendiente lambda que pasa por el origen como curva de indiferencia, como se indicó anteriormente, y rectas paralelas a ésta para indicar distintos niveles de preferencia mayor (por debajo) o menor (por encima). El plano ICE quedaría de este modo dividido en franjas por esas rectas paralelas con pendiente igual a lambda –curvas de indiferencia- indicando preferencias crecientes de arriba abajo (o de izquierda a derecha). No obstante ese planteamiento no es realista. La relación de preferencia cambia en las distintas zonas del plano y no es razonable considerar constante la tasa de sustitución cualquiera que sea la posición en el plano. Se han utilizado
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
222
distintas expresiones para medir la preferencia en función de las coordenadas x e y, de las cuales la que se expone a continuación -empleada por el paquete “ICEinfer”- es una función general que parece cumplir razonablemente los distintos principios y axiomas establecidos sobre el concepto de preferencia (monotonicidad, simetría, indiferencia, invariancia ante cambios de escala, etc.).
P(x, y) ~ (x2 + y2) (-)/2 {x - y}
El simbolo ~ significa “proporcional a”; {x - y} es igual a (x – y) multiplicado por el signo (1 o -1) de x-y. El parámetro mide las “economías de escala”, o los cambios en la proporcionalidad de la preferencia cuando nos movemos a lo largo de los ejes. Las preferencias cambian proporcionalmente (=1), más que proporcionalmente (>1) o menos que proporcionalmente (<1). Valores grandes de harán que las curvas se distancien cada vez menos entre sí al alejarse del origen en el centro del gráfico. Valores de gamma distintos de la unidad harán que las curvas de indiferencia se alejen de la linealidad (más distintas de la recta), aunque la forma también depende de beta; valores de gamma < beta producen curvas de indiferencia –atípicas– cóncavas hacia el origen. El mapa con curvas de indiferencia que son rectas paralelas equidistantes citado anteriormente se obtiene con beta = gamma =1. Se utiliza también en los gráficos el cociente eta = gamma/beta.
¾ dpcol <- ICEcolor(dpwdg) ¾ plot(dpcol)
-5 -10 -15 -20
Cost Difference
0
5
10
ICE Alibi Confidence Wedge with Preference Colors
-20
-10
0
10
Effectiveness Difference lambda = 0.26 , beta = 1 , gamma = 5.828 , eta = 5.828
20
GRÁFICOS AVANZADOS
223
Para cuantificar la incertidumbre –tanto estadística como económica– asociada a los diferentes parámetros (especialmente lambda), se puede utilizar la distribución de preferencia económica, calculada mediante remuestreo, para los puntos (x,y) del plano ICE que están dentro de los límites de confianza del 95%. El histograma correspondiente, elaborado automáticamente por la función «ICEcolor()», se muestra a continuación.
4000 0
2000
Frequency
6000
8000
Economic Preference Distribution within ICE Wedge
0
5
10
Preference Score En este ejemplo se observa que predominan los valores bajos, con una distribución claramente asimétrica. La mayoría de los usuarios se sitúan en las posiciones –puntos en el plano– correspondientes a coste bajo y eficacia menor. Por último, el gráfico 5 es un mapa completo de preferencias que se obtiene con la función «ICEomega()».
¾ epm <- ICEomega(beta=0.8) ¾ require(lattice) ¾ plot(epm)
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
224
ICE Economic Preference Map
40
30 5 20
Delta Cost
10
0
0
-10
-20 -5 -30
-40
-5
0
5
Delta Effectiveness (Cost Units) lambda = 1 , beta = 0.8 , gamma= 4.663 , eta= 5.828
Esta representación permite apreciar los efectos sobre las curvas de indiferencia, o de igual Beneficio Neto, de los cambios en el valor de lambda (coste total implícito) y en otros parámetros del modelo (beta y gamma, que regulan la linealidad y otras características de forma). Los distintos colores muestran las situaciones de coste/eficacia que los usuarios consideran equivalentes. Los valores de preferencia aumentan hacia el ángulo inferior derecho y disminuyen hacia el superior izquierdo. Si se utiliza el valor estándar lambda = 1, como en el ejemplo, se obtiene un mapa en el que los puntos de la diagonal (x=y) tienen preferencia cero (la ventaja en eficacia se compensa con el aumento de coste) y, además, las curvas de indiferencia son simétricas con respecto a esa diagonal.
III.23. Meta-análisis Meta-análisis es una técnica estadística que permite combinar varios estudios estadísticos en uno solo. Con ello se consigue construir estadísticos de resumen que puedan sacar ventaja de la mayor potencia proporcionada por el tamaño de muestra, necesariamente más grande, resultante de la agregación de las diferentes muestras de todos los estudios. Este análisis es de especial interés en
GRÁFICOS AVANZADOS
225
medicina, donde es importante determinar si un determinado medicamento, un compuesto, una terapia, etc., puede ser beneficioso o perjudicial para la salud y, sobre todo, en aquellos casos en los cuales existe discrepancia entre los diferentes estudios. Como se mencionó anteriormente, la ventaja del meta-análisis es que permite combinar la información de todos los trabajos realizados. Las representaciones que se utilizan más frecuentemente son el diagrama de bosque y el diagrama de embudo.
III.23.1. DIAGRAMA DE BOSQUE Para este tipo de gráfico se pueden usar las funciones «metabin()» y «forest.meta()» del paquete “meta” (Schwarzer, 2012). Las instrucciones están en el script III.31.R. Los datos, que están en el archivo Meta-análisis.csv, corresponden a un estudio de Silagy y Ketteridge (1997) sobre el efecto que tiene el consejo médico a la hora de dejar de fumar. En el archivo de datos, la variable «n.evento» hace referencia al número de personas que dejaron el tabaco por recomendación del médico, «N.evento» el número total de personas del grupo a las que el médico recomendó dejar de fumar y, «n.control» y «N.control» son las personas que dejaron de fumar y el total de personas que estaban en el grupo control, a las que el médico no les recomendó dejar el tabaco, respectivamente. Con esos datos se puede calcular para cada estudio la OR (Odds Ratio), que muestra el efecto del consejo del médico de dejar de fumar. El meta-análisis permite calcular una OR agregada, considerando la muestra total de todos los estudios. En la función «metabin()» hay que poner las variables que necesita la función: «event.e» número de eventos a los que afecta el tratamiento en el grupo experimental, «n.e» número total de observaciones en el grupo experimental, «event.c» número de eventos a los que afecta el tratamiento en el grupo control y «n.c» número total de observaciones en el grupo control. Con el argumento «sm» se indica la medida utilizada para resumir la información: riesgo relativo "RR", razón de ventajas (odds ratio) "OR", diferencia de riesgo "RD" o arcoseno de la diferencia "AS". Con «method» se especifica el método de agrupación de los casos: Mantel-Haenszel "MH", inverso de la varianza "Inverse" o método Peto "Peto". Con «studlab» se puede incluir un vector opcional con etiquetas para cada uno de los estudios. Con «print.CMH=TRUE» se indica que se muestre el resultado del test Cochran-Mantel-Haenszel, que evalúa el efecto conjunto de todos los estudios. En la función «forest.meta()» con los argumentos «pooled.totals=T» y «pooled.events=T» se especifica que se muestre el número total de observaciones y eventos de todos los estudios. Con «leftcols» y «rightcols» se especifica qué parámetros adicionales se muestran en el lado izquierdo y derecho del diagrama, respectivamente, y con «leftlabs» y «rightlabs» se ponen las etiquetas de los parámetros anteriores (debe ser el mismo número de etiquetas que parámetros en «leftcols» y «rightcols»). Los argumentos «lab.e» y «lab.c» son leyendas del resumen de los datos del grupo experimental y del grupo control, respectivamente. Con «addspace=FALSE» se indica que no se deje una línea en blanco entre los títulos y la tabla con los datos de los estudios. Por último, con «col.square» y «col.diamond» se definen los colores de los símbolos (cuadrados) de cada estudio que muestran el tamaño de la muestra y su valor de OR, y el de los símbolos (rombos) que indican el promedio de los efectos fijos y aleatorios, respectivamente.
226
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
¾ ¾ ¾ ¾
library(meta) datos<-read.csv2("Meta-análisis.csv", header=TRUE, encoding="latin1") attach(datos) meta <- metabin(event.e=n.evento, n.e=N.evento, event.c=n.control, n.c= N.control, sm="OR", method="MH", studlab=paste(Estudio,Año), print.CMH=TRUE) ¾ meta ¾ forest.meta(meta, text.fixed ="Modelo de efectos fijos", text.random="Modelo de efectos aleatorios", pooled.totals=T, pooled.events=T, xlab="Razón de ventajas (OR)", leftcols=c("studlab", "event.e", "n.e", "event.c", "n.c"), leftlabs= c("Estudio", "Eventos", "Total", "Eventos", "Total"), rightcols=c("effect", "ci", "w.fixed", "w.random"), rightlabs=c("OR", "95%-CI", "W(fijo)", "W(aleatorio)"), lab.e= "Experimental", lab.c="Control", hetlab= "Heterogeneidad: ", addspace= FALSE, col.square="red", col.diamond= "blue", fs.xlab=14, ff.xlab=2) En el test de Cochran-Mantel-Haenszel p < 0,001 y, por tanto, el número de pacientes que dejan de fumar es diferente en el grupo experimental y en el de control (véase Guisande y col., 2011 para más detalles sobre este test).
Estudio Porter 1972 Rusell 1979 Wilson 1982 Stewart 1982 Rusell 1983 Jamrozik 1984 McDowell 1985 Page 1986 Janz 1987 Slama 1990 Vetter 1990 Demens 1990 Wilson 1990 Haug 1994 Higashi 1995 Slama 1995 Modelo de efectos fijos Modelo de efectos aleatorios
Control Experimental Eventos Total Eventos Total 90 4 5 101 8 1107 34 1031 11 105 21 106 4 187 11 504 35 659 43 761 58 549 77 512 78 11 85 12 68 5 8 114 12 106 28 144 1 106 1 104 20 234 34 237 5 292 15 292 17 532 43 577 7 109 20 154 35 489 53 468 5 929 42 2199 447 7389
95% -CI W(fijo) W(aleatorio) OR 2.3% 1.12 [0.29; 4.30] 1.8% 5.8% 4.68 [2.16; 10.17] 3.4% 5.7% 2.11 [0.96; 4.63] 4.0% 3.0% 1.02 [0.32; 3.25] 2.6% 11.7% 1.07 [0.67; 1.69] 16.1% 14.6% 1.50 [1.04; 2.16] 21.7% 4.7% 1.00 [0.41; 2.42] 4.5% 3.0% 0.95 [0.30; 3.03] 2.7% 6.4% 1.89 [0.91; 3.92] 5.1% 0.6% 1.02 [0.06; 16.52] 0.4% 8.7% 1.79 [1.00; 3.22] 7.9% 3.7% 3.11 [1.11; 8.67] 2.2% 8.9% 2.44 [1.37; 4.33] 7.5% 4.6% 2.17 [0.89; 5.34] 3.2% 12.0% 1.66 [1.06; 2.59] 13.8% 4.4% 3.60 [1.42; 9.12] 3.1%
238 5640
1.76 [1.49; 2.08] 100% -1.76 [1.42; 2.18]
-100%
Heterogeneidad: I-squared=27.7%, tau-squared=0.0478, p=0.1451
0.1
0.5 1
2
10
Razón de ventajas (OR)
En el diagrama de bosque anterior se muestran las OR e intervalos de confianza de los distintos estudios. El valor estimado se representa mediante un cuadrado, y los límites de confianza son los extremos de cada línea horizontal. Vemos como muchas líneas sobrepasan el valor 1 por la derecha, indicando que la proporción de personas que dejan de fumar es mayor en el grupo experimental que fue aconsejado por el médico, que en el grupo control que no estaba influenciado por las recomendaciones del médico. El tamaño del cuadrado indica la
GRÁFICOS AVANZADOS
227
muestra utilizada: cuanto más grande es el cuadrado más representativo es el estudio y, por lo tanto, más fiables sus conclusiones. W es el peso o ponderación que corresponde a cada estudio en la obtención de la OR promedio o de resumen. Su valor depende del método de agregación utilizado, de los tamaños de muestra y del número de eventos en cada estudio. Si los estudios utilizados en el meta-análisis son todos los estudios existentes debemos utilizar el modelo de efectos fijos y, si se trata de una muestra de estudios elegida al azar, el aleatorio. Cuando los estudios son muy heterogéneos, es decir muy diferentes entre sí, es discutible que puedan agregarse en uno solo. Por esa razón se utilizan diferentes medidas de heterogeneidad. Entre ellas están Tau cuadrado, variabilidad entre estudios, o el estadístico I cuadrado, que mide la proporción de la variabilidad total que es atribuible a la heterogeneidad entre estudios, es decir, la variabilidad entre estudios dividida por la variabilidad total = variabilidad entre estudios + variabilidad entre pacientes. Los autores del estadístico I cuadrado (Higgins y col., 2003) proponen los valores de corte 25 y 75 para interpretar que la heterogeneidad es baja (menos de 25%), moderada (25% - 75%) o alta (más de 75%). En nuestro ejemplo, 27,6% es moderadabaja y, por consiguiente, no supone ningún problema. La OR de resumen calculada con el meta-análisis, se representa mediante un rombo en la parte inferior, siendo los extremos del rombo los límites de confianza correspondientes. Observamos como el intervalo de confianza es mucho más pequeño que cualquiera de los estudios individuales, lo que se debe al mayor tamaño de la muestra agregada, y el hecho de que sea mayor de 1, en concreto 1,61 para los efectos fijos y 1,67 para los aleatorios, significa que el médico influye positivamente a la hora de dejar el tabaco y, además, como mostró el test de Cochran-Mantel-Haenszel, esta diferencia es significativa. El gráfico permite, por lo tanto, apreciar los resultados y conclusiones de cada uno de los estudios individuales y el resultado agregado conseguido con el meta-análisis. El test de heterogeneidad muestra un p = 0,128, indicando que los diferentes estudios son homogéneos. Si la probabilidad fuese < 0,05, esto indicaría que los estudios no son homogéneos y las conclusiones del meta-análisis no serían válidas
Función metabin (paquete meta)
event.e: número de eventos en el grupo experimental. n.e: número total de observaciones en el grupo experimental. event.c: número de eventos en el grupo control. n.c: número total de observaciones en el grupo control. studlab: vector opcional donde se pueden incluir más etiquetas para cada uno de los estudios. data: data frame opcional con las cuatro variables necesarias: data=NULL. subset: vector opcional para seleccionar un grupo de datos: subset=NULL. method: método de agrupación de los estudios: Mantel-Haenszel "MH", inverso de la varianza "Inverse" o método Peto "Peto": method="MH".
228
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Función metabin (Continuación) sm: medida de resumen utilizada para resumir la información: riesgo relativo "RR", razón de ventajas (odds ratio) "OR", diferencia de riesgo "RD" o arcoseno de la diferencia "AS": sm="RR". incr: valor numérico que se asigna a aquellos estudios en los que algún grupo tiene un valor cero: incr=0.5. allincr: si es FALSE el valor de incr solamente se añade a los grupos con valores cero y no a todos los grupos: allincr=FALSE. addincr: si es TRUE se añade el valor de incr a todos los grupos, aunque no exista ninguno con valor cero: addincr=FALSE. allstudies: si es FALSE no se incluyen los estudios que tengan cero o todos los eventos en ambos grupos. Solamente se aplica si sm es "RR" o "OR": allstudies=FALSE. MH.exact: si es TRUE, no se suma incr a todas las frecuencias de estudios con recuento cero para los cálculos basados en el método de Mantel-Haenszel: MH.exact=FALSE. RR.cochrane: si es TRUE se añade 2*incr a n.e y n.c en los grupos con frecuencia cero: RR.cochrane= FALSE. level: nivel de confianza que se usa para calcular los intervalos de cada uno de los estudios: level=0.95. level.comb: el nivel de confianza que se usa para calcular los intervalos del promedio de todos los estudios: level.comb=level. comb.fixed: si es TRUE se aplica un modelo de efectos fijos: comb.fixed=TRUE. comb.random: si es TRUE se aplica un modelo de efectos aleatorios: comb.random=TRUE. title: título general del análisis: title="". complab: título para especificar el tipo de comparación que se realiza: complab="". outclab: título para especificar el tipo de salida del análisis: outclab="". label.e: etiqueta para el grupo experimental: label.e= "Experimental". label.c: etiqueta para el grupo de control: label.c="Control". byvar: vector opcional con información para agrupación. Debe tener el mismo número de estudios que event.e. bylab: texto con el nombre de la variable agrupación. print.byvar: si es TRUE el nombre de la variable agrupación sale delante del nombre de los grupos: print.byvar=TRUE. print.CMH: si es TRUE se muestra el resultado del test CochranMantel-Haenszel, que evalua el efecto conjunto de todos los estudios: print.CMH=FALSE. warn: si es TRUE sale un mensaje de aviso si se añade el valor de incr a algún análisis: warn=TRUE.
GRÁFICOS AVANZADOS
229
Función forest.meta (paquete meta) x: objeto con el formato meta. sortvar: vector adicional para ordenar los estudios que debe tener el mismo número de elementos que x. overall: si es TRUE se muestran los resúmenes de los valores W(fixed) y W(random): overall=TRUE. text.fixed: texto del modelo de efectos fijos: text.fixed="Fixed effect model". text.random: texto del modelo de efectos aleatorios: text.random="Random effects model". lty.fixed: tipo de línea del promedio del modelo de efectos fijos: lty.fixed=2. lty.random: tipo de línea del promedio del modelo de efectos aleatorios: lty.random=3. text.fixed.w: texto para etiquetar las estimaciones promedio del modelo de efectos fijos: text.fixed.w=text.fixed. text.random.w: texto para etiquetar las estimaciones promedio del modelo de efectos aleatorios: text.random.w=text.random. pooled.totals: si es FALSE no se muestra el número total de observaciones del conjunto de todos los estudios: pooled.totals= comb.fixed|comb.random. pooled.events: si es FALSE no se muestra el número total de eventos del conjunto de todos los estudios: pooled.events= FALSE. xlab.pos: valor numérico indicando la posición central de la leyenda del eje x: xlab.pos=ref. allstudies: si es TRUE se incluyen en el gráfico también los estudios para los que no fue posible estimar los efectos del tratamiento: allstudies=TRUE. weight: el tamaño de los símbolos indica el tamaño de muestra del estudio si no se pone este argumento. Si se pone "same" todos los símbolos son iguales y con "fixed" y "random" el tamaño de los símbolos depende de los valores W(fixed) y W(random), respectivamente. pscale: se utiliza para cambiar la escala de las proporciones de los objetos de tipo metaprop. Por ejemplo, pscale = 100 significa que las proporciones se expresan por 100 observaciones: pscale=1. ref: valor numérico indicando el valor de x donde pintar una línea de referencia. leftcols: parámetros que se muestran en el lado izquierdo del diagrama: leftcols=c("studlab", "event.e", "n.e", "event.c", "n.c"). rightcols: parámetros que se muestran en el lado derecho del diagrama: rightcols=c("effect", "ci"). leftlabs y rightlabs: etiquetas de los parámetros anteriores.
230
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Función forest.meta (Continuación) lab.e y lab.c: leyendas del resumen de los datos del grupo experimental y del grupo control, respectivamente: lab.e= "Experimental" y lab.c="Control". lab.e.attach.to.col y lab.c.attach.to.col: se especifican las columnas donde ubicar las etiquetas lab.e y lab.c, respectivamente. at: vector numérico con la posición de las marcas del eje x: at=NULL. label: si es TRUE se muestran las etiquetas de las marcas anteriores: label=TRUE. col.i: color de los resultados del estudio individual y los límites de confianza: col.i="black". col.i.inside.square: color de los resultados del estudio individual y los límites de confianza, si los límites de confianza están completamente dentro de los cuadrados: col.i.inside.square= "white". col.square: color de los símbolos que muestran el número de datos de cada estudio: col.square="gray". col.square.lines: color del borde de los símbolos que muestran el número de datos de cada estudio: col.square.lines=col.square. col.diamond: color de los rombos que representan los resultados de los modelos de efectos fijos y efectos aleatorios: col.diamond= "gray". col.diamond.fixed: color de los rombos de las estimaciones de efectos fijos: col.diamond.fixed=col.diamond. col.diamond.random: color de los rombos de las estimaciones de efectos aleatorios: col.diamond.random=col.diamond. col.diamond.lines: color de las líneas exteriores de los rombos que representan los resultados de los modelos de efectos fijos y efectos aleatorios: col.diamond.lines="black". col.diamond.fixed.lines: color de las líneas externas de los rombos para la estimación de efectos fijos: col.diamond.fixed.lines= col.diamond.lines. col.diamond.random.lines: color de las líneas externas de los rombos para la estimación de efectos aleatorios: col.diamond. random.lines=col.diamond.lines. col.by: color para imprimir la información en los subgrupos: col.by= ="darkgray". print.I2: si es TRUE se muestra el estadístico I-cuadrado: print.I2=TRUE. print.tau2: si es TRUE se muestra el estadístico tau-cuadrado: print.tau2=TRUE. print.Q: si es TRUE se muestra el estadístico Q de heterogeneidad: print.Q=FALSE. print.p.val.Q: si es TRUE se muestra la probabilidad del estadístico Q: print.pval.Q=TRUE.
GRÁFICOS AVANZADOS
231
Función forest.meta (Continuación) hetstat: con solamente este argumento se puede definir que estadísticos de los mencionados anteriormente se muestran: hetstat=print.I2| print.tau2|print.Q|print.pval.Q. hetlab: etiqueta de los índices de heterogeneidad hetlab= "Heterogeneity: ". fontsize: tamaño de texto (en puntos). fs.heading: tamaño de texto de las leyendas de las columnas. fs.fixed: tamaño de texto de los resultados del modelo de efectos fijos. fs.random: tamaño de texto de los resultados del modelo de efectos aleatorios. fs.study: tamaño de texto de los estudios individuales: fs.study=fontsize. fs.fixed.labels: tamaño de texto de las leyendas del modelo de efectos fijos: fs.fixed.labels=fs.fixed. fs.random.labels: tamaño de texto de las leyendas del modelo de efectos aleatorios: fs.random.labels=fs.random. fs.study.labels: tamaño de texto de las leyendas de los estudios individuales: fs.study.labels=fs.study. fs.hetstat: tamaño de texto de las medidas de heterogeneidad: fs.hetstat=fontsize-2. fs.axis: tamaño de texto de la escala del eje x: fs.axis=fontsize. fs.xlab: tamaño de texto de la leyenda del eje x: fs.xlab=fontsize. ff.heading: tipo de texto de las leyendas de las columnas: ff.heading=fontsize. ff.fixed: tipo de texto de los resultados del modelo de efectos fijos: ff.fixed="bold". ff.random: tipo de texto de los resultados del modelo de efectos aleatorios: ff.random=ff.fixed. ff.study: tipo de texto de los estudios individuales: ff.study= "plain". ff.fixed.labels: tipo de texto de las leyendas del modelo de efectos fijos: ff.fixed.labels=ff.fixed. ff.random.labels: tipo de texto de las leyendas del modelo de efectos aleatorios: ff.random.labels=ff.random. ff.fixed.labels: tipo de texto de las leyendas del modelo de efectos fijos: ff.fixed.labels=ff.fixed. ff.random.labels: tipo de texto de las leyendas del modelo de efectos aleatorios: ff.random.labels=ff.random. ff.study.labels: tipo de texto de las leyendas de los estudios individuales: ff.study.labels=ff.study. ff.hetstat: tipo de texto de las medidas de heterogeneidad: ff.hetstat="bold.italic".
232
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Función forest.meta (Continuación) ff.axis: tipo de texto de la escala eje x: ff.axis="plain". ff.xlab: tipo de texto del la leyenda del eje x: ff.xlab="plain". squaresize: valor numérico que define el tamaño de los símbolos cuadrados: squaresize=0.8. plotwidth: ancho del gráfico: plotwidth= unit(6, "cm"). colgap: espacio entre las columnas de la izquierda y derecha: colgap= unit(2, "mm"). colgap.left: espacio entre las columnas de la izquierda: colgap.left= colgap. colgap.right: espacio entre las columnas de la derecha: colgap. right=colgap. colgap.forest: espacio entre las columnas adyacentes de la izquierda y derecha con el gráfico: colgap.forest= colgap. colgap.forest.left: espacio entre las columnas adyacentes de la izquierda y el gráfico: colgap.forest.left= colgap.forest. colgap.forest.right: espacio entre las columnas adyacentes de la derecha y el gráfico: colgap.forest.right= colgap.forest. just: justificación del texto con las opciones de "left", "right" o "center": just="center". addspace: si es TRUE se añade una línea en blanco para separar los resultados de los estudios: addspace= TRUE. new: si es TRUE el nuevo gráfico se añade al anterior: new=TRUE. digits: número de decimales: digits=2. Los argumentos byvar, bylab, print.byvar, studlab, level, level.comb, comb.fixed y comb.random son iguales que en la función metabin(). También se pueden usar los argumentos generales xlim, xlab y lwd.
III.23.2. GRÁFICO DE L'ABBÉ En el caso de que exista heterogeneidad en los estudios, el gráfico de L´Abbé permite identificar cuales son los estudios responsables de esta heterogeneidad. Se puede usar las funciones «metabin()» y «labbe.meta()» del paquete “meta” (Schwarzer, 2012). Las instrucciones están en el script III.32.R. Los datos, que están en el archivo Meta-análisis.csv, son del mismo ejemplo usado en el apartado anterior de Silagy y Ketteridge (1997) sobre el efecto que tiene el consejo médico a la hora de dejar de fumar. La primera parte del script en la que se usa la función «metabin()» es igual que la explicada en el apartado anterior. En la función «labbe.metabin()» los argumentos son prácticamente iguales a la función «forest.meta()» explicada también en el apartado anterior.
¾ library(meta) ¾ datos<-read.csv2("Meta-análisis.csv", header=TRUE, encoding="latin1") ¾ attach(datos)
GRÁFICOS AVANZADOS
233
¾ meta <- metabin(event.e=n.evento, n.e=N.evento, event.c=n.control, n.c= N.control, sm="OR", method="MH", studlab=paste(Estudio, Año), print.CMH=TRUE) ¾ labbe.metabin(meta, xlab="Tasa de eventos (grupo control)", ylab="Tasa de eventos (grupo experimental)", studlab=TRUE, xlim=c(-0.025,0.2), cex.lab= 1.3, cex.axis=1.2, main="Estudio de la influencia del médico\npara dejar de fumar", cex.main=1.4, bg="green") ¾ abline(a=0,b=1)
0.15
Wilson 1982 Janz 1987
Jamrozik 1984 Vetter 1990 McDowell 1985 Haug 1994
0.10
Higashi 1995
0.05
Wilson 1990
Page 1986
Rusell 1983 Demens 1990 Porter 1972 Rusell 1979
0.00
Tasa de eventos (grupo experimental)
0.20
Estudio de la influencia del médico para dejar de fumar
Stewart Slama 1995 1982 Slama 1990
0.00
0.05
0.10
0.15
0.20
Tasa de eventos (grupo control) El gráfico de L'Abbé ayuda a profundizar en el análisis de la presencia y causas de heterogeneidad en el meta-análisis. Se representa para cada estudio el resultado en el grupo de tratamiento (eje y) frente al resultado en el grupo de control (eje x), con una línea diagonal a 45º que divide al gráfico en dos partes: a un lado quedan los estudios en los que fue favorable el grupo experimental, y en el otro los estudios en los que fue favorable el grupo de control.
234
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
En el ejemplo, por encima de la diagonal están los estudios en los que la proporción de pacientes que dejaron de fumar gracias al consejo médico es mayor que en el grupo de control. Los puntos se representan en tamaño variable en función del tamaño de muestra y de la precisión de cada estimación, de modo que los puntos más grandes son los estudios más representativos. Si los puntos se agrupan en una zona estrecha, próxima a una línea recta, significa que los resultados son homogéneos, y si están dispersos muestran heterogeneidad. Se representa también la recta de ajuste a la nube de puntos (línea punteada), cuya pendiente está relacionada con la OR conjunta. Es fácil identificar los estudios más alejados del patrón mayoritario, es decir, de la recta de ajuste, que serían los responsables de la heterogeneidad observada, cuando existe.
Función labbe.metabin (paquete meta) x: objeto con el formato meta. TE.fixed: vector numérico opcional especificando los valores de los efectos combinados fijos: TE.fixed=x$TE.fixed. TE.random: vector numérico opcional especificando los valores de los efectos combinados aleatorios: TE.random=x$TE.random. text: un vector de caracteres que se pone en vez de los símbolos. cex: tamaño de los símbolos. cex.studlab: tamaño de las etiquetas de los estudios: cex.studlab= 0.8. Los argumentos comb.fixed, comb.random, lty.fixed, lty.random, sm, weight y studlab son iguales que en la función forest.meta(). También se pueden usar los argumentos generales col, bg, xlim, ylim, xlab, ylab, axes, pch y lwd.
III.23.3. DIAGRAMA DE EMBUDO Otro problema que puede tener el meta-análisis es el sesgo en la publicación, es decir, la publicación selectiva de los estudios en base a sus resultados. En otras palabras, que se publiquen más los resultados que tienen una determinada conclusión y menos los estudios en los cuales los resultados dan lugar a conclusiones diferentes. En algunos estudios se ha observado que si los resultados son negativos, es decir, que no se observa un efecto, no se suelen publicar, ya que se basa en la idea equivocada de que un no efecto no es noticia. También puede ocurrir que no se publiquen los resultados que son desfavorables a la terapia usada con un determinado fármaco. El diagrama de embudo permite visualizar y evaluar el sesgo en la publicación sobre un determinado tema. Las instrucciones están en el script III.33.R. Como ejemplo usaremos de nuevo los datos del archivo Meta-análisis.csv, que corresponden a un estudio de Silagy y Ketteridge (1997) sobre el efecto que tiene el consejo médico a la hora de dejar de fumar. La primera parte del script en la que se usa la función «metabin()» es igual a como se explicó en el apartado del diagrama de bosque. Con la función «metabias()» se realiza un test para evaluar la asimetría. El resultado es que no hay sesgo, ya que la probabilidad es mayor que 0,05 (p = 0,928). En la función «funnel.meta()», con el argumento «level» se define el nivel de confianza
GRÁFICOS AVANZADOS
235
del gráfico, con «contour.levels» los diferentes niveles de confianza para las tramas que se muestran en el gráfico y con «col.contour» los colores de esas tramas.
¾ ¾ ¾ ¾ ¾ ¾ ¾
¾
library(meta) datos<-read.csv2("Meta-análisis.csv", header=TRUE, encoding="latin1") attach(datos) meta <- metabin(event.e=n.evento, n.e=N.evento, event.c=n.control, n.c= N.control, sm="OR", method="MH", studlab=paste(Año), print.CMH= TRUE) metabias(meta) color<-c("grey60", "grey80", "grey90") funnel.meta(meta, comb.fixed=TRUE, level=0.95, contour.levels=c(0.9, 0.95, 0.99), col.contour=color, studlab=TRUE, xlab="Razón de ventajas (OR)", ylab="Error estándar", cex.lab=1.6, main="Sesgo en las publicaciones", cex.main=1.8) legend(5, 0.1,c("0.1 > p > 0.05", "0.05 > p > 0.01", "< 0.01"), fill=color)
0.2
0.0
Sesgo en las publicaciones
1984 1983 1995
0.6
1985
1987 1982 1994
1979 1995 1990
1982 1986
1.2
1.0
0.8
1972
1.4
Error estándar
0.4
19901990
1990
0.1
0.2
0.5
1.0
2.0
5.0
Razón de ventajas (OR)
10.0
20.0
236
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
El análisis para realizar el gráfico de embudo parte de la idea de que los estudios negativos, que no muestran efecto, tienen menor probabilidad de ser publicados. Si existe sesgo de publicación, que puede ocurrir preferentemente en los estudios pequeños en los que hay mayor probabilidad de que se alteren los resultados por azar, se tendería a publicar los que mostraran diferencias. En el diagrama de embudo se representa el estimador de diferencias calculado en el meta-análisis (razón de ventajas, riesgo relativo, etc.) para cada estudio, junto con su error estándar. En el caso de no existir sesgo, los puntos se deberían agrupar alrededor de un estimador central, y mostrarían tanta mayor dispersión alrededor de este valor cuanto más pequeño fuera su tamaño, de modo que la nube de puntos se distribuiría en forma de embudo invertido. Si hubiera sesgo de publicación en el sentido descrito anteriormente, la nube de puntos se deformaría y el embudo perdería su simetría. En la gráfica anterior se observa que la distribución tiene forma de embudo, corroborando la ausencia de sesgo que también mostró el test de asimetría. En el gráfico se muestra, con líneas punteadas, el embudo al que se ajustan los datos, centrado en la OR estimada. Si los puntos encajan razonablemente en el embudo, sin asimetrías notables, significa que no existe evidencia de sesgo (así ocurre en el ejemplo). También se muestran, con distintos tonos de gris, los límites de confianza para los niveles indicados en el argumento «contour.levels» (en este ejemplo 90%, 95% y 99%), basados en la hipótesis nula de que no existe efecto (OR = 1), es decir centrados los embudos en el valor 1. Los puntos que están fuera de los límites de confianza muestran los estudios con efectos significativos para el nivel correspondiente.
Función funnel.meta (paquete meta) x: objeto con el formato meta. level: nivel de confianza que se usa en el gráfico. contour.levels: vector numérico especificando los diferentes niveles de confianza para las tramas que se muestran en el gráfico. col.contour: colores de los contornos anteriores. Los argumentos comb.fixed, comb.random, lty.fixed, lty.random, sm, weight, studlab, cex.studlab, text y cex son iguales que en las funciones forest.meta() y labbe.metabin(). También se pueden usar los argumentos generales col, bg, xlim, ylim, xlab, ylab, axes, pch y lwd.
III.23.4. DIAGRAMA DE ANÁLISIS DE SENSIBILIDAD En este diagrama se realiza un análisis de sensibilidad para determinar la influencia de cada uno de los estudios en la estimación global del efecto y, por lo tanto, la robustez o estabilidad de la medida final obtenida en el meta-análisis. El método consiste en la repetición del meta-análisis tantas veces como estudios seleccionados, de forma que cada vez se omite un estudio. Si los resultados de los distintos meta-análisis son similares, es decir, el efecto tiene una misma dirección, magnitud y significación estadística, se puede concluir que el resultado del meta-análisis tiene solidez. El análisis de sensibilidad también se puede utilizar para ver que ocurre cuando se eliminan estudios que no han sido
GRÁFICOS AVANZADOS
237
publicados, hay dudas sobre la calidad del estudio, etc. Las instrucciones están en el script III.34.R. Como ejemplo usaremos de nuevo los datos del archivo Meta-análisis.csv, que corresponden a un estudio de Silagy y Ketteridge (1997) sobre el efecto que tiene el consejo médico a la hora de dejar de fumar. La única función nueva es «metainf()» que permite realizar el análisis de sensibilidad. El argumento «pooled» permite especificar si se realiza el modelo de efectos fijos "fixed" o el aleatorio "random".
¾ ¾ ¾ ¾
library(meta) datos<-read.csv2("Meta-análisis.csv", header=TRUE, encoding="latin1") attach(datos) meta <- metabin(event.e=n.evento, n.e=N.evento, event.c=n.control, n.c= N.control, sm="OR", method="MH", studlab=paste(Estudio,Año), print.CMH= TRUE) ¾ meta1<-metainf(meta, pooled="random") ¾ forest.meta(meta1, text.random="Modelo de efectos aleatorios", comb.random=TRUE, leftlabs=c("Estudio"), pooled.totals=F, pooled.events=F, xlab="Razón de ventajas (OR)", fs.xlab=14,ff.xlab=2, col.square="red", col.diamond="blue") OR
95% -CI
Omitting Porter 1972 Omitting Rusell 1979 Omitting Wilson 1982 Omitting Stewart 1982 Omitting Rusell 1983 Omitting Jamrozik 1984 Omitting McDowell 1985 Omitting Page 1986 Omitting Janz 1987 Omitting Slama 1990 Omitting Vetter 1990 Omitting Demens 1990 Omitting Wilson 1990 Omitting Haug 1994 Omitting Higashi 1995 Omitting Slama 1995
1.78 1.62 1.75 1.79 1.86 1.82 1.81 1.80 1.76 1.77 1.77 1.72 1.71 1.75 1.79 1.70
[1.43; 2.22] [1.37; 1.93] [1.39; 2.19] [1.44; 2.23] [1.52; 2.28] [1.43; 2.31] [1.46; 2.25] [1.45; 2.23] [1.40; 2.21] [1.42; 2.21] [1.40; 2.23] [1.39; 2.14] [1.36; 2.13] [1.40; 2.19] [1.40; 2.27] [1.38; 2.09]
Modelo de efectos aleatorios
1.76 [1.42; 2.18]
Estudio
1
Razón de ventajas (OR)
III.23.5. DIAGRAMA DE META-ANÁLISIS ACUMULATIVO En esta representación se van añadiendo los estudios conforme fueron apareciendo, lo cual permite ver si existe solidez en la información y, si se llegó a un equilibrio en el resultado, cuando se alcanzó este equilibrio. Aunque el orden
238
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
cronológico es el método más usado a la hora de ir añadiendo estudios al metaanálisis, es posible usar cualquier otro orden. Las instrucciones están en el script III.35.R y, continuando con el estudio de Silagy y Ketteridge (1997) sobre el efecto que tiene el consejo médico a la hora de dejar de fumar, los datos están en el archivo Meta-análisis.csv. La única función nueva es «metacum()», en la cual de nuevo con el argumento «pooled» es posible especificar si se realiza el modelo de efectos fijos "fixed" o el aleatorio "random".
¾ ¾ ¾ ¾
library(meta) datos<-read.csv2("Meta-análisis.csv", header=TRUE, encoding="latin1") attach(datos) meta <- metabin(event.e=n.evento, n.e=N.evento, event.c=n.control, n.c=N.control, sm="OR", method="MH", studlab=paste(Estudio,Año), print.CMH=TRUE) ¾ meta1<-metacum(meta, pooled="random") ¾ forest.meta(meta1, xlab="Razón de ventajas", text.random ="Modelo de efectos aleatorios", fs.xlab=14, ff.xlab=2, col.square="red", col.diamond= "blue", leftlabs=c("Estudio")) Estudio
OR
95% -CI
Adding Porter 1972 (k=1) Adding Rusell 1979 (k=2) Adding Wilson 1982 (k=3) Adding Stewart 1982 (k=4) Adding Rusell 1983 (k=5) Adding Jamrozik 1984 (k=6) Adding McDowell 1985 (k=7) Adding Page 1986 (k=8) Adding Janz 1987 (k=9) Adding Slama 1990 (k=10) Adding Vetter 1990 (k=11) Adding Demens 1990 (k=12) Adding Wilson 1990 (k=13) Adding Haug 1994 (k=14) Adding Higashi 1995 (k=15) Adding Slama 1995 (k=16)
1.12 [0.29; 4.30] 2.56 [0.64; 10.22] 2.53 [1.19; 5.36] 2.07 [1.02; 4.19] 1.71 [0.91; 3.22] 1.65 [1.07; 2.54] 1.55 [1.05; 2.28] 1.49 [1.04; 2.14] 1.53 [1.11; 2.11] 1.52 [1.12; 2.07] 1.55 [1.19; 2.03] 1.62 [1.24; 2.11] 1.69 [1.32; 2.18] 1.71 [1.35; 2.17] 1.70 [1.38; 2.09] 1.76 [1.42; 2.18]
Modelo de efectos aleatorios
1.76 [1.42; 2.18]
0.75
1.5
Razón de ventajas El gráfico muestra que a partir del año 1990, los sucesivos estudios realizados no añadieron ninguna información, ya que el resultado del meta-análisis fue el mismo.
GRÁFICOS AVANZADOS
239
III.24. Gráficos de clasificación El objetivo de los métodos de clasificación es agrupar o clasificar a los elementos de una muestra de objetos descrito mediante variables, es decir, distribuirlos por categorías en función del parecido entre los elementos en base a las variables que se utilicen. Existen diferentes tipos que veremos a continuación.
III.24.1. CLASIFICACIÓN JERÁRQUICA (DENDROGRAMA) Es uno de los métodos más utilizados. Se obtiene una secuencia de particiones (clasificaciones) organizada jerárquicamente, desde una única clase que contiene a todos los elementos, hasta n clases, cada una de ellas con un solo elemento. La secuencia puede ser representada gráficamente mediante un árbol (dendrograma), que permite ver el proceso completo de clasificación desde su inicio con cada elemento en una clase hasta el final con una única clase en la que están todos los elementos de la muestra (Guisande y col., 2011). En el gráfico se ven todas las particiones o clasificaciones obtenidas y su relación jerárquica. Una función que se utiliza para realizar un dendrograma es «hclust()» y la función «identify()» que permite resaltar zonas dentro del dendrograma. Ambas funciones vienen con el paquete base. Las instrucciones están en el script III.36.R y usaremos los datos de pigmentos de algas que están en el archivo PigAlgas.csv. En la función «hclust()», el primer argumento sirve para definir los datos y el tipo de distancia ("euclidea", "manhattan", etc); con «method» se define el método de aglomeración que puede ser alguna de las siguientes opciones: "ward", "single", "complete", "average", "mcquitty", "median" o "centroid" (para más detalles de lo que significa cada método véase Guisande y col., 2011). Dentro de la función «plot()», con el argumento «hang» se puede definir si se recortan las ramas terminales. Por ejemplo, con «hang=-1» se eliminarían las últimas ramas del dendrograma. Con la función «polygon()» se resaltan los diferentes grupos de algas con un marco. En el supuesto de no querer usar «polygon()», con la función «identify()» es posible también resaltar una zona del dendrograma. Se coloca el ratón en la zona que se quiere resaltar y al pulsar el botón izquierdo del ratón se marca la zona. Con el botón derecho del ratón se puede parar la función. Los argumentos «N» y «MAXCLUSTER» son para definir el número máximo de clústeres que se quiere resaltar y el número máximo de clústeres a resaltar en sentido vertical, respectivamente.
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
datos<-read.csv2("PigAlgas.csv", header=TRUE, encoding="latin1") datos<-na.exclude(datos): attach(datos) hc<-hclust(dist(datos[,2:20], method="euclidea"), method="complete") plot(hc,label=datos[,1],hang=0.1, main="Pigmentos en algas", ylab="Altura",xlab="", sub="") polygon(x=c(0.6,0.6,6.4,6.4),y=c(-1.4,1.3,1.3,-1.4),border="brown") polygon(x=c(6.6,6.6,11.4,11.4),y=c(-1.4,0.5,0.5,-1.4),border="yellow") polygon(x=c(11.6,11.6,15.4,15.4),y=c(-1.4,0.5,0.5,-1.4),border="red") polygon(x=c(15.6,15.6,19.4,19.4),y=c(-1.4,0.2,0.2,-1.4),border="blue") polygon(x=c(19.6,19.6,27.4,27.4),y=c(-1.4,0.65,0.65,-1.4),border="green") identify(hc, N=20, MAXCLUSTER=20)
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
240
Diatomeas-P. t. Diatomeas-P. t. Diatomeas-S. c. Diatomeas-Ch. g. Diatomeas-Ch. g. Diatomeas-S. c. Dinofíceas-H. sp. Dinofíceas-A. m. Dinofíceas-P. m. Dinofíceas-P. m. Dinofíceas-H. sp. Criptofíceas-R. b. Criptofíceas-R. b. Criptofíceas-C. sp. Criptofíceas-C. sp. Cianofíceas-S. sp. Cianofíceas-S. sp. Cianofíceas-C. sp. Cianofíceas-C. sp. Clorofíceas-Ch. sp. Clorofíceas-Ch. sp. Clorofíceas-D. sp. Clorofíceas-D. sp. Clorofíceas-Ch. a. Clorofíceas-Ch. a. Clorofíceas-N. sp. Clorofíceas-N. sp.
0.5 0.0
Altura
1.0
1.5
2.0
2.5
Pigmentos en algas
Con las funciones «draw.dendrogram3d()» y «heatmap()» del paquete “NeatMap” (Rajaram y Oono, 2012) es posible realizar dendrogramas tridimensionales y “mapas de calor”, respectivamente. Las instrucciones están en el script III.37.R y se usarán de nuevo los datos morfométricos de peces del archivo Morfología.csv. En la primera parte del script se hacen las medias de todos los individuos a nivel de género con la función «aggregate()». Luego se seleccionan las variables que se van a usar para agrupar los casos, en este caso de la columna 4 a la 19 y se transforman los datos en una matriz con «as.matrix()», para posteriormente asignar etiquetas a las variables, con la función «rownames()», que permitan identificar los diferentes géneros de peces.
¾ ¾ ¾ ¾ ¾
library(NeatMap) datos<-read.csv2("Morfología.csv", header=TRUE, encoding="latin1") datos<-na.exclude(datos) attach(datos) datos1<-aggregate(datos[,5:31], na.rm=TRUE, by=list(Orden=Orden, Familia=Familia, Género=Género), mean) ¾ datos2<-as.matrix(datos1[,4:19]) ¾ rownames(datos2)<-datos1[,3]
GRÁFICOS AVANZADOS
241
Se puede hacer un dendrograma tridimensional con la función «draw.dendrogram3d()» del paquete “NeatMap” (Rajaram y Oono, 2012). Para ello obtenemos previamente coordenadas bidimensionales con la función «nMDS()». El argumento «embed.dim» define la dimensión del espacio euclideo en el que se pondrá el gráfico. Con «n.iters» se especifica el número de iteraciones. El argumento «metric» especifica el tipo de distancia, que puede ser "pearson" o "euclidean". Una vez generado el dendrograma tridimensional podemos cambiar su tamaño de modo interactivo utilizando la rueda del ratón, y girarlo convenientemente en el espacio tridimensional desplazando el ratón mientras mantenemos pulsado el botón izquierdo.
¾ hc.MDS<-nMDS(datos2, embed.dim = 3, n.iters = 300, metric="euclidean") ¾ hc.CLUSTER<-hclust(dist(datos2,method="euclidea"), method="complete") ¾ draw.dendrogram3d(hc.CLUSTER,hc.MDS$x,labels=rownames(datos2),lab el.size=0.5)
La función «heatmap()» del paquete “NeatMap” (Rajaram y Oono, 2012) construye un “mapa de calor”, que muestra con distintos colores y tonos la intensidad de la relación. Aplicado a una matriz de datos, con casos y variables (filas y columnas), clasifica ambos simultáneamente elaborando un dendrograma marginal para las filas y otro para las columnas, ordenados conjuntamente. Los colores indican la intensidad de la relación o los valores de la variable representada, desde el blanco (máxima relación o valor más alto), pasando por el amarillo y naranja hasta el rojo intenso (mínimo valor), aunque estos colores por defecto pueden ser modificados libremente por el usuario. El argumento «margin» es un vector con 2 números que especifica los márgenes que se dejan para las filas y las columnas.
¾ hv <- heatmap(datos2, margins=c(5,10), xlab ="Variables morfométricas", ylab= "GÉNEROS", main = "Morfometría de peces")
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
242
M11
M16
M8
M10
M6
M7
M9
M14
M15
M13
M4
M12
M2
M5
M17
M3
Aequidens Biotodoma Geophagus Chaetobranchus Diplodus Archosargus Tilapia Oreochromis Satanoperca Cichlasoma Astronotus Caquetaia Laetacara Apistogramma Pagellus Spondyliosoma Sarpa Cichla Cichla Sparus Pagrus Calamus Dentex Lithognathus Crenicichla Boops Sphyraena Charax Roeboides Moenkhausia Triportheus Bryconops Tetragonopterus Ctenobrycon Poptella Symphysodon Mesonauta
GÉNEROS
Morfometría de peces
Variables morfométricas
En el ejemplo se observan los valores que toman todas las variables para cada género de peces. Los valores en rojo son los más pequeños, y los de color blanco los más grandes. En la morfología de los peces las variables que menos influyen en la clasificación son M3, M5, M17, M2 y M4, que forman un grupo diferenciado en el dendrograma de la parte superior (de columnas). Este grupo de variables no permite distinguir las clases de peces, ya que toman valores bajos para todas ellas, y la zona de color rojo forma un único rectángulo en la parte izquierda del gráfico. La variable M14 distingue algunos grupos de peces, ya que las zonas de color homogéneo o similar se corresponden razonablemente con algunas clases identificadas en el dendrograma de la izquierda (de filas). Las variables M11 o M16 también parecen contribuir a distinguir diferentes grupos.
III.24.2. CLASIFICACIÓN DE K-MEDIAS Este método trata de encontrar la mejor partición posible del conjunto de objetos para un número dado de clases k (Guisande y col., 2011). Con este método –a diferencia de la clasificación jerárquica– es necesario establecer a priori el
GRÁFICOS AVANZADOS
243
número de clases que debe tener la solución buscada. Se suele utilizar a continuación del método jerárquico, sirviendo éste primero para decidir el número de clases que se desea obtener. Sin embargo se pueden obtener distintas clasificaciones, con distinto número de grupos, aplicando el método de forma repetida. El resultado puede depender en algunos casos de los centros iniciales elegidos, aunque en general la solución final es muy robusta frente a esta elección, y suele ser prácticamente independiente de los centros utilizados para iniciar el algoritmo. Es adecuado para clasificar conjuntos de elementos muy numerosos (por ejemplo con cientos de miles de objetos), con los cuales el método de clasificación jerárquica es inviable dadas las dificultades de cálculo. En este caso es mejor realizar el análisis con R Commander (Fox, 2005; 2007). Se usaran los datos de pigmentos que vimos anteriormente en el dendrograma, que están en el archivo PigAlgas.xls, para así poder comparar ambos métodos. Después de haber invocado al programa R y seleccionado el directorio cargamos el paquete “Rcmdr” con la instrucción library(Rcmdr).
A continuación se selecciona «Datos» Ö «Importar datos» Ö «desde conjunto de datos Excel, Access o dBase».
Aparece un pequeño cuadro de diálogo para introducir el nombre del conjunto de datos, en el que dejamos el nombre por defecto «Datos» y pulsamos
244
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
«Aceptar». Posteriormente aparecen los archivos del directorio de trabajo, en el que elegimos PigAlgas.xls y pulsamos «Abrir».
En R Commander pulsamos en «Visualizar conjunto de datos». Es importante inspeccionar los datos y comprobar que no existan líneas, lo cual a veces ocurre al final del archivo, que tengan celdas con el código . Si existen estas líneas, hay que eliminarlas.
Para aplicar el método de clasificación k-medias elegimos en el menú principal de R Commander las opciones «Estadísticos» Ö «Análisis dimensional» Ö «Análisis de agrupación» Ö «Agrupación por k-medias…».
En la ventana de agrupación por k-medias seleccionamos en primer lugar las variables que queremos utilizar, en este caso todos los pigmentos. Estableceremos el «Número de grupos:» (5), ya que estamos trabajando con los grupos de algas: Diatomeas, Clorofíceas, Dinofíceas, Cianofíceas y Criptofíceas. En general pondremos el número de grupos que esperamos encontrar. Se mantienen los valores por defecto en el resto de los parámetros: «Número de semillas iniciales» (10) e «Iteraciones máximas» (10). Dejaremos la marca en «Imprimir resumen
GRÁFICOS AVANZADOS
245
del grupo:» y «Gráfica doble de grupos», y marcamos «Asignar grupos al conjunto de datos».
Las semillas iniciales se utilizan para determinar los centros iniciales aleatoriamente. Cada una de las 10 utilizadas da origen a una clasificación diferente, lo que permite valorar la influencia que tiene esta elección de centros iniciales sobre el resultado final. En general el efecto es nulo, y la clasificación obtenida es la misma. El número máximo de 10 iteraciones generalmente no se alcanza, ya que antes de que eso ocurra suele repetirse la clasificación, con lo que finaliza el algoritmo. Si no se alcanza la convergencia, generalmente porque no existe una clasificación natural bien definida en la muestra, puede repetirse el método aumentando el número de iteraciones (por ejemplo 20). Entre los resultados que se obtienen es importante la suma total de cuadrados interna dentro de cada grupo (2,23) y la suma de cuadrados externa o entre grupos: 26,4. Estos dos últimos resultados, las sumas interna y externa se utilizan para evaluar la clasificación resultante. Cuanto más pequeña sea la suma interna comparada con la externa, mejor será el resultado, ya que la suma interna mide la dispersión o distancia entre los elementos del mismo grupo, y la externa mide la distancia entre grupos. Lo óptimo es un conjunto de grupos muy homogéneos y muy separados entre sí. El gráfico representa los elementos de los cinco grupos de algas, identificados con el número de grupo (1 a 5), conjuntamente con las variables –en este caso los pigmentos– en color rojo. La asignación de números a cada uno de los grupos es arbitraria. La ventaja de este método con respecto al dendrograma, es que permite ver cuales son las variables que tienen una mayor importancia en la formación de los grupos, en este caso Peridina, Clorofila c2, Luteina y Fucoxantina.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
246
-2
-1
0
1
2
3 3
-3 0.4
5 5 2
555 Peridin
1
0.2
Chlorophyll.c2
coxanthin 3 3
3 33
2 Diadinoxanthin 2 Alloxanthin Chlorophyll.a.epimer Methyl.chlorophyllide.a Chl.b.epir ß.u.carotene Chlorophyll.c1 Chlorophyll.a.alllomer Dinoxanthin 2 ß.e.carotene Violaxanthin ß.ß.carotene X9..cis.neoxanthin Zeaxanthin Chlorophyll.b
0
0.0
Comp.2
3
-1
4
-3
-0.4
-2
-0.2
11 Lutein 1 11
-0.4
-0.2
0.0
0.2
0.4
Comp.1
Es posible añadir al gráfico biplot etiquetas de caso, con el nombre del grupo de alga (o cualquier otra característica disponible en los datos). Para ello solo tenemos que modificar en la ventana de instrucciones de R Commander la orden:
¾ biplot(princomp(model.matrix(~-1 + Alloxanthin + Chl.b.epir + Chlorophyll.a.alllomer + Chlorophyll.a.epimer + Chlorophyll.b + Chlorophyll.c1 + Chlorophyll.c2 + Diadinoxanthin + Dinoxanthin + Fucoxanthin + Lutein + Methyl.chlorophyllide.a + Peridin + ß.e.carotene + ß.ß.carotene + ß.u.carotene + Violaxanthin + X9..cis.neoxanthin + Zeaxanthin, Datos)), xlabs = as.character(.cluster$cluster)) por
¾ biplot(princomp(model.matrix(~-1 + Alloxanthin + Chl.b.epir + Chlorophyll.a.alllomer + Chlorophyll.a.epimer + Chlorophyll.b + Chlorophyll.c1 + Chlorophyll.c2 + Diadinoxanthin + Dinoxanthin + Fucoxanthin + Lutein + Methyl.chlorophyllide.a + Peridin + ß.e.carotene + ß.ß.carotene + ß.u.carotene + Violaxanthin + X9..cis.neoxanthin + Zeaxanthin, Datos)), xlabs = Datos[,1]) que ejecutaremos seleccionando la instrucción corregida completa y pulsando después «Ejecutar».
GRÁFICOS AVANZADOS -2
-1
0
1
2
3 3
-3
247
0.4
Dinofíceas Dinofíceas 2
Dinofíceas Peridin Dinofíceas Dinofíceas
Diatomeas Criptofíceas Diadinoxanthin Criptofíceas Diatomeas Alloxanthin Chlorophyll.a.epimer Methyl.chlorophyllide.a Chl.b.epir ß.u.carotene Chlorophyll.c1 Chlorophyll.a.alllomer Dinoxanthin Criptofíceas coxanthin ß.e.carotene Violaxanthin ß.ß.carotene atomeas Diatomeas X9..cis.neoxanthin Zeaxanthin Diatomeas Diatomeas Chlorophyll.b
0
0.0
Comp.2
1
0.2
Chlorophyll.c2
-1
Cianofíceas
-3
-0.4
-2
-0.2
Clorofíceas Clorofíceas Lutein Clorofíceas Clorofíceas Clorofíceas
-0.4
-0.2
0.0
0.2
0.4
Comp.1
III.24.3. ÁRBOL DE CONSENSO Dado un conjunto de árboles, se puede obtener un “árbol de consenso”, o árbol medio, calculado como aquel que es más similar a todos los árboles del conjunto inicial, o que tiene una menor distancia a todos ellos. Este procedimiento se utiliza para resumir en un solo árbol diversas clasificaciones. Existen diferentes algoritmos y criterios de consenso. Como ejemplo se usarán los datos de presencia y ausencia de pigmentos en diferentes especies de algas fitoplanctónicas, que están en el archivo Consenso.csv. Las instrucciones están en el script III.38.R. La función «consensus()» del paquete “agricolae” (de Mendiburu, 2012) permite realizar árboles de consenso. A partir de un conjunto de datos realiza una clasificación jerárquica, con su correspondiente dendrograma, y a continuación repite el mismo proceso de clasificación para un número elevado de muestras aleatorias –por defecto 500– obtenidas a partir de la muestra inicial mediante remuestreo (bootstrap). Con todos los árboles construidos, la función determina finalmente el árbol de consenso, o árbol medio, y calcula la frecuencia relativa de los miembros de grupo, o porcentaje de casos asignados a la misma clase final a lo largo de todas las muestras aleatorias, que se puede interpretar como un indicador de la estabilidad o robustez de las clases obtenidas en el árbol de resumen: cuanto más próximos a 100 estén los valores, mejor es la clasificación obtenida. Es un requisito de la función que la matriz de datos tenga la columna de rownames. Por ello, en la primera parte del script se seleccionan las
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
248
variables, en este caso los pigmentos que van de la columna 3 a la 36. Luego se le añade una columna rowname con el grupo al que pertenece, en este caso la columna 1 de la matriz original. En la función «consensus()», con el argumento «distance» se define el tipo de distancia que se utiliza que puede ser: "euclidean", "maximum", "manhattan", "canberra", "binary", "minkowski" o "gower". En este caso como los datos son de presencia/ausencia se ha elegido "binary", pero en el caso de que no lo fueran habría que elegir otro tipo de distancia. Con el argumento «method» se elige el método de conglomeración a utilizar, que puede ser: "ward", "single", "complete", "average", "mcquitty", "median", "centroid", "ward", "single", "complete", "average", "mcquitty", "median" o "centroid". Las diferencias entre los distintos tipos de distancias y métodos se pueden consultar en Guisande y col. (2011). Con «nboot» se define el número de muestras bootstrap a utilizar; por defecto es 500, que es un número adecuado en la mayoría de las aplicaciones. Un valor más alto aumentará la precisión de las estimaciones, pero tardará más tiempo en ejecutarse. Con «duplicate=TRUE», si encuentra elementos repetidos utilizará la media de todos ellos y cuando es «duplicate=FALSE» utiliza todos los datos, sin controlar duplicados. Con «h» se define el tamaño de las ramas terminales.
¾ ¾ ¾ ¾ ¾ ¾
library(agricolae) datos<-read.csv2("Consenso.csv", header=TRUE, encoding="latin1") datos<-na.exclude(datos) datos1<-as.matrix(datos[,3:36]) rownames(datos1)<-datos[,1] output<-consensus(datos1, distance="binary", method="complete", nboot=100, duplicate=F, h=0.1, cex.text=0.9, col.text="red", main="Árbol consenso de algas en base a pigmentos", ylab="Altura", xlab="", sub="") Árbol consenso de algas en base a pigmentos
0.8
100
100
81
81
Dynophyceae
100100 Dynophyceae
Dynophyceae
Dynophyceae
Diatomeas
95 95 Dynophyceae
Diatomeas
100 Diatomeas
Diatomeas
Diatomeas
Diatomeas
Diatomeas
85 85 85 85 Diatomeas
Diatomeas
Diatomeas
Diatomeas
Diatomeas
Chlorophyceae
94 94 94
Dynophyceae
49 99
Chlorophyceae
Chlorophyceae
Chlorophyceae
38 Chlorophyceae
Chlorophyceae
Chlorophyceae
Chlorophyceae
57 57 Chlorophyceae
Prymnesiophycea
Prymnesiophycea
Prymnesiophycea
Prymnesiophycea
61100
71 Chlorophyceae
21
54 Prymnesiophycea
60
17
56 0.0
83
23
0.2
Altura
15
Dynophyceae
0.4
0.6
94
Los números rojos en cada nodo indican el porcentaje de elementos de cada clase que se mantienen en ella en las múltiples clasificaciones obtenidas por remuestreo. Se observan algunos porcentajes próximos al 100%, lo que indica una clasificación muy fiable. El porcentaje del primer nodo siempre es 100, ya que todos los elementos están en una sola clase para todas las muestras y, por
GRÁFICOS AVANZADOS
249
tanto, solamente deben interpretarse los siguientes nodos. La gran clase de la izquierda, que contiene a las clorofitas/primnesofitas (separándolas de las diatomeas/dinoflagelados) tiene también el 100%, aunque algunas de las diferentes clases que se forman posteriormente dentro de este grupo tienen porcentajes más bajos.
III.24.4. CARTS
ÁRBOLES
DE
CLASIFICACIÓN
Y
REGRESIÓN:
Los árboles de clasificación y regresión son un procedimiento no paramétrico de predicción de una variable dependiente sobre la base de un conjunto de variables independientes (Breiman y col., 1984). Su carácter no paramétrico hace que no requiera ninguna hipótesis relativa a la distribución de las variables dependientes e independientes, ni a la relación entre ellas y sus posibles interacciones. La variable dependiente puede ser categórica (Árboles de Clasificación), como por ejemplo diferentes especies, rechazo a un tratamiento, presencia/ausencia de un cáncer, etc. La variable dependiente también puede ser continua (Árboles de Regresión), como por ejemplo el índice de masa corporal, el azúcar en sangre, etc. En ambos casos, Árboles de Clasificación y de Regresión (CARTs), el objetivo es identificar las variables que mejor permiten identificar la variable dependiente. Por ejemplo, determinar cuales son las características clínicas, genéticas y/o ambientales que permiten predecir si una persona puede tener un determinado cáncer, o ser propenso a un infarto, etc. Amigo y col. (2007) aplicaron CARTs al índice de masa corporal (IMC) de niños y determinaron que la madre, el consumo de lípidos y las horas de televisión el domingo, eran las variables que mejor clasificaban a los niños en función de su IMC. Un análisis CARTs consiste generalmente en tres pasos: 1.
2.
Construcción del árbol. En el árbol, el nodo raíz representa a toda la población. Este nodo raíz se divide en dos subgrupos en base a la partición de una variable independiente o predictora. Los nodos hijos se dividen por medio de la partición de una variable, que puede ser la misma de antes o una nueva. El proceso se repite sucesivamente hasta que se cumpla alguna condición de parada. Las divisiones se seleccionan de modo que la “impureza” o heterogeneidad de los nodos hijos sea menor que la del nodo padre. La función de impureza o criterio de partición es una medida que permite determinar la calidad del nodo hijo, y decidir como se realiza la partición de un nodo en sus dos nodos hijos. Existen diferentes tipos de índices para cuantificar la impureza de las particiones (Breiman y col., 1984). Poda del árbol. El árbol que se ha construido generalmente está sobreajustado, es decir, contiene gran cantidad de niveles y no necesariamente una mayor complejidad significa una mejor clasificación. Imaginemos que estamos trabajando con diferentes especies y se quiere determinar cuales son las variables que permiten diferenciarlas mejor. El árbol puede seguir dividiéndose en nodos hasta que el último individuo sea clasificado, utilizando en cada paso un número mayor de variables y un modelo más complejo hasta alcanzar un porcentaje cero de individuos mal clasificados. Al aumentar la complejidad de un modelo siempre se obtiene un mejor ajuste, pero a veces simplemente recogemos peculiaridades muy específicas de los datos, que no lo hacen útil para describir el comportamiento de nuevos datos (datos de validación). La poda consiste
250
3.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R en, una vez construido el árbol, eliminar hacia atrás las particiones que no representen un aumento considerable de la capacidad de predicción total. Validación del árbol. Conforme se va podando se reduce la complejidad del árbol pero el número de individuos mal clasificados puede aumentar. El mejor árbol será aquel que tenga la proporción óptima entre la tasa de mala clasificación (cociente entre las observaciones mal clasificadas y el número total de observaciones) y la complejidad del árbol. La selección del mejor árbol se realiza por validación. El procedimiento consiste en separar una parte de la muestra, que no es utilizada para la construcción del árbol, sino únicamente para la predicción, midiendose en ella el porcentaje de acierto. También se suele utilizar un método de validación cruzada, que consiste en dividir la muestra en varios grupos excluyentes (normalmente 10 grupos) de aproximadamente igual tamaño, y hacer el árbol dejando cada vez un grupo fuera, que es utilizado para la predicción y medida del grado de acierto. El proceso se repite hasta usar todos los grupos y se selecciona finalmente el árbol con la menor tasa agregada de mala clasificación (media de los diez grupos).
Entre las diferentes funciones de R que permiten realizar CARTs usaremos «rpart()» del paquete “rpart” (Therneau y Atkinson, 2012) y la función «rpart.plot()» del paquete “rpart.plot” (Milborrow, 2012). El ejemplo utiliza datos demográficos del año 2010 de las 19 regiones o comunidades autónomas de España publicados por el Instituto Nacional de Estadística (www.ine.es), que están en el archivo Demografía.csv. El objetivo es determinar si es posible clasificar las diferentes regiones en función de las siguientes variables demográficas: nacimientos, mortalidad, mortalidad infantil (menores de 1 año), todas ellas por cada 1000 habitantes, y el número medio de hijos por madre, edad media de la madre cuando tiene su primer hijo, porcentaje medio de mujeres no casadas con hijos, número de nacimientos por cada 1000 defunciones y la esperanza de vida de hombres y mujeres. Las instrucciones están en el script III.39.R. En la función «rpart()» se pone la fórmula con la variable dependiente, en este caso las regiones, y las variables independientes o predictoras, que son todos los indicadores demográficos. Con «method» se define el método de partición; como la variable dependiente es categórica, pondremos "class". Se puede omitir el método, en cuyo caso la propia función decide el método más adecuado en función del tipo de variable dependiente. Con el argumento «control», y mediante la función «rpart.control()», se pueden modificar aspectos importantes del árbol. Con el argumento «minsplit» se especifica el número mínimo de observaciones que deben existir en un nodo para que se haga la partición, es decir, conforme sea más pequeño el árbol tendrá más nodos. Con «minbucket» se define el número mínimo de observaciones en un nodo terminal y, por tanto, al igual que el argumento anterior, conforme es más pequeño se profundiza más en el árbol, es decir, tiene más nodos y se hace más complejo. Con «cp» se controla la complejidad y permite ahorrar tiempo en el proceso de poda. Es la fracción (por defecto 0,01) en la que debe mejorar el indicador de ajuste para que continúe la construcción del árbol. Si la mejora es menor que cp el proceso se detiene. El usuario decide si quiere profundizar mucho y hacer el árbol muy complejo (cp pequeño), o tener un árbol más simple (cp más grande). Con «surrogatestyle» se controla el criterio para elegir la mejor variable suplente para la partición en cada nodo. Si es 0 se utiliza la variable con el mayor número de elementos clasificados correctamente, y si es 1 la que tiene el mayor porcentaje de elementos clasificados correctamente sobre el número de casos válidos
GRÁFICOS AVANZADOS
251
de esa variable; la primera opción penaliza a las variables que tienen valores perdidos. En la función «rpart.plot()» con el argumento «type» se selecciona el formato del gráfico, es decir, el modo en que sale la información de las variables seleccionadas en cada partición y las categorías predominantes en cada nodo. Con el argumento «extra» se puede mostrar información adicional en los nodos, como en este ejemplo, en el que le pedimos que muestre en cada nodo el número de casos clasificados correctamente frente al total. Con «varlen=0» se define que los textos de los nodos sean completos y no se corten. Con «ycompress=TRUE» se especifica que cuando se solapan las etiquetas se desplacen verticalmente para evitar este solapamiento.
¾ ¾ ¾ ¾ ¾
library(rpart) library(rpart.plot) datos<-read.csv2("Demografía.csv", header=TRUE, encoding="latin1") attach(datos) CART
Esperanza.de.vida.Mujeres<84
Hijos.Madre<1.6
Edad.Madre<31
no
Nacidos.Muertos<1095
Ceuta Esperanza.de.vida.Mujeres>=86 1/2
Andalucía Comunidad Valenciana 8/8 1/2
Castilla y León 8/9
Hijos.Madre>=1.2
Hijos.Madre>=1.3
Aragón 2/2
Galicia 4/5
Hijos.Madre<1.3
Castilla-La Mancha 1/3
Cantabria 1/2
Porcentaje.no.Casadas<32
Edad.Madre<31
Castilla-La Mancha 4/5
La Rioja 1/2
Hijos.Madre>=1.5
Cataluña 4/5
Hijos.Madre<1.2
Islas Canarias 2/2
Edad.Madre<32
Comunidad Valenciana País Vasco 1/3 2/2
Los números indican las provincias que han sido clasificadas correctamente y el número total de provincias de cada región. Por ejemplo, en el grupo que pone Castilla y León, hay 8 provincias de esta región de un total de 9 que hay en ese grupo. En general se observa que muchas regiones se identifican bien. Por ejemplo, en Andalucía, Islas canarias, Aragón y País Vasco, todas las provincias de la región están dentro de un mismo grupo. En Castilla y León, Galicia, Castilla La Mancha y Cataluña, casi todas las provincias están en el mismo grupo. Esto quiere decir que hay diferencias demográficas entre regiones en España, ya que es posible identificar relativamente bien cada una de las regiones en base a estos indicadores demográficos.
252
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
La primera variable es la esperanza de vida de las mujeres, que separa un grupo de regiones con mujeres que tienen una esperanza de vida menor o igual a 84 años a la izquierda y mayor de 84 a la derecha. El número medio de hijos por madre y la edad de la madre cuando tiene el primer hijo también son variables importantes ya que aparecen en muchos nodos. El número de nacidos por cada 1000 defunciones también es una variable importante indicando que las regiones crecen a ritmos diferentes. En el árbol se ha optado por no identificar de forma correcta todos los casos, es decir, hay grupos terminales donde hay casos de diferentes categorías, para no hacer el árbol muy complejo. Lo importante en este ejemplo era ver si los indicadores demográficos diferencian a las regiones, y cuales de estos indicadores son los más importantes para ello.
Función rpart.control (paquete rpart) minsplit: número mínimo de observaciones que deben existir en un nodo para que se haga la partición: minsplit = 20. minbucket: número mínimo de observaciones en un nodo terminal: minbucket = round(minsplit/3). cp: parámetro de complejidad, o fracción en la que debe mejorar el indicador de ajuste para que continúe la construcción del árbol. Si la mejora es menor que cp el proceso se detiene. El usuario decide si quiere profundizar mucho y hacer el árbol muy complejo (cp pequeño), o tener un árbol más simple (cp más grande): cp = 0.01. maxcompete: indica el número de variables que se guardan de las que no se eligieron, es decir, además de conocer la variable elegida para la partición del nodo, también es útil conocer la variable que se eligió en la posición segunda, tercera, etc.: maxcompete = 4. maxsurrogate: número de variables alternativas o suplentes (y divisiones) que se conservan con los resultados; por defecto es 5. Si es cero se ahorra tiempo de cálculo, ya que aproximadamente la mitad del tiempo se emplea en buscar divisiones alternativas: maxsurrogate = 5. usesurrogate: algunos casos pueden tener un valor perdido en la variable elegida para la partición en un nodo determinado. La función puede utilizar variables suplentes (surrogates) para resolver esos casos, para lo cual debemos poner el valor 1 o 2. Si el valor es 1 utiliza suplentes, si es 2 el caso es asignado al grupo mayoritario cuando todas las variables suplentes tienen también valor perdido, y si es 0 no utiliza variables suplentes (el caso se pierde), solo las muestra: usesurrogate = 2. xval: número de validaciones cruzadas: xval = 10. surrogatestyle: controla el mecanismo para elegir las variables suplentes. Si es 0 se utiliza la variable con el mayor número de elementos clasificados correctamente, y si es 1 la que tiene el mayor porcentaje de elementos clasificados correctamente sobre el número de casos válidos de esa variable: surrogatestyle = 0. maxdepth: define la profundidad del árbol, es decir, el número máximo de niveles que se generan considerando el nodo raíz como nivel cero: maxdepth = 30.
GRÁFICOS AVANZADOS
253
Función rpart (paquete rpart) formula: variable dependiente y variables independientes con el formato variable dependiente ~ variable independiente 1+variable independiente 2+…. data: opcionalmente se puede poner el data frame para interpretar los nombres de las variables. weights: opcionalmente se puede incluir una variable con pesos o ponderaciones para los casos. subset: permite realizar una selección de los datos. na.action: especifica qué hacer con los valores perdidos. Por defecto elimina todos los casos con valores perdidos de la variable dependiente, pero mantiene aquellos en los que uno o más predictores faltan: na.action = na.rpart. method: se define el método de partición que puede ser: "anova", "poisson", "class" o "exp". Si el método no se especifica, la rutina trata de hacer una suposición inteligente. Si la variable independiente es del tipo supervivencia, entonces es "exp", si tiene 2 columnas el método es "poisson", si es un factor entonces es "class", y en otras situaciones es "anova" model: si es TRUE se guarda una copia del modelo en los resultados: model = FALSE. x: si es TRUE se guarda una copia de las variables independientes en los resultados: x = FALSE. y: si es TRUE se guarda una copia de la variable dependiente en los resultados: y = FALSE. control: lista de opciones que controla el proceso de partición. cost: vector de costes no negativos para todas las variables independientes, que se puede añadir opcionalmente. La mejora en la división se divide por el coste de la variable para decidir qué variable se utiliza, de forma que una variable con coste doble que otra necesita una mejora doble para ser elegida. Por defecto es 1 para todas las variables. parms: parámetros opcionales para la función de partición. En el caso del análisis de varianza no hay parámetros. La partición por Poisson tiene un solo parámetro, el coeficiente de variación de la distribución a priori de las tasas, cuyo valor por defecto es 1. La partición exponencial tiene el mismo parámetro de Poisson. Para la partición por clasificación, la lista puede contener cualquiera de las siguientes opciones: el vector de probabilidades a priori (prior), la matriz de pérdidas (loss) o el índice de la división (split). Las probabilidades a priori deben ser positivas y sumar 1 (por defecto las frecuencias relativas). La matriz de pérdida debe tener ceros en la diagonal y valores positivos fuera de la diagonal (por defecto 1). El índice de partición puede ser "gini", que es el que se usa por defecto, o "information".
254
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Función rpart.plot (paquete rpart) x: salida de la función rpart(). type: formato del gráfico: 0 muestra las variables que han sido seleccionadas en cada partición y al final las categorías predominantes en los nodos terminales, 1 es igual que la anterior pero además muestra la categoría predominante en cada partición, 2 igual que 1 pero pone encima el nodo y debajo la variable responsable de la partición, 3 la variable responsable de la partición se pone en ambas ramas y, por último, 4 es igual que 3 pero se etiquetan los nodos, no las ramas: type = 0. extra: permite mostrar información adicional en los nodos: 0 solamente muestra el grupo mayoritario en el nodo, 1 muestra el número de casos de todas las categorías, 2 muestra el número de casos correctos frente al total, 3 muestra el número de casos incorrectos frente al total, 4 muestra la probabilidad de todas las categorías, 5 es igual que 4 pero no muestra la categoría que predomina en el nodo, 6 muestra la probabilidad de la segunda clase que predomina en el nodo, 7 es igual que 6 pero no muestra la categoría que predomina en el nodo, 8 muestra la probabilidad de la clase que predomina en el nodo y, por último, 9 muestra la probabilidad relativa considerando todas las observaciones: extra = 0. under: solamente se aplica si type > 0. Si es TRUE la información extra de los nodos se pone fuera y no dentro del nodo: under = FALSE. clip.right.labs: solamente se aplica si type es 3 ó 4. Si es TRUE solamente se pone la variable en la rama izquierda y no en la derecha: clip.right.labs = TRUE. fallen.leaves: si es TRUE se ponen todos los nodos al fondo del árbol, tipo dendrograma: fallen.leaves = FALSE. branch: controla la forma de las ramas: 0 las ramas son en forma de V y 1 son rectas: branch = if(fallen.leaves) 1 else .2. uniform: si es TRUE la separación vertical entre nodos es uniforme: uniform = TRUE. digits: número de decimales: digits = 2. varlen: define el número de caracteres de los textos: 0 utiliza el texto completo, >0 los abrevia teniendo en cuenta el número que se indique, y <0 recorta el texto de las variables teniendo en cuenta el número que se indique al máximo posible para ajustar el tamaño: varlen = -8. cex: si es NULL calcula el tamaño de los textos automáticamente, aunque se puede especificar un valor: cex = NULL. tweak: es un factor de escala para aumentar el tamaño de los textos: tweak = 1. compress: si es TRUE deja el máximo espacio posible horizontalmente entre nodos, lo cual permite que los texto sean de mayor tamaño: compress = TRUE. ycompress: si es TRUE, cuando se solapan los nodos se desplazan verticalmente para evitar este solapamiento: ycompress = FALSE. snip: si es TRUE se activa el ratón y permite podar el árbol pulsando sobre cualquier nodo. Para finalizar se pulsa el botón derecho y se selecciona «Parar»: snip = FALSE.
GRÁFICOS AVANZADOS
255
III.24.5. ÁRBOLES DE CLASIFICACIÓN Y REGRESIÓN (CARTS) Y ANÁLISIS DE COMPONENTES PRINCIPALES La función «mvpart()» del paquete “mvpart” (Therneau y Atkinson, 2012b) construye árboles de regresión (MRT, multivariate regression trees). Los datos de la variable respuesta deben tener formato de matriz (clase matrix) y las variables explicativas formato de data frame. En la función, la relación entre unas y otras se escribe del mismo modo que en los modelos de regresión. Aplicaremos este método al conjunto de datos spider que vienen con el paquete “mvpart”. Las doce primeras variables del conjunto de datos son las abundancias de 12 especies de arañas en 25 lugares, y las seis siguientes son variables explicativas de entorno (hierbas, musgo, arena, etc.). Se trata de encontrar una relación entre la distribución de las arañas y las variables ambientales. Las instrucciones están en el script III.40.R. El método realiza una clasificación de los lugares en grupos, de acuerdo con la estructura de los valores de las variables dependientes (abundancia de las distintas especies de arañas), utilizando las variables explicativas definidas en la fórmula al aplicar la función «mvpart()».
¾ library(mvpart) ¾ data(spider) ¾ mvpart(data.matrix(spider[,1:12]) ~ herbs + reft + moss + sand + twigs + water, data= spider) arct.lute pard.lugu zora.spin pard.nigr pard.pull aulo.albi troc.terr alop.cune pard.mont alop.acce alop.fabr arct.peri
moss>=1.5
reft>=6.5
moss< 1.5
reft< 6.5
twigs>=1.5
185 : n=7 373 : n=12
twigs< 1.5
13 : n=2
237 : n=7 Error : 0.569 CV Error : 0.718 SE : 0.156
Cada división en el árbol muestra la variable explicativa relevante y su valor de corte. La primera división corresponde a «moss» menor que 1,5; la segunda variable utilizada es «reft» y la tercera «twigs». Se forman claramente cuatro clases o entornos distintos. Cada rama terminal del árbol tiene un diagrama de barras asociado, indicando también el número de elementos (filas o lugares) de cada clase. Esta orden de R utiliza tres colores (tres tonos de azul) que se repi-
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
256
ten cíclicamente para las barras del diagrama, lo que hace algo confusa la interpretación (hubiera sido preferible utilizar colores distintos para cada barra). Las barras muestran las frecuencias de las especies (el valor de las variables o columnas) en cada uno de los grupos o clases, y las clases definen, en este ejemplo, ambientes o entornos distintos. El diagrama de barras ayuda a establecer el perfil de cada entorno. Se indica también el error residual del árbol, es decir, la variabilidad no explicada por la clasificación, el error de validación cruzada y el error típico o medio de ese tamaño de árbol. En la siguiente instrucción se introduce el argumento «xv="pick"», que permite obtener un gráfico con el error relativo y seleccionar sobre ese gráfico el número de ramas que se desea tener en el árbol.
¾ mvpart(data.matrix(spider[,1:12])~ herbs + reft + moss + sand + twigs + water, data= spider, xv="pick") Size of tree 4
6
9
10
0.038
0.028
0.016
0.8 0.6
Min + 1 SE
0.4
X-val Relative Error
1.0
1.2
1
Inf
0.08
cp El gráfico anterior muestra el error relativo (puntos y líneas verdes), siempre decreciente a medida que aumenta la complejidad del árbol, y el error relativo mediante validación cruzada (color azul), junto con las barras que indican inter-
GRÁFICOS AVANZADOS
257
valos de confianza. Aparecen destacados el valor mínimo del error con validación cruzada (punto grueso rojo) y el mínimo en el margen de una desviación típica (punto grueso naranja), que penaliza la complejidad del árbol y constituye generalmente la mejor opción, en este caso el árbol con cuatro ramas del diagrama anterior. Con el ratón se selecciona el punto grueso naranja, que indica un árbol con 4 nodos, que es el mismo que se mostró anteriormente y selecciona la función de forma automática. Dado que se utiliza un procedimiento de estimación basado en la simulación de un número elevado de muestras, el resultado puede ser distinto en cada aplicación. En la siguiente instrucción se introduce el argumento «pca=TRUE» para que, además del árbol, se represente también el Análisis de Componentes Principales (PCA).
¾ fit <- mvpart(data.matrix(spider[,1:12])~ herbs + reft + moss + sand + twigs + water, data= spider, pca=TRUE) arct.lute pard.lugu zora.spin pard.nigr pard.pull aulo.albi troc.terr alop.cune pard.mont alop.acce alop.fabr arct.peri
moss>=1.5
reft>=6.5
moss< 1.5
reft< 6.5
twigs>=1.5
185 : n=7 373 : n=12
twigs< 1.5
13 : n=2
237 : n=7 Error : 0.569 CV Error : 1.05 SE : 0.216
El gráfico anterior muestra de nuevo el árbol pero cada grupo lo identifica con un círculo de un color diferente, lo cual permitirá localizar cada uno de estos grupos en el PCA. Para que salga el segundo gráfico con el PCA es necesario pulsar con el ratón sobre el gráfico. En este gráfico biplot se observan las dos primeras componentes principales, mediante un código de colores para cada grupo o clase en el árbol del diagrama (punto grueso). Se representan las puntuaciones de las dos primeras componentes principales para cada lugar, y se puede observar cada clase mediante un polígono cerrado con el color correspondiente. Podemos interpretar la mayor o menor separación de las clases entre sí y su variabilidad interna. Un punto más grueso identifica el punto medio de cada clase, y estos puntos medios están unidos por trazos negros que reproducen el árbol de clasificación. Además se representan como vectores las variables dependientes o de frecuencia, de modo que es posible conocer a través del gráfico cuales son las especies predominantes en cada grupo: pard.mont y alop.acce en la clase roja; pard.nigr y pard.pull en la clase azul claro; troc.terr en la clase verde y en la clase azul oscuro.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
258
pard.mont
alop.acce pard.nigr pard.pull
alop.fabr arct.peri arct.lute
aulo.albi
alop.cune
Dim 2 21.26 % : [ 0.673 ]
zora.spin
troc.terr
pard.lugu Dim 1 77.04 % : [ 0.759 ]
En la última instrucción se utiliza la función «rpart.pca()», en la cual con el argumento «interact=TRUE» se puede representar el PCA para cada par de componentes principales. Para ello solamente es necesario pulsar sucesivamente el botón izquierdo del ratón para obtener de forma secuencial los pares de componentes aunque, en general, solamente suele tener interés práctico el primer par. Para detener la secuencia se pulsa el botón derecho del ratón
¾ rpart.pca(fit, interact=TRUE, wgt.ave=TRUE)
Dim 3 1.7 % : [ 0.57 ]
zora.spin aulo.albi alop.fabr pard.mont alop.cune pard.lugu arct.peri alop.acce pard.pull troc.terr pard.nigr arct.lute
Dim 1 77.04 % : [ 0.759 ]
GRÁFICOS AVANZADOS
259
Función mvpart (paquete mvpart) form: variables respuesta con formato matriz y las variables explicativas con formato de data frame. data: opcionalmente se puede indicar la base de datos. minauto: si es TRUE selecciona de forma automática el número mínimo de casos que debe existir en un nodo para que se realice la partición y el número mínimo de casos de los nodos terminales: minauto = TRUE. size: tamaño del árbol. xv: se define como se selecciona el árbol por validación cruzada: con "1se" se elige el mejor árbol dentro del margen de una desviación típica del óptimo global, con "min" se elige el árbol óptimo, con "pick" al pulsar con el ratón se elige el número de ramas y con "none" no se realiza validación cruzada: xv = "1se". xval: número de validaciones cruzadas o vector con las validaciones cruzadas de cada grupo: xval = 10. xvmult: número de validaciones cruzadas múltiples: xvmult = 0. xvse: multiplicador del número de SEs usados cuando se selecciona xv = "1se": xvse = 1. snip: si es TRUE se realiza una poda interactiva del árbol: snip = FALSE. plot.add: si es TRUE se representa el árbol y, adicionalmente, también se puede añadir texto: plot.add = TRUE. text.add: si es TRUE se añade al árbol la salida de la función text.rpart: text.add = TRUE. digits: número de dígitos de las etiquetas: digits = 3. margin: si por ejemplo se pone un margen de 0.1, hay un espacio extra de un 10% alrededor del gráfico: margin = 0. uniform: si es TRUE la longitud de las ramas del árbol es uniforme: uniform = FALSE. which: especifica donde ubicar las leyendas de los nodos: centrado (1), izquierda (2), derecha (3) y ambos lados (4): which = 4. use.n: si es TRUE se muestra el número de casos: use.n = TRUE. all.leaves: si es TRUE se añade la información en todos los nodos: all.leaves = FALSE. bars: si es TRUE se añaden los gráficos de barras: bars = TRUE. legend: si es TRUE se muestra la leyenda: legend=TRUE. bord: si es TRUE se muestra un marco alrededor de los gráficos de barras: bord = FALSE. xadj, yadj: ajusta el tamaño de los gráficos de barras: xadj = 1 y yadj = 1. prn: si es TRUE se muestran detalles del árbol: prn = FALSE. branch: ramas verticales (1) o inclinadas (0), en el árbol: branch = 1. rsq: si es TRUE se muestra un gráfico con información del error y r2 de las particiones: rsq = FALSE. pca: si es TRUE se muestra el PCA: pca = FALSE. interact.pca: si es TRUE el PCA es interactivo: interact.pca = FALSE. keep.y: si es TRUE se muestra los valores del eje y: keep.y = TRUE.
260
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
III.24.6. ÁRBOLES DE INFERENCIA Los árboles de inferencia condicional constituyen un método de clasificación que trata de evitar los problemas asociados a los métodos no probabilísticos (árboles de clasificación y regresión: CARTs) descritos con anterioridad, en especial el problema de sobreajuste y el sesgo de selección de variables hacia aquellas que presentan más opciones de corte. Para ello se introduce un enfoque estadístico que permite utilizar la distribución de probabilidad de las medidas, y establecer de este modo la significación estadística de las mejoras obtenidas en cada paso del algoritmo. La función «ctree()» del paquete “party” (Hothorn y col., 2004; 2006a; 2006b; Strobl y col., 2007; Hothorn y col., 2012) construye árboles de inferencia condicional. En la función se indica como argumento una fórmula que relaciona una variable dependiente (o más de una) con una o más variables explicativas. El método utilizado consiste en comprobar primero si la variable dependiente está relacionada con las explicativas, para lo que se aplica un test de independencia. Si detecta dependencia, selecciona la variable explicativa con mayor asociación a la respuesta, medida con el valor p de un test para cada variable explicativa, y a continuación realiza una clasificación binaria con esa variable, repitiendo de forma recursiva los pasos anteriores para formar clases en las que los valores de la variable dependiente sean distintos. Vamos a ver diferentes ejemplos en los que se usarán modelos de regresión lineal, regresión ordinal, clasificación de categorías y análisis de supervivencia. Como ejemplo de modelos de regresión lineal usaremos los datos de clorofila, afloramiento, temperatura y nutrientes de diferentes zonas costeras del mundo, los cuales están en el archivo Producción primaria.csv. El objetivo es determinar si algunas de las variables estudiadas explican las diferencias observadas en producción primaria, cuantificada en términos de mg de clorofila m-3, entre las diferentes áreas. Las instrucciones están en el script III.41.R. Después de cargar el paquete e importar los datos, se seleccionan todos los casos en los cuales hay datos de clorofila. Posteriormente se realiza el árbol de inferencia con la función «ctree()», empleando la clorofila como variable dependiente. El segundo gráfico muestra la versatilidad de las funciones de paneles que se explican en el último cuadro de este apartado. Los nodos intermedios se pueden modificar con el argumento «inner_panel» y los nodos terminales con «terminal_panel». Tanto los nodos intermedios como los terminales pueden tener diferentes formatos dependiendo del tipo de variable dependiente, como por ejemplo diagramas de cajas «node_boxplot», histogramas «node_hist», curvas de densidad «node_density», etc. Sin embargo, es importante tener en cuenta que debe existir una concordancia entre el tipo de datos y el formato de gráfico que se elija. Por ejemplo, en este caso para los nodos terminales se ha escogido el diagrama de cajas, que es la opción que de forma automatizada elige la función por el tipo de datos, pero si se prueba con otros formatos se observará que a veces da un error de concordancia, porque no es capaz de ajustar los datos a otros formatos de gráfico. Por último, al final del script se crea una tabla, que muestra la media estimada de la variable dependiente (si fuese una variable cualitativa o de clasificación mostraría el nivel o la clase más probable) para cada área.
¾ library(party) ¾ datos<-read.csv2("Producción primaria.csv", header=TRUE, encoding= "latin1")
GRÁFICOS AVANZADOS
261
¾ ¾ ¾ ¾ ¾
datos1<-subset(datos, !is.na(Clorofila)) attach(datos1) prod <- ctree(Clorofila ~ ., data = datos1) plot(prod) plot(prod,inner_panel=node_inner(prod, fill="cyan", id=F), terminal_panel= node_boxplot(prod,col = "black", fill="red",id=T)) ¾ table(predict(prod), Area) La interpretación del gráfico es similar a la de otros árboles de clasificación vistos con anterioridad. Se observa la formación de clases, que con este método se realiza buscando la mayor significación estadística en cada paso. La variable más relevante es silicato, con valor de corte 8,31. En el segundo paso la variable más significativa vuelve a ser silicato, ahora con valor de corte 6,89, y el proceso de clasificación finaliza: No hay más variables con relación significativa con la variable dependiente clorofila. En los nodos finales se muestra el número de casos de cada grupo, y un diagrama de cajas, que permite apreciar (diferente altura y escaso solapamiento de las cajas) como la variable dependiente, clorofila, tiene valores distintos en cada clase: pequeños en la primera (entre 0 y 1), grandes en la tercera (entre 2 y 4), con otra clase intermedia. 1 Silicato
<= 8.31
> 8.31
2 Silicato
<= 6.89
> 6.89
Node 3 (n = 15)
Node 4 (n = 10)
Node 5 (n = 11)
4
4
4
3
3
3
2
2
2
1
1
1
0
0
0
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
262
Silicato
<= 8.31
> 8.31
Silicato
<= 6.89
> 6.89
n = 15
n = 10
n = 11
4
4
4
3
3
3
2
2
2
1
1
1
0
0
0
La tabla de resultados muestra en cada fila el valor estimado para la variable dependiente en cada rama final del árbol, y la distribución de frecuencias en cada área. La clase 1, con valores bajos de clorofila, corresponde mayoritariamente a Mauritania (zona en la que solo hay elementos de la clase 1); la clase 3, con valores altos de clorofila, se relaciona con las áreas Benguela y Humboldt; ningún elemento de esta clase tercera está en el área de California ni de Mauritania. Por el árbol sabemos además que en la tercera clase los silicatos superan el valor 8,31.
Como ejemplo de supervivencia usaremos los datos de un experimento con el cladócero Daphnia sp., cuyos datos están en el archivo DaphniaSurv.csv. El objetivo es determinar si el tipo de alimentación, el tipo de alimento y la con-
GRÁFICOS AVANZADOS
263
centración de alimento explican las diferencias observadas en la supervivencia de esta especie en el tiempo. Las instrucciones están en el script III.42.R. La función «Surv()» del paquete “survival”, crea un objeto de supervivencia que puede ser utilizado para construir tablas o curvas de supervivencia mediante el modelo de riesgos proporcionales (regresión de Cox, método de Kaplan-Meier, etc.). La función «ctree()», admite en su fórmula estos objetos de supervivencia como dependientes de un conjunto de variables, realizando el árbol de clasificación con el procedimiento indicado anteriormente. En el gráfico se muestra el proceso, y en los nodos terminales se representa la curva de supervivencia para cada clase resultante. La división en clases comienza con la variable Trat (tipo de alimento), con dos niveles, y en segundo lugar Conc (concentración de alimento), también con dos niveles, dando lugar finalmente a cuatro clases.
¾ ¾ ¾ ¾ ¾ ¾ ¾
library(party) library(survival) datos<-read.csv2("DaphniaSurv.csv",header=TRUE,encoding="latin1") datos1<-subset(datos, !is.na(Time)) attach(datos1) surv<-ctree(Surv(Time, Status) ~ .,data = datos1) plot(surv)
El gráfico de supervivencia indica esperanzas de vida crecientes de izquierda a derecha, con mayor duración de vida para el tipo de alimento con el alga Scenedesmus frente al alimento sin Scenedesmus, y baja concentración frente a alta concentración. Con alimento sin Scenedesmus y alta concentración, la supervivencia es prácticamente nula a las 100 horas, y con el alga Scenedesmus y baja concentración la supervivencia es del 80% al cabo de 360 horas. 1 Trat p < 0.001
NoScen
Scen
2 Conc p = 0.029
5 Conc p < 0.001
H Node 3 (n = 39)
1
L
H Node 4 (n = 40)
1
Node 6 (n = 37)
1
L
0.8
0.8
0.8
0.8
0.6
0.6
0.6
0.6
0.4
0.4
0.4
0.4
0.2
0.2
0.2
0.2
0
0 0
50 100 150 200 250 300 350
0 0
50 100 150 200 250 300 350
Node 7 (n = 36)
1
0 0
50 100 150 200 250 300 350
0
50 100 150 200 250 300 350
264
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Como ejemplo de clasificación de categorías usaremos los datos de morfometría que están en el archivo Morfología.csv. El objetivo es determinar si es posible distinguir las familias de peces en base a las variables morfométricas. Las instrucciones están en el script III.43.R. Después de cargar los paquetes, se seleccionan solamente las variables morfométricas con las que se va a trabajar para realizar el árbol de inferencia, de la 5 a la 31. El paquete “grDevices”, el cual viene por defecto cuando se instala R, permite utilizar los colores de forma más cómoda, en concreto se usa «rainbow(4)» para rellenar con los colores del arco iris las barras de los gráficos terminales. El número 4 es debido a que hay cuatro familias de peces en los datos. El paquete ““vcd” (Meyer y col., 2012) se utiliza para poner una leyenda con la función «grid_legend()». Esta leyenda es necesaria porque los nombres de las familias se solapan con las etiquetas del eje x, en los gráficos terminales de barras. Con el paquete “partykit” (Hothorn, 2012) es posible usar «gp=gpar()», donde se puede modificar el tipo y estilo del texto. En concreto se usa «fontsize=0» para que no pongan las etiquetas de las familias en el eje x. Otra opción sería usar «fontsize=12» y luego recortar el marco de la figura una vez pegado en cualquier otro programa, para así eliminar las etiquetas de las familias en el eje x y no borrar las etiquetas con las frecuencias en el eje y. Esta última opción es la que se muestra a continuación en el gráfico.
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
library(party) library(grDevices) library(vcd) library(partykit) datos<-read.csv2("Morfología.csv",header=TRUE,encoding="latin1") datos1<-subset(datos, !is.na(Familia)) attach(datos1) datos2<-datos1[,5:31] fam <- ctree(Familia ~ ., data = datos2) plot(fam,inner_panel=node_inner(fam, fill="cyan", id=F), terminal_panel= node_barplot(fam, fill=rainbow(4),ylines=1.5, gp=gpar(fontsize=12), id=F)) ¾ grid_legend(0.9, 0.85, pch=rep(15,4), col = rainbow(4), frame = FALSE, c("Characidae", "Cichlidae", "Sparidae","Sphyraenidae"), title = "Familias", hgap=10,vgap=0.5, gp=gpar(fontface=1, fontsize=18)) La tabla de predicciones muestra que prácticamente todos los individuos se clasifican correctamente. Solamente un individuo de la familia Cichlidae es identificado erróneamente como Sparidae y, por lo tanto, es posible predecir con casi un 100% de acierto (99,9%) a que familia pertenece cada individuo a partir de sus características morfológicas.
GRÁFICOS AVANZADOS
265
El gráfico muestra que la variable M12 es muy importante, ya que permite diferenciar las familias Characidae (valores menores de 0,2227) y Sphriraenidae (valores entre 0,2227 y 0,3832). Las especies de las familias Sparidae y Cichlidae no tienen ninguna variable que las diferencie de forma clara y, por ello, para clasificar de forma correcta a casi todos los individuos es necesario emplear varias variables. M12
<= 0.2227
Familias Characidae Cichlidae Sparidae Sphyraenidae
> 0.2227
M12
<= 0.3832
> 0.3832
M24
<= 0.1776
> 0.1776
M25
<= 0.2124
M18
> 0.2124
M24
<= 0.0661 n = 335
n = 65
> 0.0661
n=7
<= 0.1079
M22
<= 0.1607
n = 29
> 0.1607
n=7
> 0.1079
M20
<= 0.2126
n = 345
> 0.2126
n = 16
n = 11
n = 198
1
1
1
1
1
1
1
1
1
0.8
0.8
0.8
0.8
0.8
0.8
0.8
0.8
0.8
0.6
0.6
0.6
0.6
0.6
0.6
0.6
0.6
0.6
0.4
0.4
0.4
0.4
0.4
0.4
0.4
0.4
0.4
0.2
0.2
0.2
0.2
0.2
0.2
0.2
0.2
0.2
0
0
0
0
0
0
0
0
0
La función «mob()» del paquete “party” (Hothorn y col., 2004; 2006a; 2006b; Strobl y col., 2007; Hothorn y col., 2012) construye un árbol de inferencia para una variable dependiente que es un modelo lineal, como el descrito en el párrafo anterior, con respecto a un conjunto de variables independientes o explicativas, en nuestro ejemplo todas las no utilizadas en el modelo lineal. Es decir, el resultado del árbol es una clasificación jerárquica que tiene, en los nodos terminales, un modelo ajustado a las condiciones particulares de cada clase, definidas por los valores de las variables explicativas significativas. Como ejemplo usaremos el archivo Bostonhousing que tiene datos de un censo de población realizado en Boston en 1970. Se trata de 506 casos (distritos) y 13 variables: tasa de criminalidad, proporción de zonas residenciales, superficie industrial, límite con el rio, concentración de óxido nítrico, habitaciones por hogar (rm), viviendas en propiedad anterior a 1940 (age), distancias ponderadas a 5 centros de empleo, índice de accesibilidad a la autopista, tasa de impuestos, relación alumno/profesor, transformación de la proporción de población de raza negra (b), proporción de pobres (lstat) y renta media de hogares con vivienda en propiedad (medv). Las instrucciones están en el script III.44.R. Después de cargar el paquete y el archivo de datos se realizan algunas transformaciones previas: logaritmo de lstat y cuadrado de rm. También se cambian los códigos de las clases de algunas de las variables. Por último, se construye el modelo lineal con la renta media de hogares con vivienda en propiedad (medv) como variable dependiente, y la proporción de pobres (lstat) y habitaciones por hogar (rm) como variables independientes, y el resto de variables se utilizan para la construcción del árbol.
¾ library(party)
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
266 ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
data("BostonHousing", package = "mlbench") BostonHousing$lstat <- log(BostonHousing$lstat) BostonHousing$rm <- BostonHousing$rm^2 BostonHousing$chas <- factor(BostonHousing$chas, levels = 0:1,labels = c("no", "yes")) BostonHousing$rad <- factor(BostonHousing$rad, ordered = TRUE) fm <- mob(medv ~ lstat + rm | zn + indus + chas + nox + age + dis + rad + tax + crim + b + ptratio, control = mob_control(minsplit = 40), data = BostonHousing, model = linearModel) plot(fm) 1 tax p < 0.001 d 432
2 ptratio p < 0.001 d 15.2
! 15.2
5 tax p < 0.001 d 265 Node 3 (n = 72) 54
54
1
1 0.3
3.9
! 432
4 ptratio p < 0.001 d 19.6
! 19.6
! 265
Node 6 (n = 63) Node 7 (n = 162) Node 8 (n = 56) Node 9 (n = 153) 54 54 54
1 0.3
3.9
1 0.3
3.9
1 0.3
3.9
54
54
54
54
54
1
1
1
1
1
6.3
83.5
6.3
83.5
6.3
83.5
6.3
83.5
0.3
3.9
6.3
83.5
En el gráfico anterior se observa como el modelo que intenta explicar la renta media de los hogares en función de la proporción de pobres y el número medio de habitaciones por hogar depende fundamentalmente de dos variables: la tasa de impuestos al patrimonio (variable claramente relacionada con la renta), y la
GRÁFICOS AVANZADOS
267
relación alumnos/profesor (variable asociada al número de niños, y en consecuencia al número de habitaciones). En cada nodo terminal se muestra gráficamente el modelo, representando la relación entre la variable dependiente (renta media de los hogares con vivienda en propiedad) y cada una de las dos variables independientes: logaritmo de la proporción de población pobre en la parte superior, y cuadrado del número de habitaciones por hogar en la inferior. La relación con la primera es siempre negativa, y con la segunda siempre positiva, aunque el modelo cambia de forma significativa en cada una de las 5 clases obtenidas. Se puede observar por ejemplo, como la relación lineal entre la renta y el número de habitaciones se va atenuando de izquierda a derecha, a medida que aumenta el impuesto medio sobre el patrimonio y la relación alumnos/profesor, de modo que en el tramo de impuestos más altos prácticamente desaparece la relación lineal entre renta y número de habitaciones por hogar, de tal forma que en esta última clase predomina la relación entre renta e impuesto, a diferencia de las restantes en las que parece más clara la relación entre renta y alumnos/profesor. Como vemos se forman clases en las que el modelo lineal en sí mismo es distinto, es decir, el criterio de clasificación es el modelo lineal. En último lugar, como ejemplo de regresión ordinal usaremos los datos mammoexp, incluidos en el paquete “party”. Estos datos contienen 412 observaciones y 6 variables de un experimento sobre mamografía: ME es información sobre si se ha realizado mamografía y cuando tiempo ha pasado desde la última vez (nunca, en el último año, más de un año), SYMP es qué piensa sobre si no es necesaria una mamografía cuando no tiene síntomas (totalmente de acuerdo, de acuerdo, en desacuerdo, totalmente en desacuerdo), PB beneficio percibido (suma de cinco variables en escala de 4 valores, cuanto más bajo indica mayor beneficio percibido), HIST historial sobre si la madre o hija ha tenido cáncer de mama (si, no), BSE es si le han enseñado autodiagnóstico (si, no), DECT si cree que la mamografía puede detectar un cáncer de mama (no creo, puede ser, estoy segura). El ejemplo se utiliza para mostrar como una variable ordinal (ME experiencia en mamografía) puede ser también utilizada como criterio de clasificación con la función «ctree()». La fórmula expresa la variable ME, experiencia en mamografía, como función de las restantes, y el árbol se construye, como en los ejemplos anteriores, buscando la variable explicativa más significativa en su relación con ME. Las instrucciones están en el script III.45.R.
¾ ¾ ¾ ¾
library(party) data(mammoexp) mammoct <- ctree(ME ~ ., data = mammoexp) plot(mammoct)
El gráfico muestra tres grupos. En el primer grupo predominan las pacientes que nunca han realizado una mamografía, grupo que se caracteriza por opinar que no es necesaria si no se tienen síntomas. Los otros dos grupos, formados por mujeres en desacuerdo con esa opinión, muestran diferentes frecuencias de la variable dependiente ordinal, y están constituidos por aquellas mujeres que perciben un mayor beneficio en la realización de mamografías (PB d 8) y las que no lo perciben, encontrándose mayores frecuencias de experiencia en mamografía en el primero. El diagrama de barras en cada nodo terminal del árbol ayuda a interpretar estas relaciones.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
268
1 SYMPT
<= Agree
> Agree 3 PB
<= 8 Node 2 (n = 113)
>8
Node 4 (n = 208)
Node 5 (n = 91)
1
1
1
0.8
0.8
0.8
0.6
0.6
0.6
0.4
0.4
0.4
0.2
0.2
0.2
0
0 Never
Within a Year Over a Year
0 Never
Within a Year Over a Year
Never
Within a Year Over a Year
Función ctree_control (paquete party) teststat: permite cambiar el test de independencia que se utiliza para decidir cual es la variable explicativa empleada para la división del árbol, donde las opciones son "quad" o "max": teststat = "quad". testtype: especifica como cuantificar la distribución del estadístico utilizado en el test y el cálculo del valor p, donde las opciones son "Bonferroni", "MonteCarlo", "Univariate" o "Teststatistic": testtype = "Bonferroni". mincriterion: valor que debe superar (1- p), para que se realice la partición del nodo: mincriterion = 0.95. minsplit: especifica la suma mínima de los pesos en el nodo para que se haga la partición: minsplit = 20. minbucket: especifica la suma mínima de los pesos en un nodo terminal: minbucket = 7. stump: si es FALSE un árbol con solo tres nodos (el nodo inicial y dos terminales) no se calcula: stump = FALSE. nresample número de réplicas Monte-Carlo cuando se determina la distribución del estadístico con ese método: nresample = 9999. maxsurrogate: máximo número de opciones “suplentes” para la división del árbol, que se utilizan –únicamente con variables ordinales– cuando la primera no cumple las condiciones para que la ramificación se pueda considerar válida: maxsurrogate = 0. mtry: algunos algoritmos se basan en la construcción de árboles aleatorios mediante selección de variables al azar en cada partición. En ese caso debe definirse con mtry el número de variables que se seleccionan; cuando es cero no se lleva a cabo una selección aleatoria: mtry = 0. savesplitstats: si es TRUE, se guardan (esto consume mucha memoria) los valores de los estadísticos utilizados en cada nodo, que pueden ser representados en un gráfico de dispersión junto con las variables explicativas: savesplitstats = TRUE. maxdepth: define la profundidad del árbol, es decir, el número máximo de niveles que se generan entre el nodo inicial y una rama terminal. El valor cero significa que no hay restricciones: maxdepth = 0.
GRÁFICOS AVANZADOS
269
Función ctree (paquete party) formula: se especifica la variable dependiente y las independientes en el modelo. data: data frame con los datos. subset: opcionalmente es posible realizar una selección de los datos: subset = NULL. weights: vector opcional con los pesos. Permite asignar a cada caso un peso o ponderación diferente; por ejemplo, si los casos son valores medios de distintas zonas, se puede utilizar como peso el número de elementos en las zonas; si un peso es cero, no se tiene en cuenta ese caso: weights = NULL. controls: modificaciones que se pueden realizar con la función ctree_control() que se detalla a continuación en el siguiente cuadro: controls = ctree_control() xtrafo: transformación a aplicar a las variables explicativas, en función del tipo de variable: xtrafo = ptrafo. ytrafo: transformación que se aplica a la variable respuesta: ytrafo = ptrafo. scores: lista opcional de nombres o números que se pueden asociar a los valores de los factores ordinales: scores = NULL.
Función plot (paquete party) x: objeto de la clase BinaryTree. type: especifica la complejidad del árbol: "extended" trata de visualizar la distribución de la variable de respuesta en cada nodo terminal, mientras que "simple" sólo proporciona información resumida: type = "extended". terminal_panel: se especifica el tipo de función para representar los gráficos de los nodos terminales con el formato function(node). Alternativamente se puede usar un generador de panel con la función grapcon_generator() que se llama con argumentos x y tp_args. Si es NULL se elige una función de forma automática en base al tipo de variable dependiente: terminal_panel = NULL. tp_args: lista de argumentos que se pasan a terminal_panel si se usa la función grapcon_generator(): tp_args = list(). inner_panel: igual que terminal_panel pero para los nodos intermedios: inner_panel = node_inner. ip_args: lista de argumentos que se pasan a inner_panel si se usa la función grapcon_generator(): ip_args = list(). edge_panel: función opcional del tipo function(split, ordered = FALSE, left = TRUE) para los bordes del gráfico. Alternativamente se puede usar un generador de panel con la función grapcon_generator() que se llama con los argumentos x y tp_args: edge_panel = edge_simple. ep_args: lista de argumentos que se pasan a edge_panel si se usa la función grapcon_generator(): edge_panel = list(). drop_terminal: indica como se representan los nodos terminales al fondo del árbol: drop_terminal = (type[1] == "extended").
270
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Función plot (Continuación) tnex: valor numérico que define el tamaño de los nodos terminales en relación con los nodos intermedios: tnex = (type[1] == "extended") + 1. newpage: si es TRUE se llama a la función grid.newpage(): newpage = TRUE.
Funciones de paneles (paquete party) Se utilizan para la configuración de los diferentes elementos del gráfico, que son distintos en función del elemento utilizado como variable dependiente en la fórmula. node_inner(ctreeobj, digits, abbreviate, fill, pval , id): configura el nodo interior. node_terminal(ctreeobj, digits, abbreviate, fill, id): configura el nodo terminal. edge_simple(treeobj, digits, abbreviate): configura los ejes laterales. node_surv(ctreeobj, ylines, id): configura un curva de supervivencia. node_barplot(ctreeobj, col, fill, beside, ymax, ylines, widths, gap, reverse, id): configura un diagrama de barras. node_boxplot(ctreeobj, col, fill, width, yscale, ylines, cex, id): configura un diagrama de cajas. node_hist(ctreeobj, col, fill, freq, horizontal, xscale, ymax, ylines, id): configura un histograma. node_density(ctreeobj, col, rug, horizontal, xscale, yscale, ylines, id): configura una función de densidad. node_scatterplot(mobobj, which, col, linecol, cex, pch, jitter, xscale, yscale, ylines, id, labels): configura un diagrama de dispersión. node_bivplot(mobobj, which, id, pop, pointcol, pointcex, boxcol, boxwidth, boxfill, fitmean, linecol, cdplot, fivenum, breaks, ylines, xlab, ylab, margins): configura un gráfico bidimensional, para regresión multivariante (en general ajustada con la función mob). ctreeobj: objeto de clase BinaryTree. treeobj: objeto de clase mob o BinaryTree. mobobj: objeto de clase mob. digits: número de decimales: digits = 3. abbreviate: si es TRUE se abrevian los textos: abbreviate = FALSE. col y pointcol: color de las líneas y símbolos. fill: color de relleno. pval: si es TRUE se muestran las probabilidades: pval = TRUE. id: si es TRUE se muestra el identificador del nodo: id =TRUE. ylines: número de líneas de separación entre gráficos en sentido vertical: ylines =3. widths: ancho en los diagramas de barras: widths = 1. width y boxwidth: ancho en los diagramas de cajas: width = 0.5. gap: hueco entre barras en los diagramas de barras: gap = NULL. yscale: límites del eje y: yscale =NULL.
GRÁFICOS AVANZADOS
271
Funciones de paneles (Continuación) xscale: límites del eje x: xscale =NULL. ymax: límite superior del eje y: ymax =NULL. beside: si es TRUE las barras se ponen unas al lado de otras y si es FALSE apiladas en los diagramas de barras: beside=NULL. reverse: si es TRUE se invierte el orden de los niveles en los diagramas de barras: reverse = NULL. horizontal: si es TRUE el diagrama de barras es horizontal: horizontal =TRUE. freq: si es TRUE el histograma es una representación de frecuencias y si es FALSE de probabilidades: freq = FALSE. rug: si es TRUE se añade un gráfico de segmentos verticales: rug = TRUE. which: vector numérico o de carácter que indica cuales de las variables regresoras deben ser representadas: which = all. linecol: color de las líneas en el modelo ajustado: linecol = "red". jitter: si es TRUE los puntos que se solapan se separan en el eje y: jitter = FALSE. labels: si es TRUE se muestran las etiquetas de los ejes: labels = FALSE. pop: si es TRUE se muestran los paneles gráficos: pop = TRUE. boxcol: color de los bordes del diagrama de caja: boxcol = "black". boxfill. color de relleno del diagrama de caja: boxfill = "lightgray". pointcol y pointcex: color y tamaño de los símbolos: pointcol = "black" y pointcex = 0.5. fitmean: si es TRUE se muestran las líneas con los valores medios estimados: fitmean = TRUE. cdplot: si es TRUE se representa la distribución acumulada de frecuencias (CD plot) o un espinograma (diagrama de barras en el que la frecuencia viene representada por la anchura de la barra en lugar de la altura), para comparar grupos de una variable categórica sobre una variable cuantitativa: cdplot = FALSE. fivenum: si es TRUE, en los espinogramas se utilizan como puntos de corte los llamados cinco puntos de resumen (mínimo, primer cuartil, mediana, tercer cuartil, máximo): fivenum = TRUE. breaks: una lista de puntos de corte alternativos para los espinogramas: breaks = NULL. margins: márgenes del panel: margins = rep(1.5, 4). Algunas funciones permiten los argumentos generales cex, pch, col, xlab e ylab.
III.25. Diagramas paleoecológicos La función «Stratiplot()» del paquete “analogue” (Simpson y Oksanen, 2012) permite realizar diagramas paleoecológicos. Las instrucciones están en el script III.46.R y como ejemplo se usan datos de metales en sedimentos a distintas profundidades del lago Yahuarkaka (Leticia, Colombia), que están en el archivo Sedimentos.csv (Cotes, 2011).
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
272
Después de cargar el paquete e importar los datos, se crea un vector con profundidades, que permitirá diferenciar los estratos en el perfil del sedimento y, posteriormente se añade una etiqueta para cada estrato. En la función «Stratiplot()» se especifica la variable y, en este ejemplo la profundidad del sedimento, y las diferentes variables a representar, los diferentes metales en el ejemplo. Con el argumento «type = c("poly","g")» se especifica que el tipo de gráfico sea en polígonos y se muestre la cuadrícula interna con las divisiones. Con «sort="wa"» las variables se ordenan por su valor de mayor a menor. Con los argumentos «zones» y «zoneNames» se especifican las variables con las profundidades de los estratos y las etiquetas de estos estratos, respectivamente. Con «col.zones» se define el color de las líneas de la cuadrícula interna que definen los estratos de las diferentes profundidades. Por último, con «col.poly» se define el color de los polígonos.
Co
Ni
Al
Cr
library(analogue) datos<-read.csv2("Sedimentos.csv", header=TRUE, encoding="latin1") attach(datos) Estratos <-c(50,100,200, 300) capas.eti <- c("E","D","C","B","A") Stratiplot(Profundidad ~ Cr + Co + Ni+ Al,type = c("poly","g"), sort="wa", zones = Estratos, zoneNames = capas.eti, col.zones="blue", col.poly="red", ylab="Profundidad (cm)", xlab="Metales en el sedimento del lago Yahuarkaka")
A 50
B 100
C
150
200
D
250
300
Metales en el sedimento del lago Yahuarkaka
0 5 15
30
0 10 20
60
40
20
0
80
60
40
20
E 0
Profundidad (cm)
¾ ¾ ¾ ¾ ¾ ¾
GRÁFICOS AVANZADOS
273
Función Stratiplot (paquete analogue) x, y, o formula: se puede usar x (matriz con las variables a representar) e y (variable donde están los datos de profundidad o años del eje y) o una fórmula. type: vector con uno o varios de los siguientes indicadores que permiten definir el tipo de gráfico. Con "l" (líneas), "p" (puntos), "b" (líneas y puntos), "h" (líneas horizontales), "g" (se representa una cuadrícula interna), "smooth" (línea suavizada) y "poly" (polígono): type = "l". data: opcionalmente se puede poner el nombre del data frame. pages: cuando el número de variables a representar es muy grande puede ser útil dividir el gráfico en varias páginas: pages = 1. rev: si es TRUE la escala del eje y se invierte: rev = TRUE. sort: método de ordenar las variables. Con "none" se sigue el orden especificado en la fórmula o en el que estén las variables en la matriz de datos, "wa" ordena las variables por su valor de mayor a menor, y "var" utiliza el orden que se especifique en svar: sort="none". svar: vector opcional en el que se puede especificar el orden de las variables: svar = NULL. rev.sort: si es TRUE la escala del eje x se invierte: rev.sort = FALSE. strip: si es TRUE cada variable se pone en un panel independiente: strip = FALSE. topPad: espacio del margen superior del gráfico: topPad =6. varTypes: especifica como se escala el eje x. Con "relative" todas las variables tienen la misma escala y con "absolute" los límites del eje x se ajustan para cada variable: varTypes = "relative". zones: vector con las profundidades de diferentes estratos. zoneNames: vector opcional con el nombre de cada una de los estratos: zoneNames = NULL. drawLegend: si es TRUE se muestra la leyenda de los estratos: drawLegend = TRUE. pch: tipo de símbolo cuando type es "p" o "b". col.line, col.symbol, col.refline, col.smooth, col.poly y col.zones: colores de las líneas, símbolos, cuadrícula interna, línea de suavizado, del polígono y de los estratos en el interior de la cuadrícula, respectivamente. lty.smooth y lwd.smooth: tipo y ancho de las líneas de suavizado. lty.zones y lwd.zones: tipo y ancho de las líneas de los estratos. gridh y gridv: número de líneas horizontales y verticales de la cuadrícula interna, respectivamente: gridh = -1 y gridv = -1. Se pueden usar los siguientes argumentos generales ylim, xlab e ylab, lty, lwd y cex.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
274
III.26. Gráficos climáticos III.26.1. ROSA DE VIENTOS Los mapas de viento se pueden hacer con otras funciones como por ejemplo la función «rosavent()» del paquete “climatol” (Gujarro, 2012). Se usarán de nuevo los datos de dirección e intensidad del viento (m s-1) que están en el archivo Clima España.csv. Las instrucciones están en el script III.47.R. La función «rosavent()» requiere una estructura de datos en la cual las columnas son categorías de vientos y las filas categorías de rangos de velocidad del viento. En cada celda está el número de días que se registró ese tipo y velocidad de viento durante el periodo de estudio. Para las categorías de viento se han diferenciado los distintos tipos de viento con el criterio que se muestra a continuación: 9 9 9 9 9 9 9 9
Viento Viento Viento Viento Viento Viento Viento Viento
del del del del del del del del
norte o Tramontana (N): de 337,5° a 22,5°. noreste o Gregal (NE): de 22,5° a 67,5°. este o Levante (E): de 67,5° a 112,5°. sureste o Siroco (SE): de 112,5° a 157,5°. sur o Migjorn (S): de 157,5° a 202,5°. suroeste, Lebeche o Garbí (SW): de 202,5° a 247,5°. oeste o Poniente (W): de 247,5° a 292,5°. noroeste o Mistral (NW): de 292,5° a 337,5°.
En el script depués de cargar el paquete e importar los datos, se excluyen aquellas filas en las que exista alguna celda en blanco.
¾ ¾ ¾ ¾ ¾
library(climatol) datos<-read.csv2("Clima España.csv", header=TRUE, encoding="latin1") datos<-datos[datos$Ciudad=="Palma de Mallorca",] datos<-na.exclude(datos) attach(datos)
Como la estructura de datos del archivo Clima España.csv no es la que necesita la función «rosavent()», posteriormente se crea un data frame para generar las categorías de velocidad y dirección de viento mencionadas anteriormente en las que se pone cero a cada celda. Las categorías de viento fueron 0-2, 2-4, 4-6, 6-8 y más de 8 ms-1. Se puede poner el rango de categorías de velocidad de viento que se quiera, pero es necesario dejar el rango de direcciones de viento que se asignan al vector «Dv». Con los argumentos «colnames» y «rownames» se ponen los nombres de las columnas y de las filas en la matriz creada, respectivamente.
¾ ¾ ¾ ¾ ¾ ¾
Dv<-as.data.frame(c(22.5, 67.5, 112.5, 157.5, 202.5, 247.5, 292.5, 337.5)) d<-nrow(Dv) Vv<-as.data.frame(c(2,4,6,8,8)) v<-nrow(Vv) A<-matrix(rep(0,v*8),nrow=v) A<-as.data.frame(A)
GRÁFICOS AVANZADOS
275
¾ colnames(A)<-c("N","NE","E","SE","S","SO","O","NO") ¾ rownames(A)<-c("0 - 2","2 - 4","4 - 6","6- 8 ","> 8") A continuación se genera un bucle para rellenar la matriz anterior con el número de días que hubo de cada tipo de viento, con la velocidad de las categorías antes descritas.
¾ for (z in 1:d){ for (i in 1:v){ if (z==1) N<-rbind(datos[Dir.Viento<22.5,],datos[Dir.Viento>=337,]) else N<-datos[Dir.Viento>=Dv[z-1,1] & Dir.VientoVv[i,1],] else N1<-N[N$Vel.Viento>Vv[i-1,1] & N$Vel.Viento<=Vv[i,1],] N1<-na.omit(N1) N2<-nrow(N1) A[i,z]<-N2 }} ¾ A Se obtiene la matriz que se muestra a continuación. Logicamente si se parte ya de esta estructura de datos, no es necesario la parte del script mostrada anteriormente.
Por último, se realiza el gráfico. El argumento «fnum» define el número de círculos concéntricos del gráfico. Con «fint» se especifica el porcentaje de cambio que significa cada círculo concéntrico, es decir, la escala. El argumento «ang» permite definir en que radio se colocan las etiquetas que indican la escala, simplemente cambiando el valor 16 por otro número. Con «uni» se especifica el título de la leyenda. El argumento lógico «key» define si se muestra la leyenda. Con el argumento «flab» se especifica si se pone una etiqueta en el último círculo (1), en todos los círculos (2), o en ninguno (cualquier otro valor). Aunque es posible usar el argumento «main», con la función «mtext()» es posible definir de forma más precisa la posición del título con respecto al gráfico.
¾ rosavent(A, fnum=8, fint=5, ang=-3*pi/16, Viento (m s"^"-1",")")), key=TRUE, flab=2) ¾ mtext("Palma de Mallorca", 3, cex=2, font=2)
uni=expression(paste("
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
276
Palma de Mallorca -1
Viento (m s ) 0-2 2-4 4-6 6- 8 >8
N
W
E 5% 10 % 15 % 20 % 25 % 30 % 35 % 40 %
S
III.26.2. DIAGRAMA DE WALTER-LIETH Este diagrama se puede realizar con la función «diagwl()» del paquete “climatol” (Gujarro, 2012). Se usarán de nuevo los datos que están en el archivo Clima España.csv. Las instrucciones están en el script III.48.R. Se carga el paquete y se importan los datos excluyendo aquellas filas que tengan alguna celda en blanco.
¾ ¾ ¾ ¾
library(climatol) datos<-read.csv2("Clima España.csv", header=TRUE, encoding="latin1") datos<-na.exclude(datos) attach(datos)
Se calcula la precipitación total de cada mes para cada ciudad y año. Si se quisiera hacer para varios años, sería necesario calcular la precipitación media mensual para todos ellos.
¾ Medias1<-aggregate(datos[ , c("Precipitación")], list(Ciudad= Ciudad, Año = Año, Mes = Mes), sum)
na.rm=TRUE,
by=
Se calculan las medias mensuales para cada ciudad, año y mes de la temperatura máxima y mínima.
¾ Medias2<-aggregate(datos[ , c("T.Max","T.Min")], na.rm=TRUE, by= list(Ciudad=Ciudad, Año=Año, Mes=Mes), mean)
GRÁFICOS AVANZADOS
277
Se calcula la temperatura más baja para cada mes para cada ciudad, año y mes.
¾ Medias3<-aggregate(datos[, c("T.Min")], na.rm=TRUE, by=list(Ciudad= Ciudad, Año=Año, Mes=Mes), min) Se selecciona la ciudad de Vigo y el año 2000 en los archivos con medias creados anteriormente.
¾ ¾ ¾ ¾ ¾ ¾
Med1<-Medias1[Medias1$Año=="2000",] Med1<-Med1[Med1$Ciudad=="Vigo",] Med2<-Medias2[Medias2$Año=="2000",] Med2<-Med2[Med2$Ciudad=="Vigo",] Med3<-Medias3[Medias3$Año=="2000",] Med3<-Med3[Med3$Ciudad=="Vigo",]
Se unen los tres archivos dejando el orden que requiere la función: precipitación mensual total, temperatura media máxima y mínima mensual, y temperatura mínima mensual.
¾ M<-cbind(Med1[,c(4)],Med2[,c(4,5)],Med3[,4]) Se crea una matriz con los meses y los cuatro parámetros que se necesitan.
¾ A<-matrix(rep(0,48),nrow=4) ¾ A<-as.data.frame(A) ¾ colnames(A)<-c("Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic") ¾ rownames(A)<-c("Prec.","Max.t.", "Min.t.", "Ab.m.t.") Se asigna cada valor de las medias calculadas en la matriz anterior.
¾ for (z in 1:12){ ¾ for (i in 1:4){ A[i,z]<-M[z,i] }} ¾ A Se obtiene la matriz que se muestra a continuación. Lógicamente si se parte ya de esta estructura de datos no es necesaria la parte del script mostrada anteriormente.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
278
En la función, el argumento «est» es para especificar el nombre del sitio. Con «alt» y «per» se especifica la altura del lugar y el periodo de tiempo, respectivamente. Con «mlab» se define si la leyenda de los meses se pone en español «es», en inglés «en» o con números «1-12». Los argumentos «pcol» y «tcol» definen el color de las líneas de precipitación y temperatura, respectivamente. Las barras azules encima de los meses indican periodos del año en los que pudo darse o hubo alguna nevada. Los argumentos «pfcol» y «sfcol» definen el color de esas barras, cuando hay probable nevada o es seguro que hubo nevada, respectivamente. Para zonas del hemisferio norte se pone «shem=FALSE» y para las del hemisferio sur «shem=TRUE». Si se pone «p3line=TRUE» se pinta una línea de referencia de la precipitación, a tres veces la temperatura.
¾ diagwl(A, est="Vigo aeropuerto", alt=261, per="2000", mlab="es", pcol = "#005ac8", tcol = "#e81800", pfcol = "#79e6e8", sfcol = "#09a0d1", shem = FALSE, p3line=FALSE) Vigo aeropuerto (261 m) 2000
13.8C
2450 mm 700
500
300 C
mm 50
100
40
80
30
60
20
40
10
20
0
0
24.1
3.3
E
F
M
A
M
J
J
A
S
O
N
D
III.27. Control de calidad El control de calidad es un conjunto de técnicas estadísticas que se utilizan en la empresa con el fin de asegurar la calidad del producto o servicio final. Históricamente comenzó como muestreo de aceptación, para comprobar la calidad de una remesa de producto homogéneo antes de su compra, pero con el tiempo las técnicas de control de calidad se fueron haciendo más complejas y sofisticadas, y se fueron aplicando en fases cada vez más tempranas –pasando por el control de
GRÁFICOS AVANZADOS
279
procesos– hasta llegar en la actualidad a las fases de diseño y planificación del producto. Se utilizan gráficas específicas y existen diferentes metodologías, que emplean técnicas estadísticas como muestreo probabilístico, análisis de la varianza, análisis de series temporales, diseño de experimentos, etc. Una metodología ampliamente utilizada es Seis Sigma. Se basa en un esquema de cinco fases secuenciales: Definir, Medir, Analizar, Mejorar y Controlar (DMAIC). El objetivo es reducir o eliminar los defectos. La meta de 6 Sigma es lograr un máximo de 3 o 4 defectos –unidades de producto o servicio que no cumplen los requisitos del cliente– por millón de oportunidades (DPMO); objetivo difícil, pero no imposible. R dispone de varios paquetes para la aplicación de técnicas de control de calidad, entre los que están “qcc” (Scrucca, 2012) para la realización de gráficos de control, “IQCC” (Recchia y Barbosa, 2012) para la realización de gráficos mejorados de control de calidad, “AcceptanceSampling” (Kiermeier, 2012) para muestreo de aceptación, o “qualityTools” (Roth, 2012) diseñado para enseñar métodos estadísticos para el control de calidad.
III.27.1. DEFINIR Esta primera fase consiste en la descripción del problema y sus consecuencias. Se utilizan habitualmente el Diagrama de Ishikawa y el diagrama de Pareto.
III.27.1.1. Diagrama de Ishikawa Esta representación también se le conoce como diagrama de causa-efecto o diagrama de espina de pescado. Consiste en una representación gráfica sencilla que consta de una línea horizontal, que representa el problema que se desea analizar, cuyo efecto principal se escribe a la derecha, y diversas líneas en forma de espinas de pez, que permiten describir los distintos elementos causales. En los extremos de estas líneas se indican las distintas categorías, y entre esos extremos y la línea central, las diferentes causas posibles asociadas a cada una. Pondremos un ejemplo sencillo, el cual consiste en analizar el bajo rendimiento académico de los alumnos de una Universidad. Utilizaremos para la construcción del diagrama la función «cause.and.effect()» del paquete “qcc” (Scrucca, 2012). Las instrucciones están en el script III.49.R. En el argumento «cause» introducimos una lista de las categorías que pueden estar influyendo: profesores, alumnos, organización, instalaciones, y materiales didácticos. Para cada categoría se construye un listado de causas probables. Por ejemplo los profesores están poco preparados o insuficientemente motivados, los alumnos no tienen una formación previa adecuada, o los materiales didácticos son antiguos y obsoletos, etc. Tanto la lista de categorías como la de causas pueden obtenerse mediante una sesión de “tormenta de ideas”. En «effect» se introduce el problema. Los argumentos «cex» y «font» permiten modificar el tamaño y la fuente de la letra, respectivamente, y ambos son un vector con tres valores: las ramas, las causas y el efecto.
¾ library(qcc) ¾ par(bg="palegoldenrod") ¾ cause.and.effect(cause=list(PROFESORES=c("Poca preparación","Escasa motivación"), ALUMNOS=c("Baja formación previa","Poca atención"), ORGANIZACIÓN=c("Horarios inadecuados","Información escasa"),
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
280
INSTALACIONES=c("Aulas incómodas","Ruidos","Faltan ordenadores"), EVALUACIÓN=c("Discontínua", "Memorística", "No equilibrada"), MATERIAL_DIDÁCTICO=c("No actualizado","Tecnología obsoleta")), effect="BAJO RENDIMIENTO", title="", cex = c(1.2,1.1,1.3), font = c(1,3,2)) ¾ mtext("Rendimiento académico del alumnado universitario", 3, line=1.5, font=2, cex=2)
Rendimiento académico del alumnado universitario PROFESORES
ALUMNOS
Poca preparación
ORGANIZACIÓN
Baja formación previa
Escasa motivación
Poca atención
Horarios inadecuados
Información escasa
BAJO RENDIMIENTO
Faltan ordenadores
Ruidos
Memorística
Aulas incómodas
INSTALACIONES
No equilibrada
Discontínua
Tecnología obsoleta
No actualizado
EVALUACIÓN MATERIAL_DIDÁCTICO
El resultado obtenido ayuda a comprender mejor la situación, y a avanzar en el análisis del problema para encontrar la solución adecuada. Se trata de juntar los distintos elementos involucrados, y definir su papel, para averiguar como pueden contribuir a la solución del problema. El diagrama de Ishikawa es útil cuando el problema es complejo, pero a menudo se encuentran en el control de calidad causas fácilmente identificables, en las que puede ser útil el diagrama de Pareto.
III.27.1.2. Diagrama de Pareto Consiste en un diagrama de barras, que ayuda a visualizar las causas importantes –generalmente en número reducido– y a distinguirlas de las triviales, más numerosas pero con menor influencia. Este diagrama se puede hacer con la función «pareto.chart()» del paquete “qcc” (Scrucca, 2012). Las instrucciones están en el script III.50.R. Supongamos que en la fabricación de un producto hemos detectado 8 tipos distintos de defectos, y que cada unidad puede presentar o no cualquiera de ellos. En una muestra hemos encontrado los defectos, representados por letras mayúsculas, el siguiente número de veces: A:1; B:1; C:4; D:2; E:47; F:1; G:1; H:11. Se construye una variable «defectos» con los datos. Posteriormente, con la
GRÁFICOS AVANZADOS
281
función «names()» se le asignan etiquetas a los valores de la variable «defectos». Con «rainbow(8)» se definen los colores de las barras. El número 8 es debido a que hay ocho defectos. Se podría poner el mismo color en todas las barras omitiendo la orden anterior. En la función «pareto.chart()», en el argumento «cumperc» con la función «seq()» se especifica que el eje del porcentaje acumulado tenga unos límites de 0 a 100 y se divida la escala por 20.
¾ ¾ ¾ ¾ ¾
library(qcc) defectos <- c(1, 1, 4, 2, 47, 1,1,11) names(defectos) <- c("A", "B", "C", "D", "E", "F", "G", "H") color<-rainbow(8) pareto.chart(defectos, cumperc = seq(0, 100, by = 20), ylab = "Frecuencia", ylab2="Porcentaje acumulado", xlab="Tipos de defectos", main="Defectos de fabricación en un producto", col=color, ylim=c(0,70))
100%
Defectos de fabricación en un producto 70
80%
60
30
Porcentaje acumulado
60%
40
40%
Frecuencia
50
20%
20
0%
10
G
F
B
A
D
C
H
E
0
Tipos de defectos
El diagrama de Pareto muestra una barra para cada tipo de defecto, junto con una curva de frecuencias acumuladas en la parte superior. En nuestro ejemplo se observa que solo los defectos E y H son importantes. La función también calcula una tabla de frecuencias que se muestra en la consola principal, donde se ve que los defectos E y H suponen el 85% de todos los defectos observados.
282
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
III.27.2. MEDIR En el control de calidad es casi siempre necesario medir y contar. Desde antiguo se conoce que la medida no es exacta, ya que el error depende de la precisión de los instrumentos utilizados, de la habilidad de los operadores, de las condiciones ambientales, etc. El error de medida tiene además una distribución Normal, como ya mostró Gauss hace doscientos años. En general existen dos tipos de desajustes en la medida:
Sesgo: desplazamiento, que se supone constante, en los valores de las medidas de la misma magnitud. Variabilidad: propia del sistema de medida o añadida por otros factores (operarios, condiciones ambientales, etc.)
Estos desajustes conducen a resultados distintos al medir de forma repetida la misma unidad. Un cierto grado de desajuste es admisible, ya que en general no existen las medidas sin error, y ese grado deberá ser definido en función de la necesidad de identificar distintas categorías del producto, y su tolerancia (rango de desviaciones que mantiene la utilidad del producto). La incapacidad del sistema para medir correctamente puede conducir a aceptar unidades que están fuera de los límites de tolerancia, o a rechazar unidades que están dentro de esos límites. Ambos errores de decisión deben ser evitados por igual, teniendo en cuenta los costes correspondientes.
III.27.2.1. MSA tipo I Los análisis de los sistemas de medidas (MSA) de tipo I son experimentos o procedimientos diseñados para verificar la corrección de la medida. Se calcula un índice de capacidad del sistema de medida (Cg) como cociente entre una fracción, típicamente 0,2, de la amplitud del intervalo de tolerancia o diferencia entre el límite superior (LS) y el límite inferior (LI) y una medida de la dispersión, generalmente el rango en el que se encuentran el 95,5% o el 99,73% de los valores. Estos porcentajes corresponden a amplitudes de intervalo de 4 ó 6 desviaciones típicas (valores k=2 y k=3 de una variable Normal estándar). La mayoría de las medidas siguen en la práctica una distribución Normal, pero pueden utilizarse los cuantiles correspondientes en lugar de los citados valores k si la distribución es otra. El valor del índice de capacidad es:
ܥ ൌ Ͳǡʹ
ሺௌିூሻ ସ௦
ó
ܥ ൌ Ͳǡʹ
ሺௌିூሻ ௦
GRÁFICOS AVANZADOS
283
Cuando hay sesgo, debe restarse éste del numerador. El sesgo se calcula midiendo repetidamente una magnitud conocida exactamente (un patrón), y restando la media de las medidas (xm) menos la cantidad exacta o medida patrón (xe):
ܵ݁ ݃ݏൌ ȁݔ െ ݔ ȁ ܥ ൌ Ͳǡʹ
ሺௌିூିௌ௦ሻ
ó
ସ௦
ܥ ൌ Ͳǡʹ
ሺௌିூିௌ௦ሻ ௦
MSA tipo I se puede hacer con la función «cg()» del paquete “qualityTools” (Roth, 2012). Las instrucciones están en el script III.51.R. En el archivo Piezas.csv hay medidas del diámetro interior de dos piezas de automóvil en milímetros. El diámetro objetivo, que se pretende conseguir con la fabricación, es 23,65 mm, con límites de tolerancia LI = 23,35 y LS = 23,95. En la función «cg()» con «target» se define el valor objetivo. Con el argumento «tolerance» los límites superior (LS) e inferior (LI). Por último, con «cex.val» el tamaño del texto de la tabla.
¾ ¾ ¾ ¾ ¾
library(qualityTools) datos<-read.csv2("Piezas.csv", header=TRUE, encoding="latin1") attach(datos) windows(11,8) cg(Pieza1, target = 23.65, tolerance = c(23.35, 23.95), cex.val=2) RunChart
x99.865%
x s target Cg Cgk
23.70
xtar 0.1 T
35
Histogram of Pieza1 - target conf.int
15
20
25
30
H0 : Bias = 0 t-value: -1.207 p-value: 0.235
0
5
10
Density
x
x
23.65
target
= 23.64 = 0.03 = 23.65 = 0.83 = 0.76
-0.04
-0.02
0.00
0.02
23.60
Tolerance View
x 0
10
20 Index
30
23.4
x0.135%
23.6
23.8
xtar 0.1 T
0
10
20 Index
30
0.04
284
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
El gráfico de la izquierda muestra como los valores se mantienen dentro de los márgenes de tolerancia (líneas continuas negras), y en la tabla se observa como la media de la muestra (23,64) coincide prácticamente con el valor objetivo (23,65), por lo que no existe sesgo. Para comprobarlo se muestra el histograma de la derecha con la desviación entre ambos valores, media muestral y valor objetivo o de referencia, y los resultados del contraste sobre la hipótesis nula de que la media es igual a la referencia, con un valor p = 0,235, que confirma que no hay diferencias significativas entre la media de la muestra y el valor objetivo. La tabla también muestra los índices de capacidad Cg = 0,83 y Cgk = 0,76, de los que debe usarse el primero (ya que el sesgo es nulo). En general el valor debe superar el límite 1,33 para que se considere aceptable, por lo que la capacidad observada es insuficiente. Cuando la capacidad es baja los errores de medida pueden llevarnos a identificar como fuera de límites unidades que realmente están dentro y viceversa.
Función cg (paquete qualityTools)
x: vector o variables con las medidas realizadas. target: valor objetivo. tolerance: vector con el límite superior y el límite inferior. ref.interval: valor numérico con el nivel de confianza: ref.interval = 0.9973002. facCg: valor numérico para calcular el índice de capacidad del sistema de medida centrado (Cg): facCg = 0.2. facCgk: valor numérico para calcular el índice de capacidad del sistema de medida no centrado (Cgk): facCgk = 0.1. n: valor numérico entre 0 y 1 que define la fracción a utilizar de la amplitud de los límites de tolerancia: n = 0.2. col: color de la línea que une los puntos en el gráfico principal.
Se pueden usar los argumentos generales type, pch, xlim e ylim.
III.27.2.2. MSA tipo II Los análisis de los sistemas de medidas (MSA) de tipo II son procedimientos diseñados para estudiar la repetibilidad y reproductibilidad (R&R) de un sistema de medidas. La repetibilidad se refiere a la precisión de la medida, valorada a través de la desviación típica, resultado ésta de la toma de varias mediciones de una misma medida y en las mismas condiciones, es decir, en un mismo objeto, con un único instrumento de medición y por el mismo operario. La reproductibilidad es el promedio de variaciones debidas a la toma de una determinada medida efectuada bajo condiciones de medición diferentes, que pueden ser distintos instrumentos, distintos operarios, distintas condiciones ambientales, etc. La varianza total observada puede ser expresada como suma de las distintas componentes: ଶ ଶ ଶ ߪ௧௧ ൌ ߪ௭௦ ߪௗௗ
Es decir, una parte de la variabilidad se debe al hecho de que las piezas medidas son distintas, y otra parte se debe al propio proceso de medida.
GRÁFICOS AVANZADOS
285
A su vez, la variabilidad de la medida puede descomponerse en la suma de los distintos efectos o factores, incluidas las interacciones de dos o más factores: ଶ ଶ ଶ ଶ ߪௗௗ ൌ ܴ݈ܾ݁݀ܽ݀݅݅݅ݐܿݑ݀ݎሺߪ௦ ߪ௧௦ ߪ௧ ଶ ଶ ଶ ߪ௦כ௧௦ ߪ௦כ௧ ǤǤ)ܴ݈ܾ݁݀ܽ݀݅݅݅ݐ݁ሺߪ )
La varianza del error es intrínseca al proceso de medida, y generalmente inevitable, y se denomina repetibilidad. El resto de la varianza de la medida puede ser explicada, e incluso evitada (utilizando un único operario, un solo instrumento, idénticas condiciones ambientales, etc.), y se denomina reproductibilidad. Para el análisis podemos utilizar las funciones «gageRRDesign()», «response()» y «gageRR()» del paquete “qualityTools” (Roth, 2012). Las instrucciones están en el script III.52.R. En el archivo R&R.csv hay mediciones tomadas por tres operarios a diez piezas distintas y cada operario midió dos veces cada pieza. Es importante entender la estructura de la matriz de datos para realizar un correcto diseño. Por ejemplo, la variable «Operario2.1» contiene las primeras medidas realizadas por el operario 2 y «Operario2.2» las segundas medidas realizadas por el mismo operario, de cada una de las diez piezas. Es necesario medir al menos dos veces cada pieza para obtener la variabilidad residual o intrínseca del sistema. En la función «gageRRDesign()», en los argumentos «Operators», «Parts» y «Measurements» se especifica el número de operarios, de objetos (piezas) medidas y cuantas veces se midió cada objeto por cada operario, respectivamente. En «method» se puede elegir entre «crossed», que es el diseño en el cual un objeto se puede medir varias veces, como es el caso de este ejemplo, o «nested» que es el caso en el cual para poder medir el objeto se tiene que destruir, y las réplicas consisten en medir la misma parte en diferentes piezas, asumiendo que esas partes son parecidas. El argumento «sigma» (por defecto 6) determina el intervalo de confianza y con «randomize=TRUE» se puede aleatorizar el diseño. En la función «response()» se asignan las variables o vectores con la mediciones al objeto «diseño», que se organizó con la función «gageRRDesign()» descrita anteriormente. Por último, con la función «gageRR()» se realiza el análisis R&R, que se asigna al objeto «gdo», del cual luego extraemos los resultados gráficos con la función «plot()».
¾ ¾ ¾ ¾
library(qualityTools) datos<-read.csv2("R&R.csv", header=TRUE, encoding="latin1") attach(datos) diseño <- gageRRDesign(Operators=3, Parts=10, Measurements=2, method="crossed", sigma = 99.73, randomize=FALSE) ¾ response(diseño)<- c(Operario1.1, Operario2.1, Operario3.1, Operario1.2, Operario2.2, Operario3.2) ¾ gdo<-gageRR(diseño) ¾ plot(gdo) Los resultados de la tabla son los de un análisis de la varianza (ANOVA), que permite identificar los distintos sumandos y calcular las componentes. Los resultados muestran que el efecto del operario (p = 0,00099) y de la pieza (p < 0,001) son ambos significativos, pero no la interacción entre ambos (p = 0,495).
286
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Por lo tanto consideraremos el modelo sin interacción, como se muestra en la siguiente tabla de ANOVA. De nuevo se observa que existen diferencias significativas en las medidas realizadas entre piezas (p = 0,00054) y en función de quien sea el operario que las realice (p < 0,001).
Los siguientes resultados muestran la descomposición de la varianza entre los distintos elementos. Como se explicó anteriormente, la varianza total se debe a dos causas: las diferencias entre piezas (Part to Part) con un 50,9% de total y los errores de medida (totalRR), que representan el 49,1% del total. Esta última, es la que nos interesa analizar y, a su vez, se divide en dos partes: repetibilidad (35,3%), o error atribuible al proceso de medida en sí mismo, y reproducibilidad (13,8%), o error atribuible a otros factores conocidos, en este caso a las diferencias entre operarios. En general se requiere que la contribución de la RR total no supere el valor 0,1 y se consideran inaceptables valores mayores que 0,3 como los observados en el ejemplo.
Los datos anteriores también se pueden ver en los gráficos que se muestran a continuación. En la parte izquierda, el diagrama de barras representa las componentes de la varianza, en proporción, en color rojo. En color verde se muestran las proporciones correspondientes a las desviaciones típicas. Como se mencionó anteriormente, la varianza total se debe a la variabilidad en los errores de medida (totalRR), y las diferencias entre piezas (PartToPart). En general se aprecia
GRÁFICOS AVANZADOS
287
como la variabilidad debida a las piezas es ligeramente mayor que la debida al proceso de medida y, dentro de esta última, la repetibilidad o error interno del proceso de medida es mayor que la reproducibilidad o error atribuible a los operarios. El diagrama de cajas, Measurement by Operator, muestra las diferencias entre operarios. El tercero tiende a obtener medidas más altas que los otros dos (mediana o trazo grueso más alto), y con una variabilidad (imprecisión, dada por la amplitud de la caja) también superior. El diagrama de interacción, Interaction operator:Part, debajo del anterior, indica una evolución similar para los tres operarios, con líneas que apenas se cruzan y, por lo tanto, interacción nula entre operario y pieza, como mostró el ANOVA al ser la interacción no significativa. En la parte derecha se muestra en primer lugar un diagrama de cajas que explica las diferencias entre piezas. La pieza F tiene medidas claramente superiores a las restantes. El gráfico intermedio y el inferior indican los valores medios y el rango de las dos medidas tomadas, para cada operario y cada pieza, respectivamente. En el intermedio, los valores que sobresalen por encima de la línea roja (límite superior del intervalo de confianza) corresponden sistemáticamente a la pieza F en los tres operarios. En el inferior todos los valores están dentro de los límites de confianza. Components of Variation
Measurement by Part
23.8 23.7
Measurement
0.6 0.4 0.0
23.5
0.2
23.6
0.8
VarCompContrib StudyVarContrib
totalRR
repeatability
reproducibility
PartToPart
A
B
C
D
component
23.80 23.70
x
23.60
LCL = 23.53
A
B
3 2
2 1
1 2
3 1
1 2
R
3 3
3
2 1
1
H
I
J
B
C
D
UCL = 0.17
R 0.07
0.00
2 2
A
A B C
0.10
1 2 3
0.15
Operator
0.05
23.80 23.70
mean of Measurement
23.60 23.50
R Chart
2 1 1 3
C Operator
2 1
2
E
F Part
G
J
x 23.62
C
3
1
I
UCL = 23.71
Interaction Operator:Part
3
H
23.50
23.8 23.7
Measurement
23.6 23.5
B
3
G
x Chart
Operator
3
F Part
Measurement by Operator
A
E
LCL = 0 A
B
C Operator
288
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
III.27.3. ANALIZAR Más allá de la medida, es necesario analizar la capacidad del proceso productivo para averiguar en qué extensión se están utilizando los márgenes de tolerancia por las causas comunes de variabilidad. De este modo podremos saber también qué proporción de las unidades estarán fuera de los márgenes (piezas defectuosas), si el proceso está controlado o no, y si es necesario realizar algún tipo de intervención. Se utilizan tres índices de capacidad de proceso:
ܿ ൌ
ሺܷܵ ܮെ ܮܵܮሻ ൫ܳǡଽଽ଼ହ െ ܳǡଵଷହ ൯
ܿ ൌ
ܿ ൌ siendo
൫ܳǡହ െ ܮܵܮ൯ ൫ܳǡହ െ ܳǡଵଷହ ൯ ൫ܷܵ ܮെ ܳǡହ ൯ ൫ܳǡଽଽ଼ହ െ ܳǡହ ൯
ܿ ൌ ݉݅݊൫ܿ ǡ ܿ ൯
El índice cp es la capacidad potencial del proceso si es centrado (si la variable es Normal), y cpk la capacidad real incorporando la posición y la forma de la distribución de la característica. Se miden en ese caso dos capacidades laterales, superior e inferior, y se toma la menor de ellas. El valor Q se refiere al cuantil correspondiente, indicado por el subíndice, siendo USL y LSL los límites de tolerancia superior e inferior. En el archivo Piezas.csv hay medidas del diámetro interior de dos piezas de automóvil en milímetros. En este caso vamos a trabajar con la pieza 2. El objetivo es determinar qué proporción de las unidades está fuera de los márgenes (piezas defectuosas). Las instrucciones están en el script III.53.R. Se puede utilizar la función «pcr()» del paquete “qualityTools” (Roth, 2012) para el cálculo de las capacidades de proceso. Esta función representa un histograma, la distribución ajustada, y calcula los índices de capacidad, los parámetros de la distribución, y un test de ajuste. En la función debe indicarse cual es la distribución que quiere utilizarse como referencia con el argumento «distribution». Se pueden utilizar otras distribuciones distintas de la Normal, por ejemplo la distribución Weibull, que se emplea con frecuencia en el ámbito del control de calidad. Con «target» se define el valor objetivo.
¾ ¾ ¾ ¾ ¾ ¾
library(qualityTools) datos<-read.csv2("Piezas.csv", header=TRUE, encoding="latin1") attach(datos) windows(14,9) pcr(Pieza2, distribution="normal", target=25.567, main="", cex.val=2) title("Capacidad del proceso", cex.main=2)
GRÁFICOS AVANZADOS
289
El test de Anderson-Darling es uno de los más potentes para probar la hipótesis de normalidad. En este caso, ya que el valor p > 0,05, se cumple la Normalidad.
El gráfico muestra un histograma, que permite apreciar de modo aproximado la forma Normal de la distribución, a lo que contribuye el pequeño diagrama de la derecha –un gráfico qq– que transforma la variable de forma que si es Normal los puntos deben situarse aproximadamente sobre la diagonal, como ocurre en el ejemplo. En el histograma se muestran también los límites de tolerancia (25,5 y 25,6), y se observa que ningún valor está fuera de ellos. Las piezas observadas por millón (ppm) son cero, y se calcula la fracción esperada de piezas defectuosas o no conformes, expresada también en piezas por millón: pL =1349,9 por encima del margen superior, pu = 1349,9 por debajo, 2699,8 en total por cada millón de piezas, es decir, el 0,27% (pt =2699,8). En el gráfico se muestran también los índices de capacidad: cp = 1 y cpk = 1. En general se consideran aceptables los índices con valores superiores a 1,33. También se muestran los parámetros de la distribución Normal estimados con los datos de la muestra (media = 25,6; dt = 0,0157), y el estadístico A y valor p del test de Normalidad de Anderson-Darling.
Capacidad del proceso LSL = 25.5
USL = 25.6
cpkU= 1 cpkL= 1 cpk= 1 cp= 1
20
25
30
TARGET
25.53
0
25.55
5
25.57
25.59
10
15
n= 37 A= 0.682 p= 0.0689 mean= 25.6 sd= 0.0157
25.50
25.52
25.54
25.56
Expected Fraction Nonconforming pt = 0.0026998 pL = 0.0013499 pU = 0.0013499
ppm ppm ppm
= 2699.8 = 1349.9 = 1349.9
25.58
25.60
25.62
Observed ppm = 0 ppm = 0 ppm = 0
25.64 25.54
25.55 25.56 25.57 25.58 25.59 25.60
290
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Función pcr (paquete qualityTools) x: vector, variable o data frame con las medidas realizadas. distribution: tipo de distribución para la cual se calcula la capacidad del proceso ("normal", "log-normal", "exponential", "logistic", "gamma", "weibull", "cauchy", "beta", "f", "t", "geometric", "poisson" o "negative-binomial"): distribution = "normal". lsl: límite mínimo. usl: límite máximo. target: valor objetivo. boxcox: si es TRUE se realiza una transformación Box-Cox: boxcox = FALSE. lambda: valor de lambda para la transformación de Box-Cox: lambda = c(-5,5). grouping: si se seleccionan grupos, se calcula la desviación estándar como la desviación estándar media de los subgrupos especificados corregidos por el factor de c4, y la fracción esperada de los no conformes se calcula utilizando esa desviación estándar: grouping = NULL. std.dev: desviación para la distribución Normal: std.dev = NULL. conf.level: nivel de confianza: conf.level = 0.9973002. lineWidth: ancho de línea de la curva de densidad: lineWidth = 1. lineCol: color de línea de la curva de densidad: lineCol = "red". lineType: tipo de línea de la curva de densidad: lineType = "solid". specCol: color de las líneas de los límites: specCol = "red3". specWidth: ancho de línea de los límites: specWidth = 1. cex.text: tamaño del texto de lsl, usl y target: cex.text = 2. cex.val: tamaño del texto de los índices: cex.val = 1.5. cex.col: color de lsl, usl y target: cex.col = "darkgray". Se pueden usar los argumentos generales main, xlim e ylim.
III.27.4. MEJORAR Las características de calidad que podemos medir en el producto final definen la eficacia del proceso productivo: el proceso será eficaz si el producto es adecuado y reúne las propiedades deseables. Para conseguir ese resultado es necesario utilizar otras variables, variables de entrada o inputs del sistema, que deben ser modificadas y ajustadas de forma coordinada para conseguir el resultado buscado. Se denominan genéricamente “factores” las variables de entrada que tienen efecto sobre las variables de salida o características de calidad, y que pueden ser controladas (la temperatura del proceso, o su duración). Existen otras variables de entrada que no pueden ser controladas por distintos motivos. Algunas de ellas pueden ser incluso no conocidas; de otras no sabemos cual es su efecto sobre las variables de salida (o no existe tal efecto); algunas son difíciles de controlar, y otras sería excesivamente costoso hacerlo. Variables no controlables podrían ser por ejemplo la humedad ambiental, algunas características mal conocidas de la materia prima, o la concentración o motivación de un operario. Las variables de entrada no controladas añaden variabilidad (ruido) al producto, y generalmente se intenta mantenerlas constantes.
GRÁFICOS AVANZADOS
291
III.27.4.1. Diseño factorial Se utiliza para profundizar en el conocimiento de los factores y de su efecto sobre las características de calidad. Supongamos un experimento para averiguar el efecto sobre una variable dependiente, por ejemplo el diámetro interior de una pieza, de tres factores: temperatura (A); tiempo de exposición (B) y cantidad de un aditivo empleado en el proceso de fabricación (C). Utilizaremos para cada factor dos niveles, inferior y superior, además de un nivel intermedio de referencia. Se puede hacer también el experimento sin utilizar valores intermedios. Las instrucciones están en el script III.54.R. En la función «facDesign()» el argumento «k» es el número de factores, en este caso son tres: temperatura, tiempo de exposición y cantidad de aditivo. Con «replicates=1» se especifica que se quiere un diseño en el que solamente se mida una réplica. El argumento «centerCube=4» se utiliza para indicar que vamos a emplear niveles intermedios en los factores (en otro caso sería cero). El programa añade un factor, bloque (que no utilizaremos en este ejemplo), que permite agrupar las unidades homogéneas.
¾ odf <- facDesign(k = 3, replicates=1, centerCube = 4, block=1) ¾ names(odf) <- c("Temperatura", "Tiempo" , "Aditivo" ) ¾ summary(odf)
La función genera automáticamente el diseño del experimento y decide cuantas unidades necesitaremos en la muestra y las combinaciones adecuadas de los niveles de los factores para cada unidad. Observamos que contiene doce medidas, y determina los valores asignados a los diferentes niveles de los factores: 1 es el nivel superior, -1 el inferior y 0 el intermedio. La variable de resultado es y, que de momento aparece con valor NA, o valor perdido. Podemos ig-
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
292
norar la variable Block, que no utilizaremos. La única combinación de los factores que se repite es la de valores intermedios, lo que permitirá estimar la variabilidad residual. El paso siguiente consiste en realizar el experimento para obtener la variable de resultado para cada combinación de los tres factores. Los valores medidos están en el archivo Factores.csv. Es muy importante respetar el orden de los valores de acuerdo con el diseño mostrado anteriormente. En el archivo, el primer dato corresponde a la primera combinación del diseño (1,1,1), es decir, se mide el diámetro de la pieza en las condiciones de máxima temperatura, máximo tiempo de exposición y máxima cantidad de aditivo. El segundo dato del archivo es la combinación (-1,-1,1), es decir, condiciones de mínima temperatura, mínimo tiempo de exposición y máxima cantidad de aditivo. Así, sucesivamente con el resto de valores que introducimos en las siguientes filas del archivo. Posteriormente cargamos los datos e introducimos los valores de esa variable de resultado en nuestro objeto odf. Con la función «effectPlot()» se muestra el efecto de los factores sobre el diámetro interno de la pieza. Con «classic» se puede elegir entre el estilo de gráfico clásico en una sola fila (TRUE) o en varias filas (FALSE). Con «fun» se define el tipo de función, en este caso la media. Con «single=FALSE» se especifica que todos los gráficos salgan en una ventana. Por último, con «points=TRUE» salen los puntos en el gráfico.
¾ datos<-read.csv2("Factorial.csv", header=TRUE, encoding="latin1") ¾ response(odf)<-datos$VR ¾ effectPlot(odf, classic=TRUE, fun = mean, single = FALSE, points = TRUE, axes = TRUE, main="", cex.lab=2) ¾ title("Diseño factorial", cex.main=2)
9.0
9.5
10.0
10.5
11.0
Diseño factorial
-1
1
A: Temperatura
-1
1
B: Tiempo
-1
1
C: Aditivo
GRÁFICOS AVANZADOS
293
Observamos en el gráfico anterior como en el factor temperatura, el nivel bajo produce un resultado cercano a 9,8 y el alto a 10,2 del diámetro interior de la pieza, el factor tiempo da un resultado de 9,5 y 10,4 y el factor aditivo 10,6 y 9,3, es decir, en éste último el efecto es negativo, más aditivo conduce a menor valor de la variable. El siguiente paso es determinar si existe interacción entre los factores y, para ello, usamos la función «interactionPlot()».
¾
interactionPlot(odf, main="", response = NULL, fun = mean, col = c("red", "green")) ¾ title("Interacción entre factores", cex.main=1.5) El gráfico muestra que no existen interacciones, ya que las líneas rectas no se cruzan en ningún caso.
Interacción entre factores 1
-1
1
A
A -1 1
10.5
-1 1
11.0
-1
9.0
9.5
10.0
A
10.5
-1 1
11.0
B
9.0
9.5
10.0
B
C Para saber si los efectos observados son significativos o no lo son necesitamos otros gráficos. El paquete “qualityTools” (Roth, 2012) dispone de dos adecuados para este fin: gráfico de Pareto y gráfico Normal:
¾ windows(12,7) ¾ par(mfrow = c(1,2)) ¾ paretoPlot(odf,main="", ylab="Diámetro interno", ylim=c(0,20), xlab="Factores") ¾ title("Diagrama de Pareto", cex.main=1.5)
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
294
¾ normalPlot(odf,main="",xlab="Coeficientes", ylab="Cuantiles teóricos") ¾ title("Gráfica de Normalidad", cex.main=1.5) El primer gráfico muestra una barra para cada efecto, incluyendo todos los factores y sus interacciones, ordenados de mayor a menor por el tamaño del efecto. Una línea roja horizontal indica el valor de un efecto significativo para el tamaño de muestra utilizado. Observamos que los tres factores tienen efectos estadísticamente significativos, pero ninguna de las interacciones lo es (están por debajo de la línea). El segundo gráfico muestra el efecto en el eje horizontal, y permite distinguir un efecto negativo (factor C e interacción ABC) de otros positivos. La línea roja corresponde ahora a la hipótesis nula de efecto nulo: los efectos que se alejan de la línea roja (se marcan en color rojo para el nivel de significación 0,01) son significativos. De nuevo comprobamos que los efectos simples son todos significativos y las interacciones no lo son. Para calcular la significación estadística se utiliza el supuesto –suele cumplirse en la práctica- de que los residuos tienen distribución Normal. Diagrama de Pareto
Gráfica de Normalidad 10
20 A Temperatura B Tiempo C Aditivo
B
p < 0.01 p >= 0.1
-15.332 5
A
10.43 10
B:C
A:C -5
4.931
A:B
0
Cuantiles teóricos
Diámetro interno
15
5
A:B:C 2.776 0.926 -0.687 0.03
-10
-1.464
C
Factores
B:C
A:C
A:B
A:B:C
A
B
C
0 -15
-10
-5
0
5
10
Coeficientes
Para mejorar nuestro conocimiento de las relaciones entre los factores y la variable dependiente realizamos gráficos 3D con las funciones «wirePlot()» y «contourPlot()» del paquete “qualityTools” (Roth, 2012), las cuales tienen argumentos muy similares a las funciones para este tipo de gráficos que se vieron en el Capítulo I.
¾ windows(14,6) ¾ par(mfrow = c (1,2)) ¾ wirePlot(A, B, datos.VR, data = odf, main="", zlab="A:Diámetro interno", ylab="Tiempo", xlab="Temperatura", sub="Diámetro interno~A+B+AB", theta = 120, phi = 20) ¾ contourPlot(A, B, datos.VR, data = odf, main="")
GRÁFICOS AVANZADOS
295
El primer gráfico muestra como varía la variable resultado con los distintos valores de los factores, suponiendo –como es el caso– que éstos pueden variar de forma contínua. El valor de la variable objetivo se muestra en el eje vertical con un código adicional de colores que permite averiguar las combinaciones de valores de los factores (temperatura y tiempo) necesarias para conseguir un valor adecuado de la variable dependiente. Para este objeto puede ser más adecuado el gráfico de curvas de nivel de la derecha: así por ejemplo, temperatura= -0,5 (valor medio-bajo) y tiempo = 0,5 (medio-alto) permite conseguir un valor de diámetro interno de 10. 1.0 > +9.2 > +9.4 > +9.6 > +9.8 > +10 > +10.2 > +10.4 > +10.6 > +10.8
rno et ro inte A:D iám
10.0
-1.0 9.5
0.5
B : Tiempo
10.5
> +9.2 > +9.4 > +9.6 > +9.8 > +10 > +10.2 > +10.4 > +10.6 > +10.8
0.0
ra
-0.5
rat u
-1.0
0.0 0.5
-0.5
Te
Tie 0.0 mp o
mp e
-0.5 0.5 1.0 1.0
-1.0 -1.0
-0.5
Diámetro interno~A+B+AB
0.0
0.5
1.0
A : Temperatura
Se muestran por último los diagramas para los factores tiempo/aditivo y temperatura/aditivo, cuya interpretación es similar. El hecho de que las curvas de nivel sean rectas y paralelas indica que la relación entre factores y variable resultado es lineal, e indica también que no existen interacciones.
¾ windows(14,6) ¾ par (mfrow = c (1,2)) ¾ wirePlot(B, C, datos.VR, data = odf, main="", zlab="B:Diámetro interno", ylab="Aditivo", xlab="Tiempo",sub="Diámetro interno~B+C+BC", theta = 120, phi = 20) ¾ contourPlot(B, C, datos.VR, data = odf, main="") 1.0 > +8.5 > +9 > +9.5 > +10 > +10.5 > +11 > +11.5
11.0
et ro inte B:D iám
10.5
0.5
9.5
0.0
-1.0 9.0
-0.5 mp o
-1.0
0.0
-0.5 Ad 0.0 it ivo
0.5
-0.5
Tie
rno
C : Aditivo
10.0
> +8.5 > +9 > +9.5 > +10 > +10.5 > +11 > +11.5
0.5 1.0 1.0
-1.0 -1.0
Diámetro interno~B+C+BC
-0.5
0.0 B : Tiempo
0.5
1.0
296
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
III.27.4.2. Diseño con mezclas El diseño de experimentos con mezclas (MDOE, Mixture Design of Experiments) trata de determinar la combinación óptima de elementos (factores) que produce la respuesta deseada utilizando el número mínimo de pruebas experimentales. En general el número de combinaciones es excesivamente alto para que se pueda visualizar razonablemente el resultado y se intenta solucionar ese problema utilizando técnicas diversas. Scheffé (1963) propone el diseño centroide simplex, que incluye observaciones de mezclas en donde los componentes aparecen en igual proporción, y consiste en 2q-1 puntos correspondientes a q permutaciones de (1,0, …, 0) o mezclas de los q componentes puros, las (q:2) permutaciones (1/2,1/2,0,…,0) o mezclas binarias, las mezclas ternarias, y así sucesivamente. Cornell (1975; 2002) profundiza en estos diseños con nuevas propuestas, y utiliza un conocido ejemplo que emplearemos en este apartado. Se trata del diseño de una mezcla de polímeros para un tejido con aplicaciones marinas. La propiedad evaluada es el alargamiento del hilo o elongación, y se consideran tres componentes en la mezcla: polietileno de baja densidad (LDPE), poliestireno y polipropileno. El objetivo es conseguir la mezcla más idónea para obtener la máxima elongación. Los datos están en el archivo Elongación.csv. Las instrucciones están en el script III.55.R. Para generar el experimento adecuado, con el mínimo número posible de unidades muestrales, se usa la función «mixDesign()» del paquete “qualityTools” (Roth, 2012). Los dos primeros argumentos «p» y «n» indican el número de factores o componentes de la mezcla (3) y el grado del modelo a utilizar, es decir el número de componentes que queremos mezclar como máximo en cada ensayo (ponemos 2), respectivamente. Un grado más elevado en el argumento «n», en este caso tres, valor máximo posible ya que solo se mezclan tres componentes, encarecerá el experimento al aumentar el número de ensayos, pero a cambio se obtendrá una mejor resolución en el resultado. Los argumentos «center» y «axial» se utilizan para añadir puntos centrales o axiales adicionales respectivamente. Con «replicates» se indica el número de réplicas de los diferentes puntos utilizados, siguiendo el orden (center, axial, pureBlend, BinaryBlend, p-3 blend, p-2 blend, p-1 blend). En nuestro ejemplo –ya se ha dicho que no tenemos center ni axial– se indica que las mezclas puras, con un solo componente, tendrán 2 réplicas, y las binarias, con dos componentes, 3 réplicas; se suelen utilizar en la práctica valores pequeños como los del ejemplo.
¾ odm <- mixDesign(p=3,n=2, center = FALSE, axial = FALSE, randomize = FALSE, replicates = c(1,1,2,3)) ¾ names(odm) <- c("Polietileno", "Poliestireno", "Polipropileno") ¾ odm El diseño resultante tiene 15 puntos o ensayos, con mezclas de un solo componente (1-blend) o dos componentes (2-blend). Los componentes son A, B, y C, que aparecen solos (valor 1) o mezclados en partes iguales (0,5). La variable de resultado y aparece de momento con valores perdidos NA. Ahora es necesario realizar los 15 ensayos y obtener el valor de la variable de resultado, elongación, para cada uno de ellos, de modo que pueda ser incorporada al modelo. Los valores pueden ser incorporados directamente en el orden exacto creando una variable, o bien leídos de un archivo externo. Es necesario que el orden de los datos en el archivo sea exactamente el que se muestra en el diseño. Es decir, los
GRÁFICOS AVANZADOS
297
dos primeros datos son las dos réplicas puras con polietileno, los dos siguientes replicas de la mezcla de polietileno y poliestireno, y así sucesivamente.
A continuación se cargan los datos y se introducen en el diseño factorial para obtener los resultados del modelo.
¾ datos<-read.csv2("Elongación.csv", header=TRUE, encoding= "latin1") ¾ response(odm) <- datos$elongacion ¾ odm
En la tabla anterior se puede ver para que mezclas se obtienen los valores más altos y más bajos de elongación. Sin embargo, como en el diseño realizado solamente se utilizaron mezclas de dos compuestos y en una proporción al 50% de ambos, no es posible ver que elongación se obtiene para mezclas en otras proporciones diferentes al 50% y considerando los tres elementos. Esta información se puede observar gráficamente, ya que una vez completado el objeto de diseño de mezclas «odm», se pueden utilizar las funciones gráficas del paquete “qualityTools” (Roth, 2012), como son «contourPlot3()» y «wirePlot3()». En
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
298
ambas funciones con el argumento «form» se indica la fórmula o función ajustada: "linear", "quadratic", "fullCubic", "specialCubic" o bien otra fórmula indicada expresamente.
¾ contourPlot3(A, B, C, datos$elongacion, data = odm, form = "quadratic", xlab="Polietileno", ylab= "Poliestireno", zlab="Polipropileno", main="", cex.axis=1, col.text="black", border="white") ¾ title(main="Efecto sobre la elongación",cex.main=2) ¾ wirePlot3(A, B, C, datos$elongacion, data=odm, form="quadratic", theta=170, xlab="Polietileno", ylab= "Poliestireno", zlab="Polipropileno", main="Efecto sobre la elongación") El primer gráfico muestra mediante curvas de nivel y un código de colores el resultado de las mezclas posibles. El valor de la variable elongación aumenta hacia la derecha, y disminuye hacia la izquierda. Si buscamos la máxima elongación (valores superiores a 18), la combinación óptima será 70% polipropileno y 30% polietileno. Por el contrario, si buscamos la mínima elongación, la mezcla adecuada será 90% poliestireno y 10% polipropileno.
Efecto sobre la elongación Polietileno
> +9 > +10 > +11 > +12 > +13 > +14 > +15 > +16 > +17 > +18
0.9 0.8 0.7 0.6 0.5 0.1
0.1 0.2
0.4 0.3 0.3 0.4
0.4 0.3
0.5 0.6
0.5 0.2
0.7 0.8 0.9
Poliestireno
0.2
0.6 0.7
0.1
0.8 0.9
Polipropileno
En el segundo gráfico tridimensional se observa la respuesta estimada para cada combinación de la mezcla de los tres elementos. De nuevo se comprueba que los valores más altos de elongación se obtienen con proporciones elevadas de polipropileno, y los más bajos con poliestireno. Sin embargo, para definir la proporción óptima quizás es más útil el gráfico anterior.
GRÁFICOS AVANZADOS
299
Efecto sobre la elongación
> +9 > +10 > +11 > +12 > +13 > +14 > +15 > +16 > +17 > +18
Polipropileno Poliestireno
Polietileno
III.27.4.3. Diseños Taguchi Algunos diseños experimentales, como los diseños factoriales fraccionales y otros diseños específicos fueron popularizados por Taguchi en su aplicación al control de calidad, y se conocen en general como diseños Taguchi. Un diseño factorial completo 2k incluye k factores de dos niveles, y requiere todas las combinaciones posibles (2k) de esos factores. Además es necesario incluir en el diseño la variabilidad residual, para lo que generalmente se utilizan dos réplicas por cada combinación, en cuyo caso el número de ensayos es 2k+1. Si el número de niveles de cada factor es n > 2, el número de ensayos sería 2nk, un número que crece rápidamente haciéndose a menudo inviable. El análisis del diseño factorial completo permite estimar los efectos simples y todas las interacciones (dobles, triples, etc.). Como en general las interacciones de más de dos factores no suelen tener interés, es posible simplificar el diseño, reduciendo considerablemente el número de ensayos, cuando solo queremos analizar los efectos individuales, o a lo sumo las interacciones de dos factores. Estos diseños simplificados se denominan diseños fraccionales, y han sido estudiados en la literatura especializada para conseguir la máxima capacidad de análisis con el mínimo esfuerzo experimental (mínimo tamaño de muestra). También se han encontrado diseños con tamaño pequeño que permiten combinar varios factores de diferente número de niveles, que no son técnicamente diseños fraccionales. Hay, por lo tanto, dos tipos de diseños Taguchi: simples, en los que todos los factores tienen el mismo número de niveles, y mixtos, en los cuales los factores tienen diferente número de niveles. La función «taguchiDesign()» del paquete “qualityTools” (Roth, 2012), facilita la aplicación y análisis de la mayoría de los diseños utilizados. Solo tenemos que elegir el adecuado en la lista que se muestra a continuación. El número
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
300
que sigue a la L es el número de ensayos, y el siguiente o siguientes, el número de niveles de cada factor ("L18_2_3" es un experimento con 18 ensayos o medidas que combina factores con 2 y 3 niveles):
"L4_2": 3 factores con 2 niveles "L8_2": 7 factores con 2 niveles "L9_3": 4 factores con 3 niveles "L12_2": 11 factores con 2 niveles "L16_2": 16 factores con 2 niveles "L16_4": 16 factores con 4 niveles "L18_2_3": 1 factor con 2 niveles y 7 factores con 3 niveles "L25_5": 6 factores con 5 niveles "L27_3": 13 factores con 3 niveles "L32_2": 32 factores con 2 niveles "L32_2_4": 1 factor con 2 niveles y 9 factores con 4 niveles "L36_2_3_a": 11 factores con 2 niveles y 12 factores con 3 niveles "L36_2_3_b": 3 factores con 2 niveles y 13 factores con 3 niveles "L50_2_5": 1 factor con 2 niveles y 11 factores con 5 niveles "L8_4_2": 1 factor con 4 niveles y 4 factores con 2 niveles "L16_4_2_a": 1 factor con 4 niveles y 12 factores con 2 niveles "L16_4_2_b": 2 factores con 4 niveles y 9 factores con 2 niveles "L16_4_2_c": 3 factores con 4 niveles y 6 factores con 2 niveles "L16_4_2_d": 5 factores con 4 niveles y 2 factores con 2 niveles "L18_6_3": 1 factor con 6 niveles y 6 factores con 3 niveles
Supongamos que queremos averiguar el efecto, sobre una variable dependiente, de cuatro factores cada uno de los cuales tiene tres niveles. Utilizaremos el diseño “L9_3”, con el que solo necesitaremos 9 ensayos, en lugar de los 2x34 = 162 de un experimento factorial completo con dos réplicas. Las instrucciones están en el script III.56.R. En la función «taguchiDesign()» al poner «randomize=FALSE» lo que se hace es que salga siempre el mismo diseño factorial. Si se escoge la opción «TRUE» saldrán distintos diseños factoriales cada vez que se haga el análisis.
¾ odt <- taguchiDesign("L9_3", randomize=FALSE) ¾ values(odt) <- list(A = c(700, 750, 800), B = c(10, 15, 20), C = c("M1", "M2", "M3"))
¾ names(odt) <- c("TEMPERATURA", "TIEMPO", "MATERIAL", "MAQUINA") ¾ summary(odt) En la información que se obtiene sobre los factores, que se muestra en la tabla de la siguiente página, se indican los niveles que corresponden a cada código (1,2,3), y las combinaciones adecuadas para cada ensayo. Con esa información se realizan los nueve ensayos y se obtiene el valor de la variable resultado, datos que están en el archivo Taguchi.csv con el nombre de variable «Diámetro». Como en los ejemplos anteriores, utilizamos la función «response()» para asignar los valores de la variable de resultado, y emplearemos la función gráfica «effectPlot()» para visualizar los efectos.
¾ datos<-read.csv2("Taguchi.csv",header=TRUE,encoding="latin1") ¾ response(odt) <- datos$Diámetro ¾ effectPlot(odt, col=2, main="", ylab="Media del diámetro")
9.2
9.2
9.6
9.8 10.0
1
2
C: MATERIAL
3
9.8 10.0
2
9.6
1
9.4
Media del diámetro
9.4
Media del diámetro
9.2
9.2
9.6
9.8 10.0
9.4
9.6
9.8 10.0
Media del diámetro
9.4
Media del diámetro
GRÁFICOS AVANZADOS
3 1
A: TEMPERATURA
1
301
2
2
D: MAQUINA 3
B: TIEMPO
3
302
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Observamos en la gráfica como los efectos de los factores temperatura y máquina no parecen importantes. Sin embargo, a mayor tiempo se produce un diámetro mayor, y el material 1 da lugar a valores más elevados del diámetro (al contrario que el material 3). Por último, para valorar la significación de estos efectos podemos utilizar un ANOVA.
¾ ajuste <- lm(datos$Diámetro ~ A+B+C+D, data = odt) ¾ summary(ajuste)
Los resultados del ANOVA muestran que, efectivamente, los factores A (temperatura) y D (máquina) no son significativos, no influyen en la variable de resultado, pero sí lo son B (tiempo) y C (material).
III.27.5. CONTROLAR Esta fase consiste en planificar, documentar e implementar convenientemente los controles necesarios para asegurar el mantenimiento de la calidad, utilizando los resultados obtenidos en las fases anteriores. Se debe cuantificar la mejora conseguida en los resultados, establecer los mecanismos y protocolos de medición y seguimiento de los procesos, las señales de alarma o avisos de desviación que indican que es necesaria alguna actuación, y las acciones a realizar en esos casos. Todo ello debe ser adecuadamente documentado. En la fase de control se utilizan los Gráficos de Shewhart. Estos gráficos permiten observar el seguimiento de un proceso, y conocer si se desarrolla de forma adecuada o se desvía de lo esperado y, en ese caso, ayudan a encontrar el problema y a aplicar la solución correcta. El proceso debe mantener el valor medio de la variable objetivo dentro de estrechos límites, para lo cual es útil representar la media en su evolución temporal. También debe mantener la variabilidad dentro de límites razonables, para lo que se suele representar la desviación típica o el rango. Aunque la desviación típica es considerada habitualmente el mejor indicador de variabilidad, en el
GRÁFICOS AVANZADOS
303
ámbito del control de calidad se utiliza frecuentemente el rango o recorrido, diferencia entre valor máximo y mínimo en una muestra, por su facilidad de cálculo. Existen gráficos para variables cuantitativas y cualitativas, y la función «qcc()» del paquete “qcc” (Scrucca, 2012) contiene los más utilizados. Dentro de la función con el argumento «type» se puede especificar el tipo de gráfico, como se muestra en la Tabla III.1 Tabla III.1. Tipos de gráficos que se pueden especificar en el argumento «type» de la función «qcc()».
Tipo
Estadístico representado
"xbar"
Media
"R"
Rango
"S"
Desviación típica
"xbar.one" Media "p" "np" "c" "u" "g"
Proporción Recuento Recuento Recuento Recuento
Descripción del gráfico Medias de una variable en un proceso contínuo Rangos de una variable en un proceso contínuo Desviación típica de una variable contínua Datos uno a uno en un proceso contínuo Proporción de unidades defectuosas Número de unidades defectuosas Defectos por unidad Promedio de defectos por unidad Número de no eventos entre eventos
III.27.5.1. Variables En el archivo Shewhart1.csv hay datos de la longitud de una pieza metálica, cuyo valor nominal debe ser 80 mm, que consisten en 300 valores correspondientes a 60 muestras de 5 unidades. La variable «Medida» indica el valor, y «Muestra» el conjunto al que pertenece. La variabilidad del proceso de fabricación hace que cada pieza tenga una medida próxima al valor nominal, dentro de márgenes razonables, pero podrían ocurrir desajustes que provoquen un porcentaje de piezas defectuosas inadmisible. Las instrucciones están en el script III.57.R. La función «qcc.groups()» del paquete “qcc” (Scrucca, 2012) organiza los datos convenientemente, de acuerdo con la estructura de muestras citada anteriormente. La función «qcc()» realiza el gráfico. Construimos en primer lugar el gráfico de la media con los valores de las 30 primeras muestras. Con el argumento «center» se define el tamaño objetivo que debe tener la pieza.
¾ ¾ ¾ ¾
datos<-read.csv2("shewhart1.csv",header=TRUE,encoding="latin1") attach(datos) Medida <- qcc.groups(Medida, Muestra) qcc(Medida[1:30,], type="xbar", center=80, ylab="Length (mm)", xlab= "Group", title="Measurements from 1 to 30")
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
304
El gráfico muestra que el proceso parece estar bajo control. Los valores medios de las muestras de cinco unidades oscilan aleatoriamente en torno al valor nominal. Los límites de control en el gráfico, LCL y UCL, corresponden a 3 veces la desviación típica de la media (solo el 2,67 por mil de los valores es de esperar que estén fuera de ellos), y se calculan con los propios datos. La leyenda del gráfico nos indica además que no existen valores fuera de límites (Number beyond limits), y que no existen rachas (Number violating runs). Una racha es un conjunto de 5 o más valores consecutivos por encima o por debajo de la media, y podría indicar un desajuste en el proceso. El número de elementos que define una racha se puede modificar (por ejemplo 7), antes de realizar el gráfico, con la función «qcc.options(run.length=7)».
80.15
Measurements from 1 to 30
80.00
CL
79.85
79.90
79.95
Length (mm)
80.05
80.10
UCL
LCL 1
3
5
7
9
11
13
15
17
19
21
23
25
27
29
Group Number of groups = 30 Center = 80 StdDev = 0.1063495
LCL = 79.85732 UCL = 80.14268
Number beyond limits = 0 Number violating runs = 0
Como los límites de control se calculan en el gráfico utilizando los propios datos, es necesario evitar que un desajuste gradual o progresivo adapte los límites a cualquier funcionamiento irregular, y el gráfico no detecte las anomalías. Para ello podemos utilizar en el cálculo de los límites una parte de la muestra de la que sabemos que está bajo control, y que no modifique esos límites al añadir nuevos datos. Esto es lo que hace el segundo gráfico, en el que conservamos la
GRÁFICOS AVANZADOS
305
muestra ya utilizada (30 grupos de 5) y añadimos ahora los grupos restantes, del 31 al 60. Los nuevos datos se añaden con el argumento «newdata».
¾ qcc(Medida[1:30,], type="xbar", center=80, ylab="Length (mm)", xlab= "Group", title="Measurements from 1 to 60", newdata=Medida[31:60,]) En el nuevo gráfico se observa que, manteniendo los límites de control del gráfico anterior, se ha producido un valor fuera de los límites, un desajuste ocasional, que en principio no tiene importancia, ya que el proceso posterior parece seguir bajo control.
Measurements from 1 to 60 New data in medida[31:60, ]
80.2
Calibration data in Medida[1:30, ]
80.1 80.0
CL
79.9
Length (mm)
UCL
LCL 1
4
7
11
15
19
23
27
31
35
39
43
47
51
55
59
Group Number of groups = 60 Center = 80 StdDev = 0.1063495
LCL = 79.85732 UCL = 80.14268
Number beyond limits = 1 Number violating runs = 0
Otro gráfico de interés es el que representa el rango. Un rango excesivamente alto indica una variabilidad grande que puede conducir a un número elevado de elementos defectuosos en el producto. Para ello, simplemente hay que especificar «type="R"».
¾ qcc(Medida[1:30,], type="R", ylab="Length (mm)", xlab="Group", title= "Measurements from 1 to 60", newdata=Medida[31:60,])
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
306
En el nuevo gráfico se observa que la variabilidad se mantiene bajo control. La presencia de rachas no suele ser preocupante cuando se trata de valores por debajo del rango medio (rachas por debajo de la línea contínua horizontal).
Measurements from 1 to 60 Calibration data in Medida[1:30, ]
New data in medida[31:60, ]
0.3 0.2
CL
0.0
0.1
Length (mm)
0.4
0.5
UCL
LCL 1
4
7
11
15
19
23
27
31
35
39
43
47
51
55
59
Group Number of groups = 60 Center = 0.2473688 StdDev = 0.1063495
LCL = 0 UCL = 0.5230539
Number beyond limits = 0 Number violating runs = 12
Por último, también se puede utilizar con el mismo fin la desviación típica, una medida más apropiada en general para medir la variabilidad, ya que no está tan influenciada por los valores atípicos. Para obtener este nuevo gráfico simplemente se cambia de nuevo el argumento «type="S"».
¾ qcc(Medida[1:30,], type="S", ylab="Length (mm)", xlab="Group", title= "Measurements from 1 to 60", newdata=Medida[31:60,]) El aspecto del gráfico con la desviación típica, como se puede observar, es muy similar al de los gráficos construidos con el rango; el número de rachas (12) es el mismo en ambos casos.
GRÁFICOS AVANZADOS
307
Measurements from 1 to 60 Calibration data in Medida[1:30, ]
New data in medida[31:60, ]
0.10
CL
0.00
0.05
Length (mm)
0.15
0.20
UCL
LCL 1
4
7
11
15
19
23
27
31
35
39
43
47
51
55
59
Group Number of groups = 60 Center = 0.1017448 StdDev = 0.1082408
LCL = 0 UCL = 0.2125447
Number beyond limits = 0 Number violating runs = 12
III.27.5.2. Atributos En ocasiones la variable objetivo no es cuantitativa (diámetro, temperatura, etc.) sino cualitativa, como por ejemplo elemento defectuoso o no defectuoso. En estos casos puede utilizarse con el mismo fin de seguimiento o control del proceso un gráfico de proporción. Utilizaremos un ejemplo en el que el producto consiste en unidades de fruta (kiwis) envasadas en cajas de 60 unidades. La inspección determina el número de unidades que presentan algún defecto de cualquier tipo. Interesa mantener el porcentaje de unidades defectuosas por debajo de un límite admisible. Se muestrea una caja cada hora elegida al azar. Los datos están en el archivo Shewhart2.csv, y consisten en una variable «Tamaño», que indica el tamaño de las muestras (60 unidades –una caja completa– en todos los casos), y otra «Defectos» que muestra el número de unidades defectuosas. El número de cajas revisadas es 50. Las instrucciones están en el script III.58.R. De nuevo se utiliza la función «qcc()» del paquete “qcc” (Scrucca, 2012). Inicialmente se construirá un gráfico «p» para los 30 primeros elementos, al igual
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
308
que en el ejemplo con las variables. Para este tipo de gráfico se utiliza el argumento «sizes» para especificar los datos a representar.
¾ qcc(Defectos[1:30], sizes=Tamaño[1:30], type="p", title="Defective parts") El gráfico muestra la secuencia de proporciones de elementos defectuosos para el conjunto de datos. Los límites de control se establecen automáticamente a partir de los datos, en función de su propia variabilidad. En este ejemplo no se observa ningún elemento fuera de los límites, y la presencia de rachas esporádicas no es preocupante.
0.14
Defective parts
0.10 0.08 0.06 0.04
CL
0.00
0.02
Group summary statistics
0.12
UCL
LCL 1
3
5
7
9
11
13
15
17
19
21
23
25
27
29
Group Number of groups = 30 Center = 0.05111111 StdDev = 0.2202244
LCL = 0 UCL = 0.1364036
Number beyond limits = 0 Number violating runs = 1
Una vez comprobado que el proceso está bajo control, construimos otro gráfico, que mantiene los límites obtenidos con los 30 primeros elementos de la muestra, y comprueba si el proceso con otra muestra adicional, en este caso formada por las 20 últimas cajas, está también controlado. Para incorporar los nuevos datos se utilizan los argumentos «newdata» y «newsizes».
¾ qcc(Defectos[1:30], sizes=Tamaño[1:30], type="p", newdata= Defectos[31:50], newsizes=Tamaño[31:50], title="Defective parts")
GRÁFICOS AVANZADOS
309
Como se puede observar, el proceso continúa razonablemente bajo control, con una evolución similar a la muestra previa.
Defective parts 0.14
Calibration data in Defectos[1:30]
New data in Defectos[31:50]
0.10 0.08 0.06 0.04
CL
0.00
0.02
Group summary statistics
0.12
UCL
LCL 1
4
7
10 13 16 19 22 25 28 31 34 37 40 43 46 49 Group
Number of groups = 50 Center = 0.05111111 StdDev = 0.2202244
LCL = 0 UCL = 0.1364036
Number beyond limits = 0 Number violating runs = 1
III.28. Minería de datos Se denomina minería de datos a la combinación de diferentes técnicas estadísticas con herramientas y conceptos procedentes del campo de las redes neuronales, para el análisis de conjuntos de datos muy grandes y complejos. Los procedimientos y algoritmos utilizados permiten la descripción sistemática de los datos para mejorar el conocimiento de su estructura y sus características principales, la aplicación semi-automática de diversas técnicas de análisis multivariante, o la construcción sencilla de modelos. El paquete “rattle” (R Analytical Tool To Learn Easily) (Williams, 2009; 2012) es una aplicación gráfica de minería de datos desarrollada para introducir los elementos básicos de la minería de datos y su empleo por usuarios no expertos. Combina numerosas funciones y paquetes de R a través de un GUI (Interfaz Gráfico de Usuario) específico. Esos paquetes son instalados y cargados automá-
310
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
ticamente cuando se necesitan sin que el usuario tenga que conocerlos previamente. El paquete “rattle” proporciona, además, las herramientas adecuadas para la introducción de datos con formatos diversos y la salida de resultados gráficos, numéricos o de texto. Una vez instalado se inicia rattle desde R con las siguientes instrucciones:
¾ library(rattle) ¾ rattle()
En los siguientes apartados veremos su funcionamiento y algunas utilidades con un ejemplo. A lo largo de la ejecución, R irá instalando y cargando, nos preguntará en cada ocasión si queremos hacerlo, todos los paquetes adicionales requeridos.
III.28.1. CARGAR LOS DATOS Lo primero que debemos hacer es leer los datos. Lo más seguro suele ser leer datos con un formato estándar, como csv (datos en texto separados por coma o punto y coma), un formato que se puede generar fácilmente desde aplicaciones diversas (como Excel, por ejemplo) y que es compatible con casi cualquier sistema operativo. Para leer el archivo de datos se selecciona la pestaña «Datos» en el menú principal. Al pulsar el botón «Archivo», aparece la ventana que se muestra a continuación, donde buscaremos –en la carpeta adecuada- el archivo Deudas.csv. El menú nos permite elegir la carpeta mediante un explorador, y en la parte inferior derecha del menú marcaremos la opción «Archivos CSV». Finalmente pulsamos «Abrir».
GRÁFICOS AVANZADOS
311
En «Separador» hay que poner «;» y en «Decimal» se pone «,». Hay que tener seleccionado «Encabezado». A continuación pulsamos «Ejecutar» en la parte superior izquierda del menú principal, apareciendo la siguiente ventana.
El archivo Deudas.csv contiene 100 casos, clientes de una entidad bancaria, y 9 variables, cinco de ellas categóricas y cuatro cuantitativas:
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
312
Edad: menos de 30, entre 30 y 40, más de 40. Formación: elemental, bachillerato y estudios universitarios. Empleo: antiguedad en el empleo; menos de 5 años, entre 5 y 10 y más de 10. Residencia: antiguedad en la actual; menos de 5 años, entre 5 y 10 y más de 10. Ingreso: volumen de ingresos. Deud_ing: relación (%) entre deudas e ingresos. Deud_tarj: importe de las deudas por tarjetas de crédito. Deud_otr: importe de otras deudas. Impago: si ha tenido o no impagos.
La estructura de variables aparece en la ventana central, como se muestra en la ventana anterior. Ahora debemos elegir nuestra variable objetivo. Nuestros datos tienen –para la entidad bancaria– un objetivo general: averiguar por qué se producen los impagos, e intentar anticipar el posible impago de un cliente. Para ello es necesario profundizar en el conocimiento de las relaciones entre la variable impago y las restantes. Por tanto, la variable objetivo es «Impago», y la marcaremos como «Destino». Las demás serán variables de «Entrada» o variables explicativas. Solamente se permite una variable objetivo, y cada vez que hagamos un cambio debemos pulsar «Ejecutar». Una vez seleccionada la variable objetivo y las variables explicativas podemos explorar los datos.
III.28.2. EXPLORAR En el menú principal pulsamos la pestaña «Explorar» y, sin cambiar las opciones por defecto, pulsamos «Ejecutar». Aparecerá un resumen descriptivo, que muestra para las variables categóricas los niveles y la tabla de frecuencias, y para las cuantitativas el mínimo, máximo, cuartiles, media, y mediana, lo cual se muestra en la siguiente ventana.
A continuación seleccionamos, dentro de la misma opción «Explorar», «Distribuciones» y pulsamos «Ejecutar», sin modificar las opciones por defecto.
GRÁFICOS AVANZADOS
313
Los gráficos que aparecen muestran la relación o correlación entre todas las variables explicativas, que pueden ser asociadas dos a dos. Para las variables cuantitativas se representa por defecto un histograma y para las categóricas un diagrama de barras. En la intersección entre variables cuantitativas se representa el correspondiente diagrama de dispersión, con una curva de ajuste y el coeficiente de correlación lineal. Por ejemplo, analicemos la relación entre deudas e ingresos. La variable «Deud_ing» es una variable asimétrica (asimetría positiva) que está asociada positivamente (r = 0,64) con otras deudas «Deud_otr»de forma aproximadamente lineal, y que no parece estar relacionada con ninguna de las variables categóricas (edad, formación y empleo). 2.0
3.0
0
10 20 30
0 2 4 6 8 3.0
1.0
0.20
0 .061
-0.06 6
-0.16
0.10
-0 .08 6
0 .00 072
-0.0 72
0.18
-0.00 35
-0.12
0.38
0.64
3.0
1.0
-0.13
2.0
Edad
10 20 30
1.0
Empleo
2.0
3.0
1.0
2.0
Formaci.f3.n
0
Deud_ing
0
0.63
4
8
Deud_tarj
0 2 4 6 8
Deud_otr
1.0
2.0
3.0
1.0
2.0
3.0
0
4
8
Si pulsamos en la pestaña “Diagrama de caja” en las cuatro variables numéricas y pulsamos de nuevo «Ejecutar», obtenemos nuevos gráficos.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
314
Se muestra la relación entre la variable objetivo «Impago» y las variables numéricas, a través de diagramas de caja, para el conjunto de la muestra y para cada uno de los dos niveles (si/no) de impago. Ahora podemos apreciar que los impagos parecen relacionados con un elevado nivel de deudas/ingresos, y con un bajo nivel de ingresos.
Deud_ing
100
Ingreso
0
5
50
10 15 20 25 30 35
Distribución de Deud_ing (muestra) por Impago
150
Distribución de Ingreso (muestra) por Impago
All
No
Si
All
No
Si
Distribución de Deud_otr (muestra) por Impago
6 2
4
Deud_otr
6 4
0
0
2
Deud_tarj
8
8
10
10
Distribución de Deud_tarj (muestra) por Impago
All
No
Si
All
No
Si
Como se muestra en la siguiente ventana, es posible elegir diferentes tipos de gráficos para cada una de las variables, en esta fase exploratoria.
GRÁFICOS AVANZADOS
0.8 0.6 0.4
All No Si
0
0.0
0.2
Proporción d x
40 20
Frecuencia
60
Todos No Si
Distribución de Deud_tarj (muestra) por Impago 1.0
Distribución de Deud_ing (muestra) por Impago
315
0
10
20
30
40
0
2
Deud_ing
4
6
8
10
Deud_tarj
Distribución de Edad (muestra) por Impago
Mosaico de Empleo (muestra) por Impago menos de 5
mas de 10
entre 5 y 10
No
entre 30 y 40
mas de 40
Todos No Si 5
10
15
20
25
Si
Edad
Impago
menos de 30
Empleo
III.28.3. PRUEBAS Una vez explorados los datos es posible realizar pruebas sencillas, como contrastes de bondad de ajuste para ver si los datos se ajustan a una distribución Normal (test de Kolomogorov-Smirnov), pruebas paramétricas (t-test) y no paramétricas de contrastes de homogeneidad (test de Wilcoxon de suma de rangos), correlaciones, etc. (véase Guisande y col., 2011). Para ello se selecciona la pestaña «Prueba» y, dentro del menú que aparece, se selecciona el test y la variable a la que se le va a realizar la prueba. Por ejemplo, seleccionamos la variable «Ingreso», a la cual se realiza un test de la t para ver si hay diferencias significativas entre los dos grupos que define la variable «Impago». Los resultados muestran que hay diferencias significativas entre los dos grupos (p = 0,0026), con una media de ingresos de 52,35 para el grupo de no impagos y de 33,24 para el grupo de si impagos.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
316
III.28.4. MODELOS Después de explorar los datos y realizar pruebas sencillas, el siguiente paso es realizar análisis más complejos. Por ejemplo, en la pestaña «Explorar», se selecciona «Componentes principales», y pulsamos «Ejecutar».
Obtenemos el gráfico biplot, con la representación de los objetos (clientes de la entidad bancaria) como puntos en el plano de las dos primeras componentes principales, y las variables como vectores. El ángulo que forman muestra la correlación (más correlación cuanto más agudo el ángulo). En el ejemplo esta correlación es escasa, y la varianza explicada por la primera componente (se ve en la ventana principal) es solamente el 56,3%. Si se arrastra este gráfico se puede ver el otro gráfico de barras que hay detrás, con la contribución de cada eje. Componentes principales Deudas.csv 0
5
Ingreso
1
5
0.4
-5
0.2
3 5734
0.0 37
-5
-0.2
Deud_otr
67 -0.4
PC2
40
0
889333 65 74 14 87 78 17 92 1160 22 253 71 79 70 43 91 20 13 55 61 42 97 25 73 3298 30 84 82 51 29 468327 3823 698 625689 10 66 81 76 852650 95 80 28 31 86 21 75 39 752 48
eud_tarj
Deud_ing
-0.4
-0.2
0.0 PC1
0.2
0.4
GRÁFICOS AVANZADOS
317
Posteriormente elegimos la pestaña «Cluster», indicamos 2 en «Número de clústers» y manteniendo las restantes opciones por defecto pulsamos «Ejecutar». A continuación pulsamos el botón «Discriminante» para obtener el gráfico y resultados del análisis.
Discriminant Coordinates Deudas.csv
2
2
0
1 2 1 111 1 1 111 1 1 1 1 1 1 2 1 111 11 1 1 11 1 1 11 1 1 11 1 1 11 1 11 11 1 11 1 1 1 1 1 11
1
2 2
2 2 2
2
222
2
-4
-2
dc 2
1
1 2
4
6
8
10
dc 1
El gráfico parece mostrar la existencia de varios grupos separados; aunque hemos indicado dos grupos, con la esperanza de que separe a los clientes que tienen impagos de los que no los tienen, en el gráfico parece haber más de dos grupos homogéneos, quizás cuatro. No podemos asociar la pertenencia a grupos con los niveles de impago con este gráfico, y debemos aplicar otra técnica.
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
318
Se elige ahora la opción «Modelo» en el menú operativo, y manteniendo las opciones por defecto pulsamos de nuevo «Ejecutar». El modelo construido, en este caso un árbol de clasificación, está diseñado para explicar la variable objetivo. Pulsamos «Dibujar», a la derecha del menú, para ver el árbol.
Árbol de decisión Deudas.csv $ Impago
Deud_ing < => 8.05
2
3
No 41 obs
Si 29 obs
100%
86.2%
El árbol es muy simple, ya que el algoritmo ha encontrado solamente una variable explicativa, la relación entre deudas e ingresos –el resto de las variables no parecen ayudar a decidir el impago– y encuentra también el nivel de corte adecuado: 8,05%. Con ese criterio es capaz de predecir el 100% de los clientes que no tienen impagos, clientes “seguros” en los que la entidad bancaria podrá confiar, y el 86,2% de los que tienen impagos. Según estos resultados, cuando un cliente tiene un nivel de endeudamiento por encima del 8,05% la entidad no deberá concederle préstamos, ya que la probabilidad de impago es muy elevada. Finalmente, en la pestaña «Registro» del menú operativo se conservan todas las instrucciones de R que la aplicación ha ido generando. Pueden copiarse para documentar el trabajo realizado, y sobre todo para reproducir los resultados, ya que esas instrucciones pueden ser utilizadas directamente desde R, sin que sea necesario emplear este paquete, es decir, incorporarlas a un script y realizar el proceso como hemos mostrado a lo largo del libro con otros gráficos.
CAPÍTULO IV MAPAS
IV.1. Áreas administrativas La función «adarea()» del paquete “mapq” permite realizar un mapa de cualquier zona del mundo con una alta resolución. Este paquete está incluido en el conjunto de archivos que se descargan de la página web que se mencionó en el Capítulo I. Para instalarlo simplemente hay que ir en el menú principal a «Paquetes» Ö «Instalar paquetes(s) a partir de archivos zip locales…» y seleccionar el archivo mapq.zip, el cual está en la carpeta del Capítulo IV.
Las instrucciones del primer ejemplo están en el script IV.1.R. En el primer mapa se observa que simplemente es necesario poner en el argumento «Area» el nombre de la zona que se quiere representar. Los nombres de las diferentes áreas administrativas se pueden ver en la Tabla IV.1.
¾ library(mapq) ¾ data(World) ¾ adarea(Area="Philippines")
319
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
320
5
10
Latitud
15
20
Philippines
118
120
122
124
126
Longitud También es posible representar varias áreas administrativas a la vez como se observa en el segundo mapa del script.
¾ adarea(Area=c("Dominican Republic","Haiti"))
18.5 17.5
Latitud
19.5
Dominican Republic Haiti
-74
-73
-72
-71
-70
-69
-68
Longitud En el tercer mapa del script se observa que para representar todo el mundo simplemente hay que especificar «Area="World"».
¾ windows(18,9) ¾ adarea(Area=c("World"))
MAPAS
321
En el siguiente mapa se muestra como es posible modificar el color de fondo, tanto de la zona de mar con el argumento «colbg», como de la zona de continente con «colcon». En vez de la función «rgb()» se puede poner cualquier color de los mostrados en el Capítulo I.
¾ adarea(Area=c("Bahamas"), colbg=rgb(175,225,255, maxColorValue=255), colcon=rgb(200,225,150, maxColorValue=255))
24 23 22 21
Latitud
25
26
27
Bahamas
-80
-78
-76
Longitud
-74
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
322
También se puede seleccionar una latitud y longitud, como se muestra a continuación, donde se ve un área más pequeña de las Bahamas. Para ello, se introducen las longitudes y latitudes mínimas y máximas con los argumentos «minLon», «maxLon», «minLat» y «maxLat», respectivamente.
¾ adarea(Area=c("Bahamas"), colbg = rgb(175, 225, 255, maxColorValue= 255), colcon = rgb(200,225,150, maxColorValue=255), minLon = -78.1, maxLon= -77.4, minLat=23.6, maxLat=24.5)
24.0 23.6
23.8
Latitud
24.2
24.4
Bahamas
-78.1
-77.9
-77.7
-77.5
Longitud Esta alta resolución también se puede observar en el mapa de las desembocaduras de los ríos Amazonas y Tocantins en Brasil.
¾ adarea(Area=c("Brazil"), colbg=rgb(175, 225, 255, maxColorValue=255), colcon=rgb(200,225,150,maxColorValue=255), minLon=-52, maxLon=47.8, minLat=-2.5, maxLat=1.5, main="Desembocadura de los\n ríos Amazonas y Tocantins", cex.main=1.4)
MAPAS
323
-2
-1
Latitud
0
1
Desembocadura de los ríos Amazonas y Tocantins
-52
-51
-50
-49
-48
Longitud
Si se selecciona «Area="World"» y un determinado rango de latitud y longitud dentro del mundo, con el argumento «exclude» se puede especificar que unos determinados países se pongan con un color de fondo, que se especifica con «colexc», para así resaltar solamente el área que se desee, como por ejemplo en este caso Centro América.
¾ adarea(Area="World", minLon = -120, maxLon= -75, minLat=5, maxLat= 35, exclude=c("Cuba","Jamaica","United States", "Colombia", "Bahamas"), colexc="ivory1", main="Centro América",colcon="khaki", cex.main=1.4)
20 15 10 5
Latitud
25
30
35
Centro América
-120
-110
-100
Longitud
-90
-80
324
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Función adarea (paquete mapq) Area: área administrativa o vector con varias áreas. El listado con los nombres de las diferentes áreas se puede consultar en la Tabla IV.1. Para representar todo el mundo se especifica Area="World": Area="World". minLon, maxLon, minLat y maxLat: opcionalmente se puede delimitar la zona con las coordenadas geográficas del mapa especificando las longitudes y latitudes mínimas y máximas. colbg: color de fondo del mapa que corresponde al mar: colbg= rgb(255,255,255,maxColorValue=255). colcon: color de fondo del continente: colcon=rgb(200,200,200, maxColorValue =255). colf: color de las fronteras de las áreas: colf: "black". pro: si es TRUE se hace un cálculo automático para que los ejes de latitud y longitud sean proporcionales con la fórmula asp= 1/cos (latitud*pi/180): pro =TRUE. boxf: indica donde representar el marco y puede ser "plot", "figure", "inner", "outer" o "n" (no se pone marco): boxf = "plot". inc: porcentaje que se deja en los márgenes del mapa para que los límites x e y no sean exactamente los límites de las áreas seleccionadas y se deje un espacio en blanco: inc = 0.005. exclude: área administrativa o vector con varias áreas, que se pueden representar con otro color dentro del mapa cuando se usa la opción Area="World". colexc: color de fondo de las áreas que se especifican en exclude: colexc = "white". colfexc: color de las fronteras de las áreas que se especifican en exclude: colfexc: "black". Admite los argumentos generales axes, asp, lab, xlab, ylab, main, cex.main, cex.lab, cex.axis, bty, family, font.main, font.lab y font.axis. Tabla IV.1. Nombres de las diferentes áreas administrativas. Los datos de longitud y latitud usados en el paquete “mapq” fueron obtenidos de la página web http://www.diva-gis.org/.
Afghanistan American Samoa
Åland Islands
Albania
Algeria
Andorra
Angola
Anguilla
Argentina
Armenia
Aruba Bahamas Belarus
Antigua and Barbuda Australia Bahrain Belgium
Austria Bangladesh Belize
Bermuda
Bhutan
Bolivia
Azerbaijan Barbados Benin Bonaire, Sint Eustatius and Saba
Bosnia and Herzegovina
Botswana
Bouvet Island
Antarctica
Brazil
MAPAS
British Indian British Virgin Ocean Territory Islands Burkina Faso Burundi
Brunei Darussalam Cambodia
325 Bulgaria
Canada
Cape Verde
Chad Cocos Islands Congo, The Democratic Republic of the Croatia Czech Republic Dominican Republic Equatorial Guinea Falkland Islands
Chile Colombia
Cameroon Central African Cayman Islands Republic China Christmas Island Comoros Congo
Cook Islands
Costa Rica
Côte d'Ivoire
Cuba Denmark
Curaçao Djibouti
Cyprus Dominica
Ecuador
Egypt
El Salvador
Eritrea
Estonia
Ethiopia
Faroe Islands
Fiji
Finland
French Polynesia Georgia Greece Guam Guinea-Bissau
French Southern Territories Germany Greenland Guatemala Guyana
Honduras
Hong Kong
India Ireland Jamaica Kazakhstan Kuwait Lebanon Liechtenstein Macedonia Maldives
Indonesia Isle of Man Japan Kenya Kyrgyzstan Lesotho Lithuania Madagascar Mali
Martinique
Mauritania
France
French Guiana
Gabon Ghana Grenada Guernsey
Gambia Gibraltar Guadeloupe Guinea Heard Island and McDonald Islands Iceland Iraq Italy Jordan Kosova Latvia Libya Macao Malaysia Marshall Islands
Haiti Hungary Iran Israel Jersey Kiribati Laos Liberia Luxembourg Malawi Malta Mauritius
Mayotte
Mexico
Moldova Montserrat
Monaco Morocco
Mongolia Mozambique
Micronesia, Federated States of Montenegro Myanmar
326 Namibia New Caledonia Nigeria Northern Mariana Islands
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Nauru New Zealand Niue
Nepal Nicaragua Norfolk Island
Netherlands Niger North Korea
Norway
Oman
Pakistan
Palau
Palestina
Panama
Paraguay Poland
Peru Portugal
Réunion
Romania
Philippines Puerto Rico Russian Federation
Saint Helena, Ascension and Tristan da Cunha
Saint Kitts and Nevis
Saint Pierre and Miquelon
Samoa
San Marino
Santa Lucia
Saudi Arabia Sierra Leone
Senegal Singapore Solomon Islands
Serbia Sint Maarten
Sao Tome and Principe Seychelles Slovakia
Somalia
South Africa
South Georgia and the South Sandwich Islands
South Korea
South Sudan
Spain
Sri Lanka
Sudan
Suriname
Swaziland Taiwan Timor-Leste Trinidad and Tobago Turks and Caicos Islands
Sweden Tajikistan Togo
Switzerland Tanzania Tokelau
Svalbard and Jan Mayen Syria Thailand Tonga
Tunisia
Turkey
Turkmenistan
Tuvalu
Uganda
Ukraine
United Arab Emirates
United Kingdom
United States
Uruguay Venezuela Western Sahara
Uzbekistan Viet Nam Yemen
Vanuatu Virgin Islands Zambia
Slovenia
Papua New Guinea Pitcairn Islands Qatar Rwanda Saint Vincent and the Grenadines
United States Minor Outlying Islands Vatican Wallis and Futuna Zimbabwe
MAPAS
327
IV.2. Gráficos dentro de mapas Con la función «adarea()» mostrada anteriormente se puede representar cualquier mapa y luego, como se explica a continuación, incluir uno o varios gráficos. Sin embargo, usaremos el paquete “maptools” (Lewin-Koh y Bivand, 2012) para mostrar otra opción que tiene muchas funciones para hacer mapas. Una de estas herramientas es el archivo de datos “wrld_simpl”, en el cual están las coordenadas de las fronteras de los diferentes países. En el siguiente ejemplo se ubica en el mapa del Neotrópico la situación de varios puntos de muestreo en una zona del Amazonas. Los datos, que son las latitudes de los puntos de muestreo, están en el archivo Neotrópico.csv y las instrucciones en el script IV.2.R. Después de llamar a los paquetes necesarios y de cargar los datos de la posición geográfica de los puntos de muestreo, se carga el archivo de datos que tiene las coordenadas de las fronteras de todos los países del mundo con el argumento «data(wrld_simpl)». Posteriormente se hace un gráfico con la función «plot()», simplemente para delimitar el área del mundo que se va a representar. Posteriormente, de nuevo con la función «plot()», se representa el mapa que tiene las coordenadas de los países. Como los puntos de muestreo están muy cercanos para la escala del Neotrópico, se hace un gráfico más pequeño que se integra dentro del anterior con la función y argumentos «par(new=T,omd= c(x1,x2,y1,y2))» que ya se explicó en el Capítulo II. En este ejemplo también se muestra la forma de hacer flechas en curva con la función «curvedarrow()» del paquete “diagram” (Soetaert, 2012). Hay que especificar las coordenadas de origen «from» y las coordenadas finales «to». Con «arr.pos» se especifica la posición relativa de la punta de flecha (de 0 a 1) y con «arr.type» el tipo de punta de flecha («"simple"», «"triangle"», «"curved"», «"circle"», «"ellipse"» o «"T"»). El argumento «curve» define el tamaño relativo de la curva y el sentido de giro que se controla siendo positivo o negativo el valor. Con «segment» se puede dar unas coordenadas relativas que hace que se empiece y/o acabe antes del origen y final especificado con «from» y «to».
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
library(diagram) library(maptools) datos<-read.csv2("Neotrópico.csv",header=TRUE) (datos) data(wrld_simpl) mapa<-wrld_simpl x<-0; y<-0 windows(7,9) plot(x, y, ylim=c(-57,30),xlim=c(-100,-30), main="Neotrópico", cex.main= 1.8, font.main=2, xlab="Longitud", ylab="Latitud", cex.lab=1.5, font.lab=2) plot(mapa, border="black", add=T) text(-60,-4, "Zona de muestreo") curvedarrow(from = c(-70,-3), to = c(-58,23), lty= 1, lwd=5, lcol="red", curve = -0.4, arr.col="red", arr.pos = 1, arr.type="curved", segment = c(0,1)) oldpar<-par(new=T, omd=c(0.58,0.98,0.58,0.98))
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
328
¾ plot(datos$Lon, datos$Lat, ylim=c(-3.95,-3.75),xlim=c(-71,-68), pch=19, col="blue", xlab="", ylab="", bty="l") ¾ text(datos$Lon,datos$Lat,labels=datos$Sitio,pos=4,offset=0.4,cex=1) ¾ par(oldpar)
-3.75
Neotrópico
Caballochoca
-3.95
20
-3.85
Lago Tarapoto Río Amazonas
-69.5
-50
-40
-68.0
0
-71.0
-20 -60
-40
Latitud
Zona de muestreo
-100
-90
-80
-70
-60
-30
Longitud
IV.3. Mapas con información adicional Se puede añadir a un mapa información adicional como distribución de especies, ciudades, zonas donde se han producido eventos, datos poblacionales, datos epidemiológicos, etc. La función «adarea()» del paquete “mapq” mostrada anteriormente, permite incluir en el mapa cualquier tipo de información a partir de un archivo que simplemente requiere coordenadas de latitud y longitud. Por ejemplo, en la base de datos «Flamingo», que viene con el paquete “mapq”, están las coordenadas de avistamiento de tres especies de flamenco del
MAPAS
329
género Phoenicopterus en Bolivia (Hurlbert y Keith, 1979). Las instrucciones están en el script IV.3.R.
-10
Distribución de especies de flamencos
-12
P. jamesi P. andinus P. chilensis
-14
¾
-16
¾
-18
¾
-20
¾
-22
¾
library(mapq) data(World) data(Flamingo) par(bg="grey95",lwd=1,fg="black") adarea(Area=c("Bolivia"), main="Distribución de especies de flamencos", boxf="n") points(Flamingo[Flamingo$Especie=="Phoenicopterus jamesi", "Lon"], Flamingo[Flamingo$Especie=="Phoenicopterus jamesi", "Lat"], pch=19, col="blue",cex=2) points(Flamingo[Flamingo$Especie=="Phoenicopterus andinus", "Lon"], Flamingo[Flamingo$Especie=="Phoenicopterus andinus", "Lat"], pch=19, col="green",cex=2) points(Flamingo[Flamingo$Especie=="Phoenicopterus chilensis", "Lon"], Flamingo[Flamingo$Especie=="Phoenicopterus chilensis", "Lat"], pch=19, col="red",cex=2) par(font=3) legend("topright",c("P. jamesi","P. andinus","P. chilensis"), pch= c(19,19,19), col=c("blue","green","red"))
Latitud
¾ ¾ ¾ ¾ ¾
-68
-66
-64
Longitud
-62
-60
-58
330
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
En el script IV.4.R se muestra como también es fácil representar una distribución de especies mediante polígonos con las funciones «adarea()» y «polygon()». Es importante tener en cuenta que en el archivo de datos, en este caso «Gorilla», la primera y la última coordenada de cada especie deben ser iguales, para que los polígonos sean cerrados. Además, es necesario dejar una línea en blanco entre los conjuntos de coordenadas de cada especie.
¾ ¾ ¾ ¾
library(mapq) data (World) data(Gorilla) adarea(Area="World", minLon=2, maxLon=31, minLat=-8, maxLat=5, colcon="khaki", colbg = rgb(175, 225, 255, maxColorValue = 255), main="Distribución de especies de gorilas") ¾ polygon(Gorilla$Lon, Gorilla$Lat, col=c("red","green")) ¾ par(font=3) ¾ legend(24,4,c("G. beringei","G. gorilla"), pch=15, col=c("red", "green"), bty="n")
Otra función del paquete “mapq” es «vararea()». Esta función permite representar cualquier variable (densidad o riqueza de especies, variables ambientales como la temperatura, humedad, etc.), en un mapa de contornos. La función requiere tener instalado el paquete “plotrix” (Lemon, 2012). Las instrucciones del ejemplo están en el script IV.5.R. En el primer mapa se representan los valores de altimetría y batimetría a nivel de todo el mundo. Los datos fueron obtenidos de la página web http://rda. ucar.edu/datasets/ds759.2/. La función «vararea()» requiere la misma estructura de datos que otras funciones que representan contornos y se mostraron en el Capítulo II, la cual consiste en un objeto dividido en niveles con un intervalo regular, y con valores crecientes de las variables x e y.
MAPAS
331
En la tabla siguiente se muestra la estructura original de los datos de batimetría y altimetría. La primera fila contiene las longitudes a intervalos de 5´; la primera columna contiene las latitudes también a intervalos de 5´, y el resto de datos corresponde al valor de altimetría/batimetría en metros para esas coordenadas.
-90 -89,917 -89,833 -89,75 . . 89,91667
-179,917 -179,833 2800 2800 2800 2800 2800 2800 2800 2850 . . . . -4290 -4290
. . . . . . . . . . . . . . -4290 -4290
180 2800 2800 2800 2800 . . -4290
La estructura de datos anterior se convierte en tres archivos diferentes. El primero «Long.RData» son los datos de longitud, que corresponden al eje x en el mapa. El segundo «Lati.RData» son los datos de latitud, eje y en el mapa. El tercer y último archivo «BatAlt.RData» son los datos de batimetría/altimetría para esas coordenadas. En la primera parte del script se cargan esos datos junto con «World.RData» que contiene los datos de las coordenadas de los países.
Lati.Rdata Long.Rdata -90,000 -179,917 -89,917 -179,833 -89,833 -179,750 -89,750 -179,667 . . . . 89,917 180
¾ ¾ ¾ ¾ ¾
BatAlt.Rdata 2800 2800 2800 2850 . . . . -4290 -4290 2800 2800 2800 2800
2800 2800 2800 2850 . . -4290
library(mapq) data(World) data(Long) data(Lat) data(BatAlt)
Debido a que el mapa tiene mucha información, no es posible copiarlo directamente desde la pantalla como metafile. Por ello, se exporta a un archivo jpeg, utilizando la función «jpeg()», la cual ya se explicó en el Capítulo I en el apartado de dispositivos para gráficos. Desde este archivo jpeg se puede importar fácilmente a cualquier otro documento. Es importante resaltar que se obtiene una calidad mucho mayor si los mapas se exportan a un dispositivo diferente a la pantalla, como se observa en este caso, ya que es posible modificar, con los argumentos «width», «height» y «quality», la calidad de salida. Al final del script es necesario cerrar el dispositivo con «dev.off()». Dentro de la función «vararea()», con los argumentos «varLon», «varLat» y «varscale» se introducen las variables que tienen los datos de longitud, latitud y de la variable a representar, respectivamente. Aunque la función asigna una posición para la leyenda de colores, con los argumentos «xl», «yb», «xr» e «yt»
332
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
se puede modificar esta posición. Con el argumento «legend.pos="y"» se especifica que la leyenda de colores se ponga en el eje y, con lo que solamente es necesario asignar la posición en el eje x con «xl» y «xr».
¾ jpeg(filename = "Batimetría-Altimetría.jpg", width = 4000, height = 2000, units = "px", pointsize = 48, quality = 1200, bg = "white", res = NA) ¾ vararea(Area=c("World"), varLon=Long, varLat=Lati, varscale=BatAlt, legend.pos="y", main="Batimetría/Altimetría en metros", xl=185, xr=195) ¾ dev.off()
En el segundo mapa del script IV.5.R se muestran los valores de clorofila en superficie en el medio acuático obtenidos del proyecto NASA Sea-viewing Wide Field-of-view Sensor (Sea-WiFS, Feldman y McClain, 2011). En la matriz de datos original hay valores negativos para indicar las coordenadas de tierra, los cuales se sustituyeron por el valor cero. En primer lugar se cargan los datos, pero como hay valores extremos de unos 100 mg m-3, y la mayoría no sobrepasan los 6 mg m-3, es conveniente hacer una transformación logarítmica con la función «log()». Posteriormente, con «color.scale()» se hace una paleta de colores. En la función «vararea()», con los argumentos «legend.min», «legend.max» y «legend.freq» se especifican los valores mínimo, máximo y el intervalo de la leyenda, expresada en escala logarítmica.
¾ data(Chla) ¾ logChla<-log(Chla+1) ¾ color<-color.scale(x=1:10,cs1=c(0.5,0),cs2=c(0.8,1),cs3=c(1,1), color.spec= "hsv",alpha=1,na.color=NA) ¾ jpeg(filename = "Clorofila-a.jpg", width = 4000, height = 2000, units = "px", pointsize = 48, quality = 1200, bg = "white", res = NA) ¾ vararea(Area=c("World"), varLon=Long, varLat=Lati,varscale=logChla, legend.pos="y", colscale=color, colcon="ivory2", main= expression
MAPAS
333
("Concentración de clorofila en mg m"^"-3"),xl=185, xr=195, cex.main=2.2, legend.min=0, legend.max= 4.6, legend.freq=0.46) ¾ dev.off()
En el script IV.6.R hay otro ejemplo de cómo se representan variables en un mapa. Los datos, que están en el archivo Chla.csv, son los valores de clorofila mencionados anteriormente, pero solamente de una zona de la costa pacífica de Sudamérica. En este caso se parte de una estructura de datos, la cual es posiblemente más frecuente, que consiste en tres columnas: longitud, latitud y el valor de la variable para esas coordenadas:
Longitud -85 -85 -85 . . -70
Latitud 5 4,917 4,833 . . -20
Chla 0,181 0,187 0,183 . . 0
Como ya se mencionó antes, los gráficos de densidad requieren una estructura de datos dividida en niveles con un intervalo regular, y con valores crecientes de las variables x e y. Debido a que en este caso la estructura es diferente, es necesario generarla. Para eso nos sirve la función «interp()», presente en el paquete “akima” (Akima, 1978: Akima, 1996; Akima y col., 2012), que ya se explicó en el Capítulo II. Hay que tener en cuenta que la función «interp()» no admite celdas vacías. Por tanto, si hay celdas vacías es necesario eliminarlas previamente con la función «na.exclude». En la función «interp()» simplemente hay que introducir los datos del eje x «datos$Longitud», del eje y «datos$Latitud» y de z «datos$Chla». La estructura de datos que se ha generado se guarda en el objeto «input».
334 ¾ ¾ ¾ ¾ ¾ ¾
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R library(mapq) library(plotrix) library(akima) data(World) datos<-read.csv2("Chla.csv",header=TRUE,encoding= "latin1",fill=TRUE) input<-interp(datos$Longitud, datos$Latitud, datos$Chla, duplicate= "mean")
Posteriormente, con la función «color.scale()», se hace una paleta de colores, la cual es una de las que se mostraron en el Capítulo I.
¾ color<-color.scale(x=1:10, cs1=c(0,0.1,1), cs2=c(1,0.7,1), cs3=c(1,0.5,0), color.spec= "rgb",alpha=1,na.color=NA) Al igual que antes, para mejorar la calidad del gráfico, se exporta a un dispositivo diferente que la pantalla, en este caso a un archivo tiff, donde con el argumento «res» se puede dar una resolución alta al gráfico. En la función «vararea()» es importante mencionar que en los argumentos «varLon», «varLat» y «varscale» hay que poner la salida de la función «interp()», es decir, «input$x», «input$y» e «input$z». Con «xl», y «xr» definimos la posición en el eje x de la leyenda de colores, la cual hemos especificado que se ubique en el eje y «legend.pos="y"». Con los argumentos «legend.min» y «legend.max» se especifica el valor mínimo y máximo de la escala de la leyenda de colores y con «legend.freq» se define en cuantos intervalos se divide la escala de la leyenda. Por último, en «colscale», aunque la función tiene asignada una paleta de colores, se puede especificar otra diferente, en este caso se utilizza la paleta que se asignó en el paso anterior al objeto «color».
¾ tiff(filename = "Chla1.tiff", width = 80, height = 80, units = "in", pointsize =120, bg = "white", res=100) ¾ vararea(Area=c("World"), varLon=input$x, varLat=input$y, varscale=input$z, xl=-69, xr=-67, legend.pos="y", legend.min=0, legend.max=5, legend.freq=1, colcon="khaki", colscale=color, minLon=-85, maxLon=-70, minLat=-20, maxLat=5, main="Clorofila en la costa\nPacífica de Sudamérica", cex.main=1.4) ¾ text(-65,3.9,expression(paste("mg m"^"-3"))) ¾ text(-78,-1.4,"ECUADOR") ¾ text(-76,-8,"PERÚ") ¾ text(-74.5,3,"COLOMBIA") ¾ dev.off() Se observa que el mapa está pixelado, lo cual se debe a que los datos son cada 5´; cuanto mayor sea la resolución de los datos o más grande el área representada, menor será el efecto de pixelado. En el caso del mapa anterior, que mostraba datos de clorofila a nivel mundial, la resolución también era de 5´, pero al ser el área mayor no se notaba el pixelado.
MAPAS
335
Función vararea (paquete mapq)
varLon: variable con los datos de longitud. varLat: variable con los datos de latitud. varscale: variable a representar en el mapa. colscale: gradiente de colores que se usará para representar a la variable: colscale= color.scale(x=1:22,cs1=c(0.5,1),cs2=c(0.5, 1), cs3=c(1,1) ,color.spec= "hsv",alpha=1,na.color=NA). legend.pos: define si la leyenda de colores se pone en el sentido del eje "x" o del eje "y": legend.pos="y". legend.freq: define el número de intervalos de la leyenda de colores: legend.freq=5. legend.min y legend.max: opcionalmente se pueden indicar los valores mínimo y máximo de la escala de la leyenda de colores. xl y xr: opcionalmente se puede indicar la posición inicial y final de la leyenda de colores en el eje x. yb e yt: opcionalmente se puede indicar la posición inicial y final de la leyenda de colores en el eje y.
Son válidos todos los argumentos de la función adarea().
336
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
El script IV.7.R muestra como se puede añadir información sobre la variación geográfica de cualquier variable con la función «adarea()», mediante la función «points()». Los datos están en el archivo Terremotos.csv, que contiene las coordenadas, magnitud y profundidad de algunos de los terremotos que se han producido en los últimos años (datos obtenidos de la página web http://earthquake.usgs.gov/earthquakes/). Después de cargar los datos y eliminar las filas que no tengan algún dato con «na.exclude()», se crea una nueva matriz con los datos estandarizados de la variable de interés, en este caso la Magnitud del terremoto, en una escala de 0 a 5 y se guarda en el objeto «datos1». Este valor de 5 es algo que puede modificar el usuario en el objeto «scale», para ajustar el tamaño de los símbolos. Posteriormente, con la función «length()» se calcula el número de filas, es decir, número de datos de esta matriz estandarizada. Con «rainbow()» se genera un color, al cual se le da semi-transparencia con el argumento «alpha».
¾ library(mapq) ¾ data(World) ¾ datos<-read.csv2("Terremotos.csv", header=TRUE, encoding= "latin1", fill=TRUE) ¾ datos<-na.exclude(datos) ¾ attach(datos) ¾ windows(18,9) ¾ adarea(Area="World", main="Terremotos") ¾ scale<-5 ¾ datos1<-as.data.frame((datos[, "Magnitud"]/max(datos[, "Magnitud"]))* scale) ¾ j<-length(datos1[,1]) ¾ col<-rainbow(1,alpha=0.2) Posteriormente, se genera un bucle donde j es el número de filas de la matriz. Este bucle va representando todos los datos y establece el tamaño de los símbolos en función del valor de la variable en la matriz estandarizada «cex=datos1[z,]».
¾ for (z in 1:j){ points(datos[z,"Longitud"], datos[z,"Latitud"], cex=datos1[z,], pch=16, col=col)} A continuación se calcula el rango entre la máxima y la mínima magnitud de todos los terremotos y se asigna al objeto «r». Posteriormente, este rango se divide por el valor que se ha considerado en la estandarización (5), calculando así el intervalo de incremento de cada símbolo que se usará para realizar la escala, y se asigna al objeto «i». Luego se pinta un marco para la leyenda con «rect()». Finalmente, se realiza un bucle donde el usuario debe indicar la coordenada (horizontal) de longitud de comienzo de la leyenda (-180 en este caso), y las coordenadas de latitud (altura) para los puntos (-55), y para los textos (-45).
¾ r<-range(datos[,”Magnitud”]) ¾ i<-(r[2]-r[1])/scale
MAPAS
337
¾ rect(-175,-40,-85,-75, border=T, col="grey98") ¾ col2<-rgb(255, 0, 0, alpha=100, maxColorValue=255) ¾ for (n in 1:scale){ points((-180+n*12),-55, cex=n,pch=16, col=col2) text((-180+n*12),-45,r[1]+i*n) if(scale==n)text((-180+n*15),-45,”Magnitud”) else NULL} Por último, se hace otro bucle para representar la escala de colores que muestra la frecuencia de los terremotos. De nuevo debe indicarse la coordenada horizontal (-180 igual que antes), la altura de los puntos (-65), y también de los textos (-70).
¾ for (n in 1:scale){ ¾ for (h in 1:n){ points((-180+n*12),-65, cex=1.5,pch=16, col=col)} if (scale==n){ text((-180+n*12),-70,paste(">",n))} else{ text((-180+n*12),-70,n)} if(scale==n)text((-180+n*15.7),-70,"Frecuencia") else NULL} En el mapa el tamaño de los círculos muestra la magnitud del terremoto, con la escala que se muestra abajo a la izquierda. Al poner el color semi transparente, las zonas en las que se producen más terremotos se representan en color más intenso, debido a la superposición de nuevos círculos. Por lo tanto, con este gráfico se puede apreciar la intensidad de los terremotos (tamaño de los círculos) y la frecuencia con que ocurren (color más claro o más oscuro).
En el script IV.8.R se muestra como insertar texto con información fácilmente en un mapa con la función «adarea()» junto con las funciones «points()» y
338
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
«text()». Los datos están en el archivo Ciudades.csv, en el cual hay datos de población, junto con la latitud y longitud de ciudades de Asia (datos obtenidos de la página web http://www.world-gazetteer.com). En el script se realiza una selección de los datos para conservar solamente las ciudades que tengan entre 2 y 2,5 millones de habitantes, y se guarda en el objeto «datos1».
¾ library(mapq) ¾ data(World) ¾ datos<-read.csv2("Ciudades.csv", header=TRUE, encoding= "latin1", fill= TRUE) ¾ windows(18,9) ¾ adarea(Area="World", minLon=30, maxLon=150, minLat=-10, maxLat=50, colcon="white", colbg = "white", main="Ciudades de Asia con \n 2-2,5 millones de habitantes") ¾ datos1<-datos[(datos$Población >= 2000000) & (datos$Población <= 2500000), ] ¾ points(datos1$Longitud, datos1$Latitud, pch=15, col="red") ¾ text(datos1$Longitud, datos1$Latitud, label=datos1$Ciudad, col="red", font=2, pos=4,offset=0.6)
IV.4. Mapas de vectores Una vez representado un mapa también es posible añadirle información como vectores de dirección e intensidad, que son útiles para representar los vientos. Ello se puede realizar con la función «vectorField()» del paquete “plotrix” (Lemon, 2012). Las instrucciones están en el script IV.9.R. En el ejemplo se
MAPAS
339
utilizan datos, que están en el archivo Viento.csv, de dirección e intensidad del viento, en diferentes latitudes y longitudes de la costa pacífica de Panamá. La primera parte del script es para representar el mapa, como ya se explicó anteriormente con la función «adarea()». En este caso se representa Panamá. Después se carga el archivo que tiene los datos de vientos y se pone en la función «vectorField()» la dirección e intensidad del viento, y a continuación la longitud y latitud. El argumento «scale» sirve para definir el tamaño de las flechas. Con «vecspec» se especifica si la dirección es en grados «"deg"» o en radianes «"rad"». Por último, el argumento «headspan» se utiliza para definir el tamaño de la punta de la flecha.
¾ ¾ ¾ ¾ ¾
library(mapq) library(plotrix) data(World) windows(12,7) adarea(Area=c("Panama"), colbg=rgb(175,225,255, maxColorValue=255), colcon=rgb(255,150,100, maxColorValue=255)) datos2<-read.csv2("Viento.csv", header=TRUE, encoding= "latin1") par(fg="white",lwd=2) vectorField(datos2$DirViento, datos2$IntViento, datos2$Longitud, datos2$ Latitud, scale=0.2, vecspec="deg", headspan=0.05) text(-77.8, 9.45, substitute("20 km h"^-1), cex=1.2)
¾ ¾ ¾ ¾
9.5
Panama 1
8.5 8.0 7.5
Latitud
9.0
20 km h
-83
-82
-81
-80
-79
-78
-77
Longitud
Función vectorField (paquete plotrix)
u y v: dirección e intensidad de los vectores. xpos e ypos: longitud y latitud. scale: tamaño de las flechas: scale=1. headspan: tamaño de la punta de la flecha: headspan=0.1. vecspec: define si la dirección de las flechas es en grados "deg" o radianes "rad".
340
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
IV.5. Mapas interactivos Al final del Capítulo II vimos que la Interfaz de Programación de Aplicaciones (API) de visualización de Google permite realizar representaciones interactivas, las cuales se pueden incorporar a páginas web. En ese Capítulo II se explicaron varias funciones del paquete “googleVis” (Gesmann y de Castillo, 2011; 2012), el cual proporciona una interfaz entre R y la API de visualización de Google. Ahora vamos a ver la función «gvisGeoMap()», que permite realizar mapas interactivos. Es necesario tener conexión a internet. Las instrucciones están en el script IV.10.R. El ejemplo, cuyos datos están en el archivo Población.csv, contiene el número de habitantes de diferentes países obtenidos de la página web http://www.world-gazetteer.com. Es muy importante que en el archivo de entrada, los nombres de los países, ciudades, regiones, etc., coincidan con los códigos que se pueden consultar en la siguiente página web: https://developers.google.com/adwords/api/docs/appendix/countrycodes?hl=es. En la función «gvisGeoMp()», en el argumento «locationvar» se introduce la variable con los nombres de los países, regiones, ciudades, etc., siguiendo el formato de códigos mencionado. Es muy importante el argumento «region», ya que permite seleccionar una determina zona del mundo, para lo cual hay que utilizar los códigos que se muestran en la Tabla IV.2. En «numvar» se introduce la variable que define el patrón de colores de los diferentes países, en este caso es la población. Por último, en «hovevar» se puede poner el nombre de otra variable, la cual aparecerá cuando se pase el ratón por el país, junto con la variable que se está examinando. En este caso se ha seleccionado que aparezca el nombre del país, además del dato de población.
¾ library(googleVis) ¾ Pob<-read.csv2("Población.csv",header=TRUE,encoding="latin1") ¾ M<-gvisGeoMap(Pob, locationvar="Country", numvar="Population", hovervar = "Country", options = list(region="world", showLegend= TRUE, width = 1000, height = 500, colors="[0xE0FFD4, 0xA5EF63, 0x50AA00, 0x267114]")) ¾ plot(M)
MAPAS
341
Sustituyendo «numvar="Population"» por «numvar="Annual.Grow"» se obtienen un mapa que informa de cuales fueron los países que mas crecieron. Al sustituir «region="world"» por «region="034"» se muestra el sur de Asia.
¾ M<-gvisGeoMap(Pob, locationvar = "Country", numvar= "Annual.Grow", hovervar= "Country", options = list(region="034", showLegend= TRUE, width = 1000, height = 500, colors="[0xE0FFD4, 0xA5EF63, 0x50AA00, 0x267114]")) ¾ plot(M)
Tabla IV.2. Códigos de las diferentes regiones para el argumento «region» de la función gvisGeoMap()».
world (todo el mundo) 005 (América del Sur) 021 (América del Norte) 017 (África Central) 018 (África del Sur) 034 (Sur de Asia) 143 (Asia Central) 151 (Norte de Asia) 155 (Europa Occidental)
us_metro (areas metropolitanas, EEUU) 013 (América Central) 002 (África) 015 (Norte de África) 030 (Asia Oriental) 035 (Asia/Pacífico) 145 (Oriente Medio) 154 (Norte de Europa) 039 (Sur de Europa)
IV.6. Mapas hidrológicos Las funciones «SRaqua()», «LRaqua()», «LHaqua()» e «INaqua()» del paquete “mapq” permiten representar sistemas hidrológicos. Estas funciones vienen con el conjunto de datos que se descargan de la página web que se mencionó en el Capítulo I, y la forma de instalarlas es igual a como se explicó para la función «adarea()» al comienzo del capítulo. Las coordenadas de estos
342
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
sistemas acuáticos fueron obtenidas de la página web http://www.diva-gis.org/. La función «SRaqua()» representa cuerpos de agua pequeños: ríos pequeños, quebradas, arroyos, etc. La función «LRaqua()» representa ríos grandes. La función «LHaqua()» representa sistemas lénticos: lagos, ciénagas, pantanos, embalses, lagunas, etc. La función «INaqua()» representa las islas que hay dentro de algunos sistemas acuáticos. Las instrucciones del ejemplo están en el script IV.11.R. Después de cargar la librería, se cargan las bases de datos que hacen falta: «World.RData» son las fronteras de las diferentes áreas administrativas que ya vimos anteriormente, «AquaLR» son las coordenadas de los ríos grandes, «AquaSR» son los ríos pequeños, «AquaLH» son los sistemas lénticos y, por último, «AquaIN» son las islas que hay dentro de los sistemas acuáticos. Los argumentos de las funciones «SRaqua()», «LRaqua()» «LHaqua()» y «INaqua()» son iguales a los descritos para la función «adarea()» y, por tanto, su funcionamiento es el mismo. Solamente hay un argumento nuevo, «colaq», que es el color de los ríos, lagos, pantanos, etc. (azul por defecto) e islas (blanco por defecto). Este argumento sustituye a «colcon», que era el color de cada una de las áreas administrativas. El código de las diferentes áreas administrativas es el que se mostró en la Tabla IV.1. En el script se ha introducido la función «rm()», que permite borrar datos de la memoria, aunque está anulada con el #, pero se puede activar si la memoria del ordenador es insuficiente. Con la función «ls()» se puede ver lo que hay cargado en memoria. Cuando se finalice con el script se puede borrar todo lo que hay en la memoria con la función «rm(list=ls())».
¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾
library(mapq) data(World) data(AquaLR); data(AquaSR); data(AquaLH); data(AquaIN) SRaqua(Area = "Colombia", minLon=-80, maxLon=-66, minLat=-5, maxLat=14, axes=T) #rm(AquaSR) par(new=T) LRaqua(Area = "Colombia", minLon=-80, maxLon=-66, minLat= -5, maxLat=14, xlab="", ylab="", axes=F, main="", boxf="n") #rm(AquaLR) par(new=T) LHaqua(Area = "Colombia", minLon=-80, maxLon=-66, minLat= -5, maxLat=14, xlab="", ylab="", axes=F, main="", boxf="n") #rm(AquaLH) par(new=T) INaqua(Area = "Colombia", minLon=-80, maxLon=-66, minLat= -5, maxLat=14, xlab="", ylab="", axes=F, main="", boxf="n") #rm(AquaIR) par(new=T) adarea(Area="Colombia", colcon="transparent", minLon=-80, maxLon=66, minLat=-5, maxLat=14, xlab="", ylab="", axes=F, main="", boxf="n") #rm(adworld)
MAPAS
343
En el segundo mapa se selecciona una zona de la costa del Caribe colombiano. En primer lugar se representa el continente para poder poner un fondo al mapa, que sería la parte marina. Posteriormente, se representan los ríos pequeños para ese rango de latitud y longitud con la función «SRaqua()», luego los ríos grandes con «LRaqua()», los sistemas lénticos con «LHaqua()», y luego las islas con «INaqua()». Finalmente, se representan unos puntos con la función «points()» y texto con la función «text()», para mostrar como se añade fácilmente información al mapa. El hecho de que las funciones que representan los mapas hidrológicos requieran una estructura de datos muy simple, solamente son necesarios datos de longitud y latitud, permite añadir fácilmente nuevos elementos, como por ejemplo cuerpos de agua muy pequeños que puedan faltar en la base de datos. Para ello, se puede usar la función «polygon()» si son sistemas grandes y se quieren rellenar con algún color, o la función «lines()» para ríos pequeños.
¾ adarea(Area="Colombia", colcon="white", minLon=-76, maxLon=-74, minLat=10, maxLat=11.5, xlab="", ylab="", axes=F, main="", boxf="n", colbg=rgb(175,225,255, maxColorValue=255))
344
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
¾ par(new=T) ¾ SRaqua(Area="Colombia", minLon=-76, maxLon=-74, minLat= 10, maxLat=11.5, main="Caribe de Colombia") ¾ par(new=T) ¾ LRaqua(Area="Colombia", minLon=-76, maxLon=-74, minLat=10, maxLat=11.5, xlab="", ylab="", axes=F, main="", boxf="n") ¾ par(new=T) ¾ LHaqua(Area="Colombia", minLon=-76, maxLon=-74, minLat=10, maxLat=11.5, xlab="", ylab="", axes=F, main="", boxf="n") ¾ par(new=T) ¾ INaqua(Area="Colombia", minLon=-76, maxLon=-74, minLat=10, maxLat=11.5, xlab="", ylab="", axes=F, main="", boxf="n") ¾ text("Cartagena\nde Indias", x=-75.7, y=10.44) ¾ points(x=-75.52, y=10.4, pch=16, col="green", cex=2) ¾ text("Barranquilla", x=-74.85, y=11.15) ¾ points(x=-74.85, y=11.06, pch=16, col="green", cex=2) ¾ text("Santa\nMarta", x=-74.31, y=11.32) ¾ points(x=-74.18, y=11.28, pch=16, col="green", cex=2)
El mapa 3 muestra la hidrología de Australia. Debido a que tiene mucha información, no es posible copiarlo directamente desde la pantalla como metafile y, por ello, al igual que hicimos anteriormente con otros mapas, se exporta a un archivo jpeg utilizando la función «jpeg()», en vez de mostrarlo en la pantalla.
MAPAS
345
¾ jpeg(filename = "Australia.jpg", width = 2000, height = 2000, units = "px", pointsize = 48, quality = 1200, bg = "white", res = NA) ¾ adarea(Area="Australia", colcon="white", colbg =rgb(175,225,255, maxColorValue=255)) ¾ par(new=T) ¾ SRaqua(Area="Australia", xlab="", ylab="", axes=F, main="", boxf="n") ¾ par(new=T) ¾ LRaqua(Area="Australia", xlab="", ylab="", axes=F, main="", boxf="n") ¾ par(new=T) ¾ LHaqua(Area="Australia", xlab="", ylab="", axes=F, main="", boxf="n") ¾ par(new=T) ¾ INaqua(Area="Australia", xlab="", ylab="", axes=F, main="", boxf="n") ¾ dev.off()
En el cuarto y último mapa se muestra como es posible poner de diferentes colores los sistemas acuáticos de cada uno de los países usando los argumentos «exclude» y «colexc».
346
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
¾ jpeg(filename = "Iran-Pakistan.jpg", width = 2000, height = 2000, units = "px", pointsize = 48, quality = 1200, bg = "white", res = NA) ¾ adarea(Area="World", colcon="white", minLon = 60, maxLon= 68, minLat=23, maxLat= 27,colbg=rgb(175,225,255, maxColorValue=255), xlab="",ylab="", axes=F, main="", boxf="n") ¾ par(new=T) ¾ SRaqua(Area="World", exclude="Pakistan", colexc="skyblue", minLon = 60, maxLon= 68, minLat=23, maxLat= 27, xlab="", ylab="", axes=F, main="", boxf="n") ¾ rm(AquaSR) ¾ par(new=T) ¾ LRaqua(Area="World", exclude="Pakistan", colexc="skyblue", minLon = 60, maxLon= 68, minLat=23, maxLat= 27, xlab="", ylab="", axes=F, main="", boxf="n") ¾ rm(AquaLR) ¾ par(new=T) ¾ LHaqua(Area="World", exclude="Pakistan", colexc="skyblue", minLon = 60, maxLon= 68, minLat=23, maxLat= 27, xlab="", ylab="", axes=F, main="", boxf="n") ¾ rm(AquaLH) ¾ par(new=T) ¾ adarea(Area="World", colcon="transparent", minLon = 60, maxLon= 68, minLat=23, maxLat= 27,colbg="transparent", main="Hidrología de la costa de Irán y Pakistán", cex.main=1.4) ¾ rm(list=ls()) ¾ dev.off()
BIBLIOGRAFÍA Akima, H. (1978). A Method of Bivariate Interpolation and Smooth Surface Fitting for Irregularly Distributed Data Points. ACM Transactions on Mathematical Software, 4: 148-164. Akima, H. (1996). Algorithm 761: scattered-data surface fitting that has the accuracy of a cubic polynomial. ACM Transactions on Mathematical Software, 22: 362–371. Akima H, Gebhardt A, Petzoldt T y Maechler M (2012) Package ‘akima’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Amigo H, Bustos P, Erazo M, Cumsille P y Silva C (2007) Factores determinantes del exceso de peso en escolares. Un estudio multinivel. Revista Médica de Chile, 57: 353-357. Bednarski T (1993). Robust estimation in Cox’s regression model. Scandinavian Journal of Statistics. 20: 213–225. Bednarski T (2012) Package ‘maps’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Breiman L, Friedman J, Olshen R y Stone C (1984) Classification and Regression Trees. Wadsworth. Brownrigg R y Minka TP (2012) Package ‘maps’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Calenge C (2012) Package ‘adehabitat’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Chessel D, Dufour AB, Dray S, Jombart T, Lobry JR, Ollier S, Pavoine S y Thioulouse J (2012) Package ‘ade4’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Chongsuvivatwong V (2012) Package ‘epicalc’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Cornell, JA (1975). Some comments on Designs for Cox’s mixture polynomial. Technometrics 17: 25-35
347
348
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Cornell, JA (2022) Experiments with Mixtures. John Wiley & Sons, New York. Cotes M (2011) Metales en Sedimentos del Sistema de Inundación Yahuarcaca en el Alto Amazonas y Su Posible Relación Con Actividad Humana (Leticia: Colombia). Tesis de Maestría de la Universidad Jorge Tadeo Lozano. de Mendiburu F (2012) Package ‘agricolae’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. DebRoy S y Bivand R (2012) Package ‘foreign’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Dodder NG (2012) Package ‘OrgMassSpecR’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Dubin JA, Lee JJ, Hess KR (1997) The Utility of Event Charts. Proceedings of the Biometrics Section, American Statistical Association. Dubin JA, Muller H-G, Wang J-L (2001) Event history graphs for censored survival data. Statistics in Medicine, 20: 2951–2964. Feldman GC y McClain CR (2006) Ocean Color Web, SeaWiFS Reprocessing R20100, NASA Goddard Space Flight Center Eds Kuring, N, Bailey, SW 3 May 2011 http://oceancolorgsfcnasagov/. Fox J (2005) The R Commander: A Basic Statistics Graphical User Interface to R. Journal of Statistical Software, 14: 1–42. Fox J (2007) Extending the R Commander by "plug in" packages. R News, 7: 46– 52. Fox J, Andronic L, Ash M, Bouchet-Valat M, Boye T, Calza S, Chang A, Grosjean P, Heiberger R, Karimi Pour K, Kerns GJ, Lancelot R, Lesnoff M, Ligges U, Messad S, Maechler M, Muenchen R, Murdoch D, Neuwirth E, Putler R, Ripley B, Ristic M y Wolf P. (2012) Package ‘Rcmrd’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Friendly M (2002) Corrgrams: Exploratory displays for correlation matrices. The American Statistician, 56: 316–324. Friendly M (2007). HE plots for Multivariate General Linear Models. Journal of Computational and Graphical Statistics, 16: 421–444. Friendly M y Fox J (2012) Package ‘candisc’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria.
BIBLIOGRAFÍA
349
Frutos E (2012) Package ‘GGEBiplotGUI’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Gauch H y ZOBEL R (1988). Predictive and postdictive success of statistical analysis of yield trials. Theoretical and Applied Genetics, 79:753-761. Gauch H y ZOBEL R (1996). AMMI analysis of yield trials. En: M.S. Kang y H.G. Gauch. (eds.). Genotype-by-Environment interaction. CRC Press, Boca Ratón. pp. 85-122 Gesmann M y de Castillo D (2011) Using the Google Visualisation API with R. The R Journal 3/2: 40-44. Gesmann M y de Castillo D (2012) Package ‘googleVis’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Grosjean P (2012) Package ‘SciViews’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Guijarro, JA (2001) Package ‘climatol’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Guisande C, Cabanas JM, Vergara AR y Riveiro I (2001) Effect of climate on recruitment success of Atlantic Iberian sardine (Sardina pilchardus). Marine Ecology Progress Series, 223: 243-250. Guisande C, Vaamonde A y Barreiro A (2011) Tratamiento de datos con R, SPSS y STATISTICA. Editorial Díaz de Santos, Madrid. Harrell FE Jr (2012) Package ‘Hmisc’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Hervé M (2011) GrapheR: a Multiplatform GUI for Drawing Customizable Graphs in R. The R Journal 3/2: 45-53. Hervé M (2012) Package ‘GRapheR’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Higgins JPT, Thompson SG, Deeks JJ y Altman DG (2003) Measuring inconsistency in meta-analyses. BMJ: 327:557 Hoffmann CW (2012) Package ‘cwhmisc’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Holmes EE y Ward EJ (2010) Analysis of multivariate time-series using the MARSS package. NOAA Fisheries, Northwest Fisheries Science Center, 2725 Montlake Blvd E., Seattle, WA 98112.
350
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Holmes EE, Ward EJ y Wills K (2012) Package ‘MARSS’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Hothorn T (2012) Package ‘partykit’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Hothorn T, Buhlmann P, Dudoit S, Molinaro A y van der Laan MJ (2006a). Survival Ensembles. Biostatistics, 7: 355–373. Hothorn T, Hornik K y Zeileis A (2006b). Unbiased Recursive Partitioning: A Conditional Inference Framework. Journal of Computational and Graphical Statistics, 15: 651–674. Hothorn T, Hornik K, Strobl C y Zeileis A (2012) Package ‘party’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Hothorn T, Lausen B, Benner A y Radespiel-Troeger M (2004). Bagging Survival Trees. Statistics in Medicine, 23: 77–91. Hurlbert SH y Keith JO (1979) Distribution and Spatial Patterning of Flamingos in the Andean Altiplano. The Auk, 96(2): 328-342. James D (2012) Package ‘chart’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Jombart T (2012) Package ‘adegenet’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Jombart T, Devillard S y Balloux F (2010) Discriminant analysis of principal components: a new method for the analysis of genetically structured populations. BMC Genetics, 11:94. Kampstra P (2008) Beanplot: A Boxplot Alternative for Visual Comparison of Distributions. Journal of Statistical Software, Code Snippets, 28: 1-9. Kampstra P (2012) Package ‘beanplot’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Kiermeier A (2012) Package ‘AcceptanceSampling’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Kort E (2012) Package ‘rtiff’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Lee JJ, Hess KR y Dubin JA (2000) Extensions and applications of event charts. The American Statistician, 54: 63–70.
BIBLIOGRAFÍA
351
Lewin-Koh NJ y Bivand R (2012) Package ‘maptools’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Loecher M (2012) Package ‘RedaImages’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Locher R, Ruckstuhl A y col. (2012) Package ‘IDPmiscs’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Maindonald J (2012) Package ‘DAAG. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. McCulloch C (2012) Package ‘freqMAP’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Meyer D, Zeileis A y Hornik K. (2003) Visualizing independence using extended association plots. Proceedings of the 3rd International Workshop on Distributed Statistical Computing, K. Hornik, F. Leisch, A. Zeileis (eds.), ISSN 1609-395X. Meyer D, Zeileis A y Hornik K (2006) The strucplot framework: Visualizing multiway contingency tables with vcd. Journal of Statistical Software, 17: 1-48. Meyer D, Zeileis A, Hornik K y Friendly M (2012) Package ‘vcd’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Milborrow S (2012) Package ‘rpart.plot’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Murdoch D (2009) Package ‘ellipse’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Murdoch D (2012) Package ‘rgl’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Murdoch DJ y Chow ED (1996) A graphical display of large correlation matrices. The American Statistician, 50: 178–180. Murrell P y Ihaka R (2000) An approach to providing mathematical annotation in plots. Journal of Computational and Graphical Statistics 9: 582–599. Obenchain RL (1999) Resampling and multiplicity in cost-effectiveness inference. Journal of Biopharmaceutical Statistics, 9: 563-582.
352
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Obenchain RL (2012) Package ‘ICEinfer’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Obenchain RL, Melfi CA, Croghan TW y Buesching DP (1997) Bootstrap analyses of cost-effectiveness in antidepressant pharmacotherapy. Pharmaco Economics, 17: 1200-1206. Payami H, Kay DM, Zabetian CP, Schellenberg GD, Factor SA y McCulloch CC (2010) Visualizing Disease Associations: Graphic Analysis of Frequency Distributions as a Function of Age Using Moving Average Plots (MAP) with Application to Alzheimer's and Parkinson's Disease. Genetic Epidemiology 34: 92-101. Pruzek RM (2012) Package ‘granova’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Rajaram S y Oono Y (2012) Package ‘NeatMap’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Recchia DR y Barbosa EJ (2012) Package ‘IQCC’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Ripley B, Hornik K y Gebhardt A (2012) Package ‘MASS’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Roever C, Raabe N, Luebke K, Ligges U, Szepannek G y Zentgraf M (2012) Package ‘klaR’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Roth T (2012) Package ‘qualityTools’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Sarkar D (2008) Lattice: Multivariate Data Visualization with R. Springer. Sarkar D (2012) Package ‘lattice’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Scheffé, H (1963) The simplex-centroide design for experiments with mixtures. Journal of the Royal Statistical Society B, 25:235-263 Schloerke B (2012) Package ‘GGally’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Schwarzer G (2012) Package ‘meta’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria.
BIBLIOGRAFÍA
353
Scrucca L (2012) Package ‘qcc’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Silagy C, Ketteridge S (1977) Physician advice for smoking cessation. En: Lancaster T, Silagy C, Fullerton D. Editores. Tobacco Addiction Module of the Cochrane Database of Systematic Reviews 4. Simpson GL y Oksanen J (2012) Package ‘diagram’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Soetaert K (2012) Package ‘dANALOGUE’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Stone L y Berman T (1993) Lake Kinneret: A seasonal model for carbon flux through the planktonic biota. Limnology and Oceanography, 38: 16801695. Strobl C, Boulesteix AL, Zeileis A y Hothorn T (2007). Bias in Random Forest Variable Importance Measures: Illustrations, Sources and a Solution. BMC Bioinformatics, 8: 25. Therneau TM (2012) Package ‘survival’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Therneau TM y Atkinson B (2012a) Package ‘rpart’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Therneau TM y Atkinson B (2012b) Package ‘mvrpart’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Urbanek S (2012) Package ‘rJava’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Warnes GR (2012a) Package ‘gregmisc’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Warnes GR (2012b) Package ‘gplots’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Wei T (2012) Package ‘corrplot’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Wilkinson L (2012) Package ‘venneuler’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria.
354
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Williams GJ (2009) Rattle: A Data Mining GUI for R. The R Journal 1/2: 45-55. Williams GJ L (2012) Package ‘rattle’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Wuertz D (2012) Package ‘fBasics’. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. Yan W y Kang M (2003) GGE Biplot Analysis: A Graphical Tool for Breeders, Geneticists, and Agronomists. CRC Press, Boca Raton, FL, USA. Yan W, Cornelius PL, Crossa J y Hunt LA (2001) Two types of GGE biplots for analyzing multienvironment trial data. Crop Science, 41: 656-663. Yan W, Hunt LA, Sheng Q y Szlavnics Z (2000) Cultivar evaluation and megaenvironment investigation based on the GGE biplot. Crop Science, 40: 597605. Zobel R, Wright M y Gauch H (1988) Statistical analysis of a yield trial. Agronomy Journal, 80:388-393.
ÍNDICE DE PAQUETES, FUNCIONES Y ARGUMENTOS GRÁFICOS
ERRNVPHGLFRVRUJ arctext(), 98 Area=, 319, 324 args.legend=, 71 arr.col=, 98, 129, 131, 327 arr.pos=, 98, 327 arr.type=, 98, 327 arrow.len=, 191 arrows(), 7, 67, 97 arrows=, 89, 93 as.matrix(), 68, 87, 89, 148, 240, 248 as.numeric(), 134 ask=, 12, 174, 198 asp=, 12, 40 aspect=, 90, 147 assoc(), 161, 165 at=, 7, 9, 97, 172 attach(), 42 auto.key=, 57, 92, 146 axes=, 12, 28, 71, 85, 99, 234, 236, 292, 324 axial=, 296 axis(), 7, 28, 85, 95 axis.lty=, 71 axisnames=, 71
A abbreviate=, 269 abline(), 6, 41, 97, 232 absolutethresh=, 188, 190 AcceptanceSampling, 279 adarea(), 319, 324, 327, 328 add=, 12, 46, 51, 84, 105, 123, 131, 178, 327 addaxes=, 80 addcolorlabel=, 150 addgrid.col=, 150 addincr=, 228 addmean=, 79, 80 addrect=, 150 addshade=, 150 addtextlabel=, 148, 150 ade4, 76, 80, 81, 212 adegenet, 212, 215 adehabitat, 174, 176 adj=, 12, 95 adjust=, 143, 151 aes_string=, 127 aggregate(), 67, 101, 240, 276 agricolae, 216, 247 akima, 83, 85, 333 align=, 29, 125 all.leaves=, 259 allincr=, 228 allow.multiple=, 57, 90, 94, 147 allstudies=, 228, 229 alpha.regions=, 94 alpha=, 26, 28, 33, 97, 332, 335, 336 alpha0=, 76, 77 alt=, 278 AMMI(), 216 analogue, 271 ang=, 275 angle=, 7, 10, 59, 63, 71, 74 ann=, 12, 95
B barcol=, 48 barp(), 72 barplot(), 65, 99 bars=, 259 beanlines=, 55 beanlinewd=, 55 beanplot, 52 beside=, 68, 70, 71, 271 between=, 145, 147 bg=, 12, 13, 36, 37, 42 bgcol=, 105 bin=, 63 biplot(), 190, 246
355
356
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
biv.test(), 174 bmp(), 34, 36 border=, 10, 26, 44, 51, 54, 55, 60, 71, 74, 88, 166, 169, 178, 239, 298, 327, 337 box(), 8, 95 box.col=, 143 box.ratio=, 57 box=, 8, 87, 89, 95, 185 boxcox=, 290 boxf=, 324, 329, 342 boxit=, 126 boxwex=, 54, 55 boxwidth=, 270 br=, 174 branch=, 254, 259 breakcol=, 105 breaks=, 60, 63, 101, 143, 161, 271 brw=, 105 bty=, 13, 42, 69, 77, 95, 123, 328 bud.digit=, 131 bud.ncol=, 131 bud.size=, 131 bud.title=, 131 budget=, 129, 131 buffered=, 37 bw=, 55, 158 bwplot(), 56, 90, 94, 147 by.groups=, 192, 194 by=, 63, 67, 85, 102, 154, 157, 240, 276 bylab=, 228, 231 byvar=, 228, 231
C candisc, 194 candisc(), 194, 197 candiscList(), 197 canvas=, 36, 37 car, 192 cause.and.effect(), 279 cause=, 279 cbind(), 134, 156, 195, 277 cd_plot(), 158, 160 center=, 98, 215, 296, 303 centerCube=, 291 cex.axis=, 13, 47, 71, 84, 102, 103, 154, 157, 164, 165, 233, 298, 324 cex=, 13, 40 cex.col=, 290 cex.diag=, 151, 169 cex.fact=, 42
cex.lab=, 13, 28, 40, 52, 77, 158, 164, 169, 179, 191, 194, 214, 233, 292, 324 cex.labels=, 140, 142, 143 cex.legend=, 154, 158 cex.main=, 13, 28, 35, 40, 58, 73, 84, 9, 125, 140, 153, 158, 169, 191, 233, 288, 324 cex.names=, 71 cex.studlab=, 234 cex.text=, 248, 290 cex.val=, 283, 290 cex.X.axis=, 63 cex.Y.axis=, 63 cg(), 283 chron, 133 CI.method=, 190 CI.sim=, 190 cl.cex=, 150 cl.length=, 150 cl.offset=, 150 cl.ratio=, 150 clabel=, 76, 77, 79, 80 classic=, 292 cleg=, 76, 77 clickToConfirm=, 36, 37 climatol, 274, 276 clip.right.labs=, 254 clockwise=, 73, 74, 133, 172, 173 cloud(), 92, 147 cm.colors(), 30 code=, 7, 67 coef=, 6, 195 col=, 14, 42 col.by=, 230 col.contour=, 235, 236 col.diamond.fixed.lines=, 230 col.diamond.fixed=, 230 col.diamond.lines=, 230 col.diamond.random.lines=, 230 col.diamond.random=, 230 col.diamond=, 230 col.i.inside.square=, 230 col.i=, 230 col.line=, 273 col.poly=, 272, 273 col.refline=, 273 col.regions=, 94 col.smooth=, 273 col.square.lines=, 230 col.square=, 225, 230 col.symbol=, 273
ÍNDICE DE PAQUETES, FUNCIONES Y ARGUMENTOS GRÁFICOS col.x=, 158 col.y=, 158 col.zones=, 272, 273 col_vars=, 165 colaq=, 342 colbg=, 321, 324 colClasses=, 134 colcon=, 321, 324, 343 colexc=, 323, 324, colgap=, 232 colgap.forest.left=, 232 colgap.forest.right=, 232 colgap.forest=, 232 colgap.left=, 232 colgap.right=, 232 colnames(), 68, 71, 74, 101, 134, 275, 277 color.legend(), 29, 125 color.palette=, 86 color.scale(), 28, 29, 125, 332 colorkey=, 94 colormodel=, 36, 37 colors(), 12, 13, 20, 42 colorTable(), 24 colramp=, 169 column.values=, 90 colXonY=, 151 colYonX=, 151 comb.fixed=, 228, 231, 232, 234 comb.random=, 228, 231, 232, 234 complab=, 228 compress=, 254 compression=, 36, 37 conf.level=, 148, 290 consensus(), 247 contour(), 83 contour.levels=, 235 contourPlot(), 294 contourPlot3(), 297 controls=, 269 coordinates=, 83 coordx=, 58 coordy=, 58 cor(), 148 corrplot(), 147, 148 corrplot, 147 coxr(), 181 coxrobust, 181 cp=, 250 cpoint=, 79, 80 cra=, 14, 95 cs1=, 28
357
cs2=, 28 cs3=, 28 CSEGriskfigure(), 188 csub=, 79, 80 ctree(), 260, 263, 267, 269 ctree_control(), 268 ctreeobj=, 270 cumperc=, 281 curve=, 98, 327 curvedarrow(), 327 cut=, 55 cutmax=, 55 cutmin=, 55 cwhmisc, 151 cylindrical=, 72
D d.main=, 166, 169 DAAG, 24 dapc(), 212, 215 data(), 42 date.format=, 118 date.orig=, 135, 137 dates(), 134 datevar=, 120 dcirc=, 131 default_units=, 94 demo(), 5 density(), 159 density=, 10, 59, 63, 71, 74, 101, 176 dev.off(), 35, 45, 153, 331 df=, 219 dfxy=, 176 dg=, 185 diag.panel=, 142, 143 diag=, 150 diagram, 98, 129, 327 diagwl(), 276 digits=, 42, 195, 232, 254, 259, 270 dimnames_color=, 83 dimnames_position=, 83 dimnames=, 83 din=, 14, 95 dir=, 164 direction=, 128, 129 display.height=, 128, 129 distance=, 93, 248 distribution=, 288, 290 dosqrs=, 185 dotchart(), 77 dotcircle(), 76, 77
358
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
dotplot(), 63 drape=, 94 draw.dendrogram3d(), 240 draw.line=, 80 draw=, 94 DrawChromatogram(), 170 drawlabels=, 85 drawLegend=, 273 drop.unused.levels=, 57, 90 drop_terminal=, 269 duplicate=, 85, 248, 334
E edge_panel=, 269 edge_simple(), 270 edges=, 74 effect=, 279 effectPlot(), 292, 299 ellipse, 141, 192, 194 embed.dim=, 241 end=, 30, 85 ENV=, 216 ep_args=, 269 epicalc, 63 err=, 46, 48 errbar(), 66 est=, 278 event.c=, 225, 227 event.chart(), 133, 137 event.e=, 225, 227, 233, 235, 237 exclude=, 323, 324 expand=, 89, 191 explode=, 74 expression(), 32, 47, 58, 97, 125, 129, 170, 275, 334 extra.points.no.mult=, 139
F f.weight=, 181 facCg=, 284 facCgk=, 284 facDesign(), 291 fallen.leaves=, 254 family=, 14, 37, 40, 91 fBasics, 24 ff.axis=, 232 ff.fixed.labels=, 231 ff.fixed=, 231 ff.heading=, 231 ff.hetstat=, 231 ff.random.labels=, 231
ff.random=, 231 ff.study.labels=, 231 ff.study=, 231 ff.xlab=, 232 fg=, 14, 83, 329, 339 fig.size=, 130 fig=, 14, 92 filename=, 36, 37, 153, 332, 334, 345, 346 fill=, 8, 56, 68, 120, 197, 235, 261, 264, 270, 334, 336 filled.contour(), 83 fillOddEven=, 36, 37 fin=, 14, 92 fint=, 275 flab=, 275 flowmat=, 130 fnum=, 275 font.axis=, 15, 40, 44, 47, 66, 70, 324 font.lab=, 15, 40, 44, 49, 60, 84, 95, 100, 324, 327 font.labels=, 143 font=, 15, 28, 35, 40, 56, 72 fontsize=, 80, 93, 162, 197, 231, 264 for(), 35, 134, 148, 174, 275, 336 foreign, 154 forest.meta(), 225, 231, 236 form=, 298 format=, 101 frac(), 32, 33, 58, 97 frame.plot=, 55, 86 frame=, 93, 140 freq.MAP, 153 freq=, 60, 63, 271 freqMAP(), 153 from=, 160, 327 fs.axis=, 231 fs.fixed.labels=, 231 fs.fixed=, 231 fs.heading=, 231 fs.hetstat=, 231 fs.random.labels=, 231 fs.random=, 231 fs.study.labels=, 231 fs.study=, 231 fs.xlab=, 231 fun=, 292 function(), 35, 56, 67, 69, 89, 142, 148 funnel.meta(), 234
ÍNDICE DE PAQUETES, FUNCIONES Y ARGUMENTOS GRÁFICOS G gageRR(), 285 gageRRDesign(), 285 gamma.col=, 179 gap.axis=, 105 gap.barplot(), 104 gap.boxplot(), 104 gap.plot(), 104 gap=, 46, 48, 105, 123, 124, 143, 270 GEN=, 216 getwd(), 2 GGally, 127 ggally_points(), 127 GGEBiplot(), 199 GGEBiplotGUI, 199 gp_labels=, 161 gp_varnames=, 161 gp=, 93, 264 gpar=, 80, 93, 94, 160, 161, 264 gplots, 66 grad.corr.lines=, 179 gradient=, 29, 125 granova, 182 granova.1w(), 182, 185 granova.2w(), 182 graph=, 218 GrapheR, 112 graphics, 5, 6, 11, 40, 51, 63, 71, 74, 83, 86, 89, 143, 164 graphics=, 198 gray.colors(), 30 grDevices, 30, 72, 264 gregmisc, 46 grid(), 8, 48 grid=, 82, 193, 194 grid.bg=, 131, 133 grid.col=, 131, 133 grid.left=, 133 grid.unit=, 133 grid_color=, 82, 83 grid_legend(), 78, 92, 94,142 gridh=, 273 gridv=, 273 grouping=, 290 groups=, 57, 90, 93, 194 grownage=, 55 grp=, 213, 215 gvisAnnotatedTimeLine(), 120 gvisGeoMap(), 340 gvisMerge(), 122 gvisMotion(), 118
359
gvisTable(), 120
H h.diag=, 151 h.rng=, 184, 185 hadj=, 7, 102 halfwidth=, 128, 129 hang=, 239 hcl(), 27 hclust(), 239 hclust.method=, 150 heat.colors(), 30 heatmap(), 240 height=, 36, 37, 45, 71, 74, 120, 153, 331, 340, 345 heights=, 129 help(), 5 heplot(), 197 heplot3d(), 198 hetlab=, 226, 231 hetstat=, 231 hgap=, 93, 94, 197, 264 hist(), 60, 142 hist.angle=, 143, 144 hist.border=, 143, 144 hist.col=, 143, 151 hist.density=, 143, 144 Hmisc, 66, 101, 133 horiz=, 8, 71, 99 horizontal=, 51, 55, 57, 121, 271 hsv(), 27
I ICEcolor(), 222 ICEinfer, 219 ICEomega(), 223 ICEuncrt(), 219 id.cex=, 194 id.col=, 194 id.method=, 194 id.n=, 194 id_color=, 83 id_just=, 83 id=, 83 ident=, 185 identify(), 239 IDP.misc, 165, 166, 167, 169 idvar=, 118, 120 image(), 83 in.col=, 128 INaqua(), 341
360
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
inc=, 324 include.lowest=, 63 incr=, 228 init.angle=, 73, 74 inner_panel=, 260, 264, 269 innerborder, 54, 55 inside=, 71 insig=, 150 interact.pca=, 259 interactionPlot(), 293 interp(), 83, 85, 91, 333, 334 ip_args=, 269 ipairs(), 167, 169 iplot(), 166 IQCC, 279 is.na(), 129, 261, 263
J jitter=, 55, 270, 271 jj=, 185 just=, 232
K keep.y=, 259 keep_aspect_ratio=, 165 kernel=, 55, 176 key=, 275 key.axes=, 85, 86 key.title=, 85, 86 klaR, 216 kx=, 184, 185
L lab=, 15, 58 lab.c.attach.to.col=, 230 lab.c=, 225, 230 lab.diag=, lab.e.attach.to.col=, 230 lab.e=, 225, 230 lab.size=, 129, 130 labbe.meta(), 232 label.c=, 228 label.e=, 228 label.pos=, 133, 143, 173 label.prop=, 131, 133 label.radius=, 75 labels=, 7, 11, 44, 47, 63, 74, 76 labelcex=, 123, 124 labeling_args=, 161 labels_color=, 82, 83 labeltriangle=, 80
lambda=, 219, 290 las=, 15, 97 lattice, 56, 76, 89, 92, 93, 94, 139, 144, 147, 223 laxlab=, 124 layout(), 99 layout=, 145, 146 layout.matrix=, 158 leftcols=, 225, 229 leftlabs=, 225, 229 leg.digit=, 131 leg.title=, 131 legend(), 8, 42, 49, 54, 61, 68, 78, 95, 105, 123, 131, 169, 180, 235, 259, 329, 330 legend=, 155, 157, 158 legend.bty=, 139 legend.cex=, 139 legend.coords=, 192, 194 legend.freq=, 332, 335 legend.line.at=, 135, 139 legend.line.lwd=, 139 legend.line.text=, 139 legend.loc.num=, 139 legend.location=, 139 legend.max=, 332, 335 legend.min=, 332, 335 legend.plot=, 139 legend.point.at=, 135, 139 legend.point.pch=, 139 legend.point.text=, 139 legend.pos=, 332, 335 legend.text=, 71 legend.titl=, 139 legend.titl.cex=, 139 legend.titl.line=, 139 lend=, 15, 54 length(), 60, 67, 101, 142, 174, 336 length=, 7, 67, 92, 97, 131 lengths=, 133, 173 level.comb=, 228, 232 levels=, 53 85, 86, 194, 266 li=, 47 library(), 5 light.source=, 89 line=, 7, 9, 11 line.add=, 138 line.add.col=, 138 line.add.lty=, 138 line.add.lwd=, 138 line.by=, 138 line.col=, 138
ÍNDICE DE PAQUETES, FUNCIONES Y ARGUMENTOS GRÁFICOS line.lty=, 138 line.lwd=, 138 inecol=, 271 lineCol=, 290 lines(), 8, 52, 60, 101 lineType=, 290 lineWidth=, 290 liw=, 47 ll=, 55 lm(), 41, 45, 186, 194, 302 locationvar=, 340 locator(), 9, 42, 97 loess.threshold=, 194 log(), 266, 332 log=, 53 lowCI.mat=, 151 lower.panel=, 142, 143 lphi=, 89 LRaqua(), 341 ls(), 342 lsl=, 290 ltext=, 76, 89 ltheta=, 89 lty.fixed=, 229 lty.random=, 229 lty.smooth=, 273 lty.x=, 158 lty.y=, 158 lty.zones=, 273 lty=, 15, 48 lwd.smooth=, 273 lwd.x=, 158 lwd.y=, 158 lwd.zones=, 273 lwd=, 12 lxcol=, 124
M mai=, 16, 99 main_gp=, 161 main=, 16, 40 mapping=, 127 maptools, 327 mar=, 16, 99 margin.table(), 161 margin=, 165 margins=, 160, 271 MARSS, 188 MASS, 141 matplot(), 45 matrix(), 99, 274 max(), 99, 142
361
max.span=, 75 max3=, 79, 81 maxarrow=, 131 maxbar=, 48 MAXCLUSTER=, 239 maxColorValue=, 26, 321, 324, 339 maxcompete=, 252 maxdepth=, 252, 268 maxflow=, 131 maxLat=, 322, 324 maxLon=, 322, 324 maxstripline=, 55 maxsurrogate=, 252 maxwidth=, 55 Measurements=, 285 meta, 225 metabias(), 235 metabin(), 235 metacum(), 238 metainf(), 237 method=, 55, 85, 150, 227, 253 mex=, 16, 94 mfcol=, 16, 48 mfrow=, 16, 48 mgp=, 16, 48 MH.exact=, 228 middle=, 98 min3=, 79, 81 minarrow=, 131 minauto=, 259 minbar=, 48 minbucket=, 250, 252 mincriterion=, 268 minflow=, 131 minL.axis=, 169 minLat=, 322, 324 minLon=, 322, 324 minPH=, 169 minPW=, 169 minsplit=, 250, 252 mixDesign(), 296 mlab=, 278 mobobj=, 270 model=, 179, 253 mosaicplot(), 164 mtext(), 9, 32, 46 mtry=, 268 mvpart(), 255 mvpart, 255
N n.c=, 227
362
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
n.da=, 213, 215 n.e=, 227 n.iters=, 241 n.pca=, 213, 215 na.action=, 253 na.color=, 28, 332, 335 na.exclude(), 102, 196, 239, 248, 274, 336 na.rm=, 60, 62, 101, 240, 276 NA.rm=, 137 name=, 161 names(), 281, 291, 296, 300 names=, 51, 53, 55, 130 names.arg=, 71, 99 nboot=, 248 ncol=, 8, 54, 87, 148 ndig=, 123, 124 ndim=, 195 NeatMap, 240, 241 new=, 16, 45, 60 newdata=, 305, 308 newpage=, 82, 83 newsizes=, 308 ngamma=, 179 nlab.xaxis=, 169 nlab.yaxis=, 169 nlevels=, 85, 86, 89 nls=, 58 nMDS(), 241 node_barplot(), 270 node_bivplot(), 270 node_boxplot(), 270 node_density(), 270 node_hist(), 270 node_inner(), 270 node_scatterplot(), 270 node_surv(), 270 node_terminal(), 270 normalize=, 177, 179 notch=, 50, 51 now=, 137 now.line.col=, 137 now.line.lty=, 137 now.line.lwd=, 137 nresample=, 268 nticks=, 89 nullflow=, 129, 131 number=, 42, 216 numvar=, 120, 340
O o.include=, 176
off=, 161, 165 offset=, 11, 44, 71, 170, 328 offset_labels=, 162, 163 offset_varnames=, 162, 163 oma=, 16, 17, 96 omd=, 16, 17, 100 omi=, 16, 17, 100 onefile=, 36, 37 Operators=, 285 options(), 134 order(), 101 order=, 150 OrgMassSpecR, 170 outclab=, 228 outer(), 92 outer=, 7, 8, 9, 11, 57, 90, 94, 95, 147 outline=, 51, 149 overall=, 229 overalline=, 54, 55
P p.mat=, 148, 150 p.value.bar.alpha=, 154, 158 p.value.bar.color=, 158 p3line=, 278 padj=, 7, 9, 172 pagecentre=, 36, 37 pairs(), 140, 169 panel.boxplot(), 141, 143 panel.density(), 141, 143 panel.hist(), 141, 143 panel.qqnorm(), 141, 143 panel=, 57, 143 paper=, 36, 37 par(), 12 pareto.chart(), 280 parms=, 253 pars=, 51 Parts=, 285 party, 260, 265 partykit, 264 paste(), 32, 47, 58, 73, 334, 337 path=, 98 pca.info=, 216 pca.select=, 216 pca=, 257, 259 pcex=, 177, 179 pch.cex=, 151 pch.col=, 151 pch.x=, 158 pch.y=, 158
ÍNDICE DE PAQUETES, FUNCIONES Y ARGUMENTOS GRÁFICOS pch=, 17, 40 Pcol=, 176 pcol=, 278 pcr(), 288 pdf(), 34, 36, 45 peaks(), 169 per=, 278 perc.pca=, 216 persp(), 87, 91 pfcol=, 278 phi=, 88, 89, 294 pie(), 30, 73 pie3D(), 74 pixs=, 166, 169 plot(), 39, 40 plot=, 51 plot.add=, 259 plot.axes=, 85, 86 plot.default(), 95 plot.freqMAP(), 153 plotweb(), 129 plotCI(), 46, 66 plotCI=, 151 plotmath(), 32 plotrix, 28, 71, 98, 102,123, 128, 131, 172, 177, 330 plotwidth=, 232 png(), 32, 36, 153 point.cex=, 138 point.cex.mult.var=, 139 point.cex.mult=, 139 point.col=, 138 point.pch=, 138 points(), 10, 35, 42, 79, 336, 343 points.col=, 133 points.symbol=, 133 pointsize=, 36, 37, 153, 332, 345 polar.plot(), 172 polar.pos=, 173 poly.col=, 133 polygon(), 10, 44, 97, 127, 177, 239 pooled.events=, 225, 229 pooled.totals=, 225, 229 pooled=, 237 pop=, 160, 271 pos.cor=, 177, 179 pos=, 11 posi.da=, 214 posi.pca=, 214 possub=, 79, 81 postscript(), 34
363
ppmar=, 124 predict(), 45, 58 prepanel=, 57, 94, 147 pretty=, 94 print.byvar=, 228, 232 print.CMH=, 225, 228, 233 print.I2=, 230 print.p.val.Q=, 230 print.Q=, 230 print.tau2=, 230 printer=, 36, 37 prn=, 259 pro=, 324 prop_size=, 83 ps=, 18, 39 pscale=, 229 pscales=, 145, 147 pt.bg=, 8, 48 pt.lab=, 185 pty=, 18, 83 pval=, 270 px=, 185
Q qcc, 279, 303 qcc(), 303 qcc.groups(), 303 qcc.options(), 304 qq.bg=, 144, qq.cex=, 144 qq.col=, 144 qq.pch=, 144 qqline.col=, 144 qqline.lwd=, 144 quality=, 36, 37, 331 qualityTools, 279
R radial.labels=, 133 radial.lim=, 133 radial.plot(), 131 radial.pos=, 133 radius=, 73, 74 radlab=, 131, 133 rainbow(), 30, 63, 72, 264, 281, 336 randomize=, 287, 300 range=, 51, 170, 336 ratio.da=, 214 ratio.pca=, 214 raxlab=, 124
364
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
Rcmdr, 106, 243 read.csv2(), 44, 47, 70, 93, 127, 1332, 159, 166 read.dbf(), 154 read.jpeg(), 45 readTiff(), 45 rect(), 11, 26, 58, 142, 336 rect.col=, 125, 150 rect.color=, 29 rect.lwd=, 150 ref.interval=, 284 ref.sd=, 177, 179 ref=, 179 reg.line=, 192, 194 reg=, 6 region=, 341 rep(), 28, 135, 196, 274, 277 REP=, 216 replicates=, 291, 296 res=, 36, 37, 334 rescale=, 36, 37 reset.par=, 194 resid=, 185 response(), 285 rev.sort=, 273 rev=, 273 rgb(), 26, 321, 324 right=, 63 rightcols=, 225, 229 rightlabs=, 225, 229 rm(), 342, 346 robust=, 194 rosavent(), 274 rot_labels=, 162, 163 rot=, 89 rotate=, 42 row.values=, 90 row_vars=, 165 row1attop=, 143 rownames(), 68, 70, 102, 240, 248, 275, 277 rp.type=, 131, 133, 173 rpart(), 250 rpart, 250 rpart.control(), 250 rpart.pca(), 258 rpart.plot(), 250 rpart.plot, 250 RR.cochrane=, 228 rsq=, 259 rtiff, 45 rug(), 10, 35, 95, 271
run.GrapheR(), 112 rxcol=, 124 rxlim=, 104 rylim=, 104
S savesplitstats=, 268 scale=, 196, 216 scales=, 146 scatter.dapc(), 214 scatterplot(), 192 SciViews, 141 scores=, 195, 269 scree.da=, 214 scree.pca=, 214 screen=, 93 sd.arcs=, 177, 179 seed=, 219 seg.col=, 42 seg.lwd=, 42 segments(), 10, 58 selfarrow(), 98 sep=, 58, 73, 75, 77, 172, 174, 178 seq(), 29, 59, 85, 91, 102, 125, 154, 281 setwd(), 2 sfcol=, 278 sfrac=, 48 shade.col=, 150 shade.lwd=, 150 shade=, 88, 89 shadow=, 72 shem=, 278 show.centroid=, 133 show.colors(), 24 show.gamma=, 177, 179 show.grid.labels=, 133 show.grid=, 131, 133 show.names=, 54, 55 show.p.value.legend=, 154, 158 show.position=, 79, 81 show.radial.grid=, 133 show.values=, 123, 124 side=, 7, 9, 10, 35, 54, 55, 95, 174, 176 sig.level=, 148, 150 sigma=, 34, 58, 285 single=, 292 singular.ok=, 181 size.line=, 184, 185 size_n_color(), 125 size=, 42, 102, 127, 259
ÍNDICE DE PAQUETES, FUNCIONES Y ARGUMENTOS GRÁFICOS sizes=, 308 sm=, 228 smooth=, 192, 194 snip=, 254, 259 sort.after.subset=, 137 sort.ascending=, 137 sort.by=, 137 sort.na.last=, 137 sort=, 165, 272, 273 sortvar=, 229 space=, 71 spacing=, 165 spacing_args=, 165 span=, 192, 194 specCol=, 290 specWidth=, 290 spine(), 158, 160 split_vertical=, 165 splom(), 144, 147 SplomT(), 151 spread=, 192, 194 squaresize=, 232 SRaqua(), 341 srt=, 11, 18, 44, 35, 103, 214 stagger=, 128, 129 staircase.plot(), 128 start=, 30, 74, 85, 98, 133, 173 stats, 190 staxx=, 72 staxy=, 72 std.dev=, 290 Stratiplot(), 271 stretch=, 98 strip=, 57, 90, 273 studlab=, 225, 227 stump=, 268 sub=, 11, 18, 79, 80, 129, 191, 194, 239, 248, 294 sub2=, 130 subplot(), 101 subset(), 65, 146, 172, 261, 264 subset.c=, 135, 137 subset.r= 137 substitute(), 32, 58, 339 summary(), 45, 186, 195, 291, 302 sunflowerplot(), 40 surrogatestyle=, 250, 252 Surv(), 48, 180, 263 survfit(), 48, 180
365
survival, 48, 180, 263 svar=, 273
T
172,
130,
263,
300,
t(), 74 taguchiDesign(), 299 tapply(), 66 target=, 283, 284 taylor.diagram(), 177 tck=, 18, 48 tcl=, 18, 48 tcol=, 278 TE.fixed=, 234 TE.random=, 234 te=, 179 term=, 195 terminal_panel=, 260 ternaryplot(), 82 terrain.colors(), 30, 75 teststat=, 268 testtype=, 268 tetha=, 74 text(), 11, 26, 32, 44, 75, 99, 103, 125, 148, 169, 177, 214, 327, 334, 337, 338 text=, 9 text.add=, 259 text.fixed=, 229 text.fixed.w=, 229 text.random.w=, 229 text.random=, 229 theta=, 33, 75, 87, 89, 91, 294 thr=, 169 threshold=, 188, 190 tick=, 7 ticksize=, 10, 35, 95 ticktype=, 88, 89 tiff(), 34, 36, 334 time.format=, 63 time.step=, 63 timevar=, 118 titl=, 135, 137 title(), 11, 32, 40, 50, 80, 87, 95, 141, 197, 264, 280, 293 title=, 36, 37, 150, 228, 303 titlepos=, 104 titlevar=, 120 tl.cex=, 150 tl.col=, 150 tl.offset=, 150 tl_labels=, 163 tl_varnames=, 163
366
GRÁFICOS ESTADÍSTICOS Y MAPAS CON R
tnex=, 270 to=, 160 tolerance=, 283, 284 top.dot=, 185 top.labels=, 123, 124 topo.colors(), 30 topPad=, 273 total.col=, 128, 129 totals=, 129 tp_args=, 269 treeobj=, 270 triangle.plot(), 78 trmean=, 185 trtm=, 219 tweak=, 254 type=, 8, 9, 10, 28, 36, 37, 40, 45, 83, 95, 102, 148, 149, 150, 154, 155, 158, 164, 165, 196, 254, 269
U ui=, 47 uiw=, 47 unclass=, 140 under=, 254 uni=, 275 uniform=, 254, 259 unit=, 124 units=, 36, 37, 153, 332, 334, 345 untf=, 6 uppCI.mat=, 151 upper.panel=, 142, 143 use.n=, 259 usesurrogate=, 252 usl=, 290
V v.rng=, 184, 185 vadj=, 102 val.col=, 131 val.digit=, 131 val.ncol=, 131 val.size=, 131 val.title=, 131 val=, 129, 131 var.contrib=, 216 vararea(), 330, 334 varlen=, 251, 254 varnames=, 145, 147 varTypes=, 273 varwidth=, 51, 56 vcd, 78, 82, 92, 140, 158, 161, 196
venneuler(), 152 venneuler, 152 version=, 36, 37 vfont=, 84, 85 vgap=, 93, 94
W warn=, 228 weight=, 229 what=, 52, 55 which=, 8, 95, 186, 196, 259, 271 width=, 36, 37, 51, 71, 120, 153, 270, 331, 340 widths=, 270 win.print(), 34, 36 windows(),34, 36, 46, 76, 87, 102, 152, 283, 288, 293, 320, 327, 336 wireframe(), 89, 94, 147 wirePlot(), 294 wirePlot3(), 297 with=, 161 write.dbf(), 154
X x.axis.all=, 138 x.axis.custom.at=, 138 x.axis.custom.labels=, 138 x.axis=, 138 x.julian=, 138 x.lab=, 138 x.lim.extend=, 138 x.reference=, 138 x.scale=, 138 xadj=, 259 xaxp=, 18, 60, 103 xaxs=, 18, 95 xaxt=, 18, 46, 96, 102 xcex=, 126 xeffe=, 219 xend=, 104 xgrid=, 126 xl=, 29, 331, 335 xlab.pos=, 229 xlab=, 11, 19, 40 xlabs=, 191 xlas=, 126 xleft=, 10 xlim=, 19, 42 xlog=, 19, 58 xpd=, 8, 71 xpinch=, 36, 37
ÍNDICE DE PAQUETES, FUNCIONES Y ARGUMENTOS GRÁFICOS xpos=, 36, 37, 339 xr=, 29, 331, 335 xscale=, 165 xtics=, 105 xtrafo=, 269 xv=, 256, 259 xval=, 252, 259 xvmult=, 259 xvse=, 259 xyplot(), 146
Y y.axis.custom.at=, 137 y.axis.custom.labels=, 137 y.axis=, 137 yb=, 29, 331, 335 y.idlabels=, 137 y.jitter.factor=, 137 y.jitter=, 137 y.julian=, 138 y.lab=, 138 y.lim.extend=, 138 y.renum=, 137 y.var.type=, 136, 137 y.var=, 137 yadj=, 259 yaxp=, 19, 60 yaxs=, 19, 95 yaxt=, 19, 96 ycex=, 126 ygrid=, 126 ylab_tol=, 159 ylab=, 19, 40 ylabs=, 191 ylas=, 126 ylim=, 19, 42 ylines=, 264, 270 ylog=, 19, 58 ypinch=, 36, 37 ypos=, 36, 37, 339 yscale=, 270 yspace=, 165 yt=, 29, 331, 335 ytics=, 105 ytrafo=, 269
Z zlab=, 87, 88, 89, 91, 93, 294, 295, 298 zlim=, 86, 86, 89, 90 zmax=, 166, 169
zoneNames=, 272, 273 zones=, 272, 273 zoomInPlot()=, 103 zoomtitle=, 104 ztransf=, 169
367