statistics-76197_1280

Representación gráfica en R

Usualmente se suele decir que una imagen vale más que mil palabras. Pese que escritores como Tusón nieguen la veracidad de este refrán castellano, en el mundo de la estadística suele ser cierto.

En un post anterior se habló de como conectar nuestra base de datos con el programa estadístico R, extracción de datos de la misma en tablas y proceder a análisis sencillo de los parámetros estadísticos básicos. En este post vamos a ver como analizar los datos de forma visual, haciendo mucho hincapié en las instrucciones necesarias y parámetros a nuestra disposición para la customización de los mismos. Vamos a dividir el post en función de los varios gráficos que podemos realizar en R en función de su naturaleza.

Tipos de gráficos básicos

Árbol de tallo y hoja

Este gráfico fue propuesto por Tukey (1977) y a pesar de no ser un gráfico para presentación definitiva se utiliza a la vez que el analista recoge la información ve la distribución de los mismos. Estos gráficos son fáciles de realizar a mano y se usan como una forma rápida y no pulida de mirar los datos. Es útil para ver de un vistazo:

  • El centro de la distribución
  • La fórma general de la distribución
    • Simétrica, si las porciones a cada lado del centro son imágenes espejo de las otras
    • Sesgada a la izquierda, si la cola izquierda (los valores menores) es mucho más larga que los de la derecha (los valores mayores)
    • Sesgada a la derecha, si la cola derecha (los valores mayores) es mucho mlas larga que los de la derecha (los valores menores)
  • Desviaciones marcadas de la forma global de la distribución
    • Outliers: observaciones puntuales que caen muy fuera del patrón general de datos
    • Gaps: huecos en la distribución

 Cálculo:

Un diagrama de Tallo y Hojas se puede calcular con R haciendo uso de la función steam

steam(tablaDatos)

Por supuesto, y como es habitual en las funciones definidas en R, se pueden configurar mediante sus argumentos, que se muestran a continuación:

  • x: Vector numérico que albergará los datos iniciales para el estudio.
  • scale: Ampliar la escala del diagrama de tallo y hoja, por defecto es 1, es decir, genera un diagrama individual, para cada elemento, de tallo y hoja.
  • width: Anchura deseada del gráfico.
  • atom: Marca una tolerancia.

Ejemplo:

Tomemos por ejemplo, según el artículo de Juan C. Dürsteler en InfoVis.net, un  ejemplo de horario de trenes confeccionado a partir de un díptico de la línea Castelldefels-Barcelona/Sants recogido en la estación de Renfe. Originalmente el horario ocupa una tabla de 10 filas y 9 columnas más una columna "viuda" con el tren de las 22:38. Un total de 91 campos con formato hh.mm cada uno, 455 caracteres.

trenes

Horario de trenes del ejemplo

En el diagrama de Tallo y Hojas se representa la hora a la izquierda de la barra de separación | y los minutos de la salida de cada tren a la derecha. La frecuencia de los trenes se deduce fácilmente de la longitud de las filas y es, además, muy fácil ver en que minutos de cada hora pasan típicamente los mismos:

Tallo y hojas

Diagrama de tallo y hojas donde, a la izquierda de la barra se representan las horas, y a la derecha los minutos.

Strip chart

Los gráficos de puntos son elegantemente simples y permite numerosas variaciones. La única razón por la cual no se han vuelto populares es que los programas de hojas electrónicas no los elaboren presionando una tecla...

Cálculo:

Para pintar una distribución de puntos unidimensional en R utilizamos el comando stripchart

stripchart(x)

stripchart

Los argumentos de esta función son como sigue:

  • x: Objeto que contiene los datos a ser representados. Puede ser un sólo vector o una lista de vectores, cada uno correspondiendo a un componente del gráfico. También se puede especificar “x g” para indicar que las observaciones en el vector “x” van a ser agrupadas según los niveles del factor “g”.
  • method: Para especificar el método a ser empleado para separar puntos coincidentes. Si se especifica como “overplot” (por defecto) los puntos coincidentes son superpuestos. Si se especifica como “jitter”, para “to jitter the points”, y si se especifica como “stack” los puntos coincidentes son apilados,
  • jitter: Para especificar la cantidad de “jitter” o ruído a ser aplicado.
  • offset: cuando se muestran apilados utilizando el method stack, los puntos se apilan en varias lineas de altura(symbol widths).
  • vertical: Argumento booleano. Por defecto es “FALSE” y los puntos se representan horizontalmente.
  • group.names: Grupo de etiquetas a ser impresas al lado o debajo de cada gráfico
  • ...: Parámetros gráficos adicionales que pueden especificarse como argumentos

Ejemplos:

Combinamos en el siguiente ejemplo como crear una hoja con varias representaciones gráficas utilizando el comando par con cuatro representaciones diferentes de la misma tabla de datos Tiempos del tiempo utilizado por un centenar de universitarios para correr la maratón CONAVI.

  • par(mfrow=c(2,2))
  • stripchart(Tiempos, method=’overplot’, pch=1, main=’Grafico de puntos’, xlab=’Tiempos’) mtext("(A)",side=1,line=4,font=1)
  • stripchart(Tiempos,method=’stack’,pch=2, main=’Grafico de puntos’,xlab=’Tiempos’) mtext("(B)",side=1,line=4,font=1)
  • stripchart(Tiempos,method=’jitter’,pch=3, main=’Grafico de puntos’,xlab=’Tiempos’) mtext("(C)",side=1,line=4,font=1)
  • stripchart(Tiempos,method=’stack’,vertical=TRUE,pch=0, main=’Grafico de puntos’,ylab=’Tiempos’) mtext("(D)",side=1,line=4,font=1)
marathon plot

Gráficos de puntos representando el tiempo tardado en correr la maratón CONAVI.

Diagrama de Cajas

Este ha sido un aporte fundamental realizado por Tukey (1977). Es un gráfico simple, ya que se realiza básicamente con cinco números, pero poderoso. Se observa de una forma clara la distribución de los datos y sus principales características. Permite comparar diversos conjuntos de datos simultáneamente. Como herramienta visual se puede utilizar para ilustrar los datos, para estudiar simetría, para estudiar las colas, y supuestos sobre la distribución, para comparar diferentes poblaciones.

Este gráfico contiene un rectángulo, usualmente orientado con el sistema de coordenadas tal que el eje vertical tiene la misma escala del conjunto de datos. La parte superior y la inferior del rectángulo coinciden con el tercer cuartil y el primer cuartil de los datos. Esta caja se divide con una línea horizontal a nivel de la mediana. Se define un “paso” como 1.5 veces el rango intercuartil, y una línea vertical (un bigote) se extiende desde la mitad de la parte superior de la caja hasta la mayor observación de los datos si se encuentran dentro de un paso. Igual se hace en la parte inferior de la caja. Las observaciones que caigan más allá de estas líneas (outliers) son dibujadas individualmente.

Cálculo:

Para dibujar un diagrama de caja y bigotes de una variable nos basta hacer

boxplot(x)

Si deseamos varios diagramas uno al lado del otro de las variables x1, x2, ..., xn podemos hacerlo del siguiente modo

boxplot(x1, x2, ..., xn)

boxplot

Por supuesto, se pueden configurar mediante sus argumentos, que se muestran a continuación:

  • x, ...: Los datos que van a ser representados con el boxplot. Puede ser un conjunto de vectores separados, cada uno correspondiendo a un boxplot componente o una lista que contiene a tales vectores. Alternativamente, una especificación de la forma “x ∼ g” puede ser dada para indicar que las observaciones en el vector ”x” van a ser agrupadas de acuerdo a los niveles del factor “g”. En este caso, el argumento “data” puede usarse para par valores para la variables en la especificación. ‘NA’s son permitidos en los datos.
  • range: Determina la extensión de los bigotes de la caja. Si es positivo, los bigotes se extienden hasta el dato más extremo, el cual no es más que el “rango” por rango intercuartílico de la caja. Un valor de cero hace que los bigotes se extiendan hasta los datos extremos.
  • width: Un vector que da los anchos relativos de las cajas.
  • varwidth: Si es “TRUE”, las cajas son dibujadas con anchos proporcionales a las raíces cuadradas del número de observaciones en los grupos.
  • notch: Si es “TRUE”, una cuña es dibujada a cada lado de las cajas. Cuando las cuñas de dos gráficos de caja no se traslapan, entonces las medianas son significativamente diferentes a un nivel del 5%.
  • names: Un grupo de etiquetas a ser impresas debajo de cada boxplot.
  • boxwex: Un factor de escala a ser aplicado a todas las cajas. Cuando sólo hay unos pocos grupos, la apariencia del gráfico puede mejorarse haciendo las cajas más angostas.
  • data: “data.frame”, “list”, o “environment” en el cual los nombres de las variables son evaluados cuando “x” es una fórmula.
  • plot: Si es “TRUE” (por defecto) entonces se produce el gráfico. De lo contrario, se producen los resúmenes de los boxplots.
  • border: Un vector opcional de colores para las líneas de las cajas y debe ser de longitud igual al número de gráficos.
  • col: Si se especifica, los colores que contiene serán usados en el cuerpo de las cajas.
  • log: Para indicar si las coordenadas “x” o “y” o serán graficadas en escala logarítmica.
  • pars: Los parámetros gráficos pueden ser pasados como argumentos para el boxplot.
  • horizontal: Si es “FALSE” (por defecto) los boxplots son dibujados verticalmente.
  • add: Si es “TRUE” agrega un boxplot al gráfico actual.
  • formula: Una fórmula tal como “y ∼ x”.
  • data: Un data.frame (o lista) del cual las variables en “fórmula” serán tomadas.
  • subset: Un vector opcional para especificar un subconjunto de observaciones a ser usadas en el proceso de ajuste.
  • na.action: Una función la cual indica lo que debería pasar cuando los datos contienen “NA’s”

Ejemplo:

Imaginemos que tenemos los datos sobre los pasajeros por viaje de cierta línea de tren en varios años diferentes. Si las variables vienen almacenadas como columnas de una tabla pasajeros, entonces:

boxplot(pasajeros[,2]~pasajeros[,1], notch=TRUE, main=’Promedio de pasajeros transportados\n por viaje - A~no’, xlab=’años’, ylab=’número por viaje’)

pasajeros_tren

Histograma

El histograma es el gráfico estadístico por excelencia. El histograma de un conjunto de datos es un gráfico de barras que representan las frecuencias con que aparecen las mediciones agrupadas en ciertos rangos o intervalos. Para uno construir un histograma se debe dividir la recta real en intervalos o clases (algunos recomiendan que sean de igual longitud) y luego contar cuántas observaciones caen en cada intervalo. Es tal vez el único gráfico que ha tenido un desarrollo teórico en un área que se conoce com estimación de densidades (Scott, 1992). La idea de agrupar datos en forma de histogramas se conoce desde 1662 con el trabajo de Graunt. Sin embargo, es hasta 1926 cuando aparecen las primeras reglas sobre su contrucción con la fórmula de Sturges para determinar el número de barras  k = 1+log_2(n) con k el número de barras y el tamaño de la muestra.

Los pasos para construir el histograma son:

  • Definir los intervalos o clases de igual longitud
  • Contar el número de observaciones que caen en cada clase o intervalo. A esto se le llama frecuencia del intervalo.
  • Calcular la frecuencia relativa como

 FR = \frac{# Observaciones\ del\ intervalo }{Total\ de\ datos,\ n}

  • Dibujar los rectángulos cuyas alturas son proporcionales a las frecuencias relativas

Cálculo:

Podemos calcular un histograma de los datos de una columna haciendo:

hist(x)

Entre los argumentos que acepta un histograma, tenemos por ejemplo:

  • x: Vector de valores para el que se construye el histograma.
  • breaks: Puede ser un valor con el cual se indica el número aproximado de clases o un vector cuyos elementos indican los puntos líımites entre las clases o intervalos.
  • freq: argumento booleano; si se especifica como “TRUE”, el histograma representará las frecuencias absolutas o conteo de datos en cada clase; si se especifica como “FALSE”, se reprentarán las frecuencias relativas. Por defecto, este argumento toma el valor de “TRUE” siempre y cuando los intervalos sean de igual ancho.
  • probability: Especifica un alias para “!freq”, para compatibilidad con S.
  • include.lowest: Argumento booleano; si se especifica como “TRUE”, un “x[i]” igual a los equal a un valor “breaks” se incluirá en la primera barra, si el argumento “right = TRUE”, o en la última en caso contrario.
  • right: Argumento lógico; si es “TRUE”, los intervalos son abiertos a la izquierda - cerrados a la derecha (a,b]. Para la primera clase o intervalo si “include.lowest=TRUE” el valor más pequeño de los datos será incluido en éste. Si es “FALSE” los intervalos serán de la forma [a,b) y el argumento “include.lowest=TRUE” tendrá el significado de incluir el “más alto”.
  • col: Para definir el color de las barras. Por defecto, “NULL” produce barras sin fondo.
  • border: Para definir el color de los bordes de las barras.
  • plot: Argumento booleano. Por defecto es “TRUE”, y el resultado es el gráfico del histograma; si se especifica como “FALSE” el resultado es una lista de conteos por cada intervalo.
  • labels: Argumento booleano o carácter. Si se especifica como “TRUE” coloca etiquetas arriba de cada barra.
  • nclass: Argumento entero. Para compatibilidad con S, “nclass=n” es equivalente a “breaks=n”.
  • ...: Parámetros gráficos adicionales a “title” y “axis”

Ejemplos:

Si observamos las ventas por hora de  tickets de metro en una estación dada, entonces podemos dibujar su histograma de frecuencias como

hist(salesTable, breaks = 24)

histogram

Diagramas Circulares

El uso de gráficos circulares o pasteles es bastante común entre personas no profesionales en estadística y lamentablemente se ha trivializado tanto que si en muchas de las situaciones donde se usan se suprimieran se ahorrarían muchas hojas de papel. A veces se presenta un gráfico de pastel para mostrar que en una muestra el 50% son hombres y el 50% mujeres.

Este gráfico es una gran herramienta para datos porcentuales tomadas sobre individuos o elementos, por ejemplo un análisis químico sobre el porcentaje de componentes de muestras tomadas en diversas áreas. En este caso realmente este es un gráfico multivariable que puede utilizarse para comparar diferencias o similitudes y realizar agrupamientos.

Cálculo:

En R este tipo de gráfico se obtiene con la función piechart

piechart(x, labels=names(x), shadow=FALSE, edges=200, radius=0.8, col=NULL, main=NULL, ...)

Entre los argumentos que admite, tenemos:

  • x: Vector de cantidades positivas, los cuales son presentados como las áreas en el gráfico.
  • labels: Un vector de caracteres “strings” que dan nombres a las áreas.
  • shadow: Un vector booleano que indica si un efecto de sombrea será aplicado para el gráfico, cuando se utilizan colores de relleno.
  • edges: Aproxima la linea exterior circular mediante un polígono con el número de lados especificado, que por defecto es 200.
  • radius: El pastel es dibujado centrado en una caja cuadrada cuyos lados se mueven de -1 a 1. Si se usan etiquetas largas puede ser necesario usar radios más pequeños.
  • col: Un vector de colores, para rellenar los sectores del gráfico.
  • main: Para dar título al gráfico.

Ejemplo:

Si tenemos una tabla con datos de temperaturas varias dadas en forma de strings que pueden tomar los valores 'Muy baja', 'Baja', 'Media', 'Alta' , entonces

piechart(temperaturas, col=rainbow(24))

piechart

Diagrama de Barras

Este gráfico es una modificación más clara del gráfico de tarta. Los gráficos de barras son suficientemente flexibles para ser adaptados a situaciones donde el trabajo gráfico ha tenido poco éxito, como lo es el análisis de datos categóricos. Hofmann (1998-1999) analizó el problema de la Paradoja de Simpson (un problema que surge cuando se trabajan con tablas de contingencia marginales en lugar de una tabla completa) en el caso de la tragedia del Titanic, utilizando solo gráficos de barras.

barplot

Cálculo:

Para obtener este tipo de gráficos en R, la función base es barplot, como se describe a continuación:

barplot(x)

Entre los argumentos que acepta hallamos:

barplot(height, width = 1, space = NULL, names.arg = NULL, legend.text = NULL, beside = FALSE, horiz = FALSE, col = heat.colors(NR), border = par("fg"), main = NULL, sub = NULL, xlab = NULL, ylab = NULL, xlim = NULL, ylim = NULL, axes = TRUE, axisnames = TRUE, inside = TRUE, plot = TRUE, ...)

  • height: Vector o matriz de valores que describen las barras. Si es un vector, entonces el gráfico corresponde a un secuencia de barras rectangulares cuyas alturas corresponden a los valores del vector. Si es una matriz y “beside=FALSE” entonces cada barra del gráfico corresponde a una columna de forma que los valores en cada columna serán representados por sub barras apiladas, pero si “beside=TRUE” entonces los valores en cada columna serán yuxtapuestos en vez de apilados.
  • width: Es opcional, para especificar mediante un vector el ancho de las barras.
  • space: Para fijar el espacio entre barras, como una fracción del ancho promedio de éstas. Puede especificarse con un sólo número o un número por barra. En el caso de que el objeto representado sea una matriz y “beside=TRUE”, este argumento puede darse por dos números el primero para el espacio entre barras del mismo grupo y el segundo para el espacio entre grupos. Por defecto está ajustado a ’c(0,1)’ para el caso de objeto matriz y beside=TRUE.
  • names.arg: Un vector de nombres para colocarlos debajo de cada barra o grupo de barras. Si se omite, entonces los nombres son tomados de los atributos de nombres que esten contenidos en el objeto especificado en “height”.
  • legend.text: Un vector de texto para construir una leyenda para el gráfico. Sólo es útil si “height” es una matriz, en cuyo caso las leyendas corresponderán a sus filas.
  • beside: Un valor booleano. Si es “FALSE” las columnas de “height” serán representadas por barras apiladas y si es “TRUE” entonces serán representadas por barras yuxtapuestas.
  • horiz: Un valor lógico. Si es “FALSE” las barras son dibujadas verticalmente.
  • col: Para especificar un vector de colores para las barras.
  • border: Para indicar el color a ser usado en los bordes de las barras.
  • main,sub: Para titular y subtitular el gráfico.
  • xlab: Para dar nombre al eje x.
  • ylab: Para dar nombre al eje y.
  • xlim: Para delimitar el rango de valores en el eje x.
  • ylim: Para delimitar el rango de valores en el eje y.
  • axes: Argumento booleano. Si es “TRUE”, dibuja el correspondiente eje.
  • axisnames: Argumento lógico. Si es “TRUE”, y si se ha especificado “names.arg”, entonces el otro eje es dibujado y etiquetado.
  • plot: Argumento lógico. Si es “FALSE” no se produce gráfico

Ejemplos

Retomando el ejemplo de las temperaturas que vimos con el diagrama circular,

barplot(Temperatura,space=0, col=c(’gray30’,’gray40’,’gray50’,’gray60’), main=’Temperaturas en Antioquia’,ylab=’Frecuencias’)

barra

Si tenemos por ejemplo una tabla con población y temperatura, podemos crear una tabla de doble entrada con ambos datos en columna:

frec.tipos.temperatura.poblacion<-table(tipo.poblacion, tipo.temperatura)

y hacer unas representaciones con barras laterales o apiladas del tipo

barplot(frec.tipos.temperatura.poblacion, beside=T, legend.text= rownames(frec.tipos.temperatura.poblacion), ylim=c(-0.5,25), main=’Distribucion de poblacion por rangos de temperatura\n en Antioquia’, xlab=’Tipo Temperatura’, ylab=’frec. por tipo de pob’)

barrasSeparadas

barplot(frec.tipos.temperatura.poblacion, beside=FALSE,legend.text= rownames(frec.tipos.temperatura.poblacion), main=’Distribucion de poblacion por rangos de temperatura\n en Antioquia’, xlab=’Tipo Temperatura’, ylab=’frec.por tipo de pob’)

barras apiladas

Configuraciones varias de los gráficos

A veces queremos personalizar los gráficos más allá de lo que hemos ido describiendo en cada sección pertinente. Aglutinamos aquí las personalizaciones más comunes y utilizadas por cada tipo de gráfico.

Cambio de colores

Para cambiar el color de los gráficos tenemos la opción de asignarlo a la variable col, en caso de puntos, bordes, barras,...

col = c('blue', 'grey', 'red', 'yellow', 'orange', 'green', 'pink', 'purple', 'gold')

o bien a la variable bg en caso de desear cambiar el fondo de las gráficas

bg = c('blue', 'grey', 'red', 'yellow', 'orange', 'green', 'pink', 'purple', 'gold')

Poner en vertical

vertical=T

Datos absolutos vs Relativos

Por defecto, los datos que se representan son los de la tabla que pasamos por parámetro a las diferentes funciones de dibujo. A veces nos interesará alternar entre datos absolutos (para conocer el total de sujetos que cumplen una determinado condición) y relativos (qué porcentaje de individuos cumplen una determinada condición). Para ello alternamos con:

prob=F

prob=T

Título

main = ‘titulo_del_grafico’

Subtítulo

sub = ‘subtitulo_del_grafico’

Límites de los ejes

xlim = c(limite_inferior, limite_superior)

ylim = c(limite_inferior, limite_superior)

Ejes logarítmicos

log='<x|y|xy>'

Etiquetas de los ejes

xlab = ‘etiqueta_del_eje_x’

ylab = ‘etiqueta_del_eje_y’

Tipo de gráfico

Para añadir límeas, puntos, ambos, ninguno en el caso de gráficos de dispersión

type '<l|pp|b|n>'

Leyenda

legend = c(‘nombre_serie_1’, ‘nombre_serie_2’,...,‘nombre_serie_n’)

En resumen

El poder tener una representación gráfica ayuda mucho a la estadística. El transmitir conocimientos a gente no versada en la materia, convencer de hechos o evidencias suele ser más sencillo que con largos informes y parrafadas de textos técnicos. Por esto esperamos que el artículo os haya sido de utilidad. Tanto si estáis en una carrera de ciencias como os dedicáis al análisis de datos en algún departamento de Business Intelligence de una empresa, seguro que este habrá sido un buen punto de partida para iniciaros en el análisis estadístico.

Sin duda alguna existen muchos más tipos de gráficos y personalizaciones posibles, pero de estos hablaremos ya en otra ocasión.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *