El paquete de ggplot

# Data Vizualisation - 17 de julio de 2018
library(tidyverse)
## -- Attaching packages ----------------------------------------------------------------------------------------------------------- tidyverse 1.2.1 --
## v ggplot2 3.1.0     v purrr   0.2.5
## v tibble  1.4.2     v dplyr   0.7.8
## v tidyr   0.8.2     v stringr 1.3.1
## v readr   1.1.1     v forcats 0.3.0
## -- Conflicts -------------------------------------------------------------------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()

Vamos a trabjar en un dataset que viene de serie en R para practicar, la pregunta de negocio es:

Este planteamiento lleva a otras preguntas:

Este dataset podrá ser encontrado dentro de la librería ggplot2

mpg <- ggplot2::mpg

Toda la información que nos da el dataset (por ejemplo que es cada variable). En este caso en concreto, podemos usar la función help(mpg) para obtener más información, y R nos lo mostrarà. Para este caso tenemos dos variables que son representativas:

names(ggplot2::mpg)
##  [1] "manufacturer" "model"        "displ"        "year"        
##  [5] "cyl"          "trans"        "drv"          "cty"         
##  [9] "hwy"          "fl"           "class"

Para saber más información sobre la capacidad de un galón, buscamos en google. Result: 1 galón = 4,5460902819948 litros (redondeado a 4,5461 litros).

Nuestro primer gráfico en ggplot2

ggplot(data = mpg) + # crea una capa con el dataset
  geom_point(mapping = aes(x = displ, y = hwy)) # añade otra capa de puntos

En este gráfico podemos ver una relación negativa entre las dos variables, contra más displ tengo, menos millas puedo hacer. La función mapping dentro de ggplot, servirá para indicar como las variables del dataset van a ser “mapeadas” a variabels para hacer un gráfico.

Cambiando los mappings estéticos del gráfico

Primero, entender el gráfico que hemos hecho (gráfico previo) y realizar hipótesis. Por ejemplo, para enteder los puntos que tienen un “displ” elevado y un “hwy” también por encima de la media, ¿cuál podría ser la hióotesis? Podrían ser coches híbridos por ejemplo, aumentando el número de quilometros. Podríamos ir a la variable “class” del data set para ver si estos puntos son diferentes. ¿Cómo podríamos visualizar estos datos en un ggplot?

ggplot(data = mpg)+
  geom_point(mapping = aes(x = displ, y = hwy, color = class))

En efecto vemos que a class “2seater”, tiene un tamaño de diposito más grande pero los quilometros que puede hacer son superiores que los de su grupo. Puede que no sean coches híbridos, sino coches deportivos, por eso tienen dos seaters, dándoles un motor más grande, pero pueden hacer más quilometros gracias a su forma aerodinámica u otros factores. También podríamos hacer diferencias por tamaño y no por colores, ejemplo:

ggplot(data = mpg)+
  geom_point(mapping = aes(x = displ, y = hwy, size = class))
## Warning: Using size for a discrete variable is not advised.

Nos sale un warning avisando que hace un size con una variable categórica no es muy correcto, pero lo hace igual. También podemos hacer otros parametros de aesthetics, como alpha:

ggplot(data = mpg)+
  geom_point(mapping = aes(x = displ, y = hwy, alpha = class))
## Warning: Using alpha for a discrete variable is not advised.

Por ejemplo también se puede modificar las formas de los puntos, donde se crearan formas para cada una de las variables categóricas. Si no hay suficientes formas, no se añadira ninguna forma.

ggplot(data = mpg)+
  geom_point(mapping = aes(x = displ, y = hwy, shape = class))
## Warning: The shape palette can deal with a maximum of 6 discrete values
## because more than 6 becomes difficult to discriminate; you have 7.
## Consider specifying shapes manually if you must have them.
## Warning: Removed 62 rows containing missing values (geom_point).

Por lo tanto, toda propiedad visualizar que se quiera añadir en ggplot, se deberá añadir en aes(), la estética. Se podrían añadir de forma manual las estéticas para ggplot de la siguiente forma:

ggplot(data = mpg)+
  geom_point(mapping = aes(x = displ, y = hwy), color = "red")

Aquí hemos definido la apariencia global del gráfico, fuera de la estética, separado por una “,”. Podemos configurar manualmente diferentes puntos:

  • color = nombre del color en formato string (como en el caso anterior)

  • size = tamaño del punto en milimetros(mm)

  • shape = forma del punto con número desde el 0 al 24

Googlear las formas de shape para hacer la preselección de los que nos puede interesar es la mejor opción. Por ejemplo, de forma a 0 a 14, son formas huecas que solo se e puede cambiar el color. de la 15 a la 20 son formas rellenas de color que se le puede cambiar el color otra vez. Por ejemplo:

ggplot(data = mpg)+
  geom_point(mapping = aes(x = displ, y = hwy), 
             shape = 23, size = 10, color = "red", fill = "yellow")

Podemos usar operadores lógicos para obtener más información en los gráficos, por ejemplo:

ggplot(data = mpg)+
  geom_point(mapping = aes(x = displ, y = hwy, color = displ<4))

Examen: estéticas en ggplot

str(mpg)
## Classes 'tbl_df', 'tbl' and 'data.frame':    234 obs. of  11 variables:
##  $ manufacturer: chr  "audi" "audi" "audi" "audi" ...
##  $ model       : chr  "a4" "a4" "a4" "a4" ...
##  $ displ       : num  1.8 1.8 2 2 2.8 2.8 3.1 1.8 1.8 2 ...
##  $ year        : int  1999 1999 2008 2008 1999 1999 2008 1999 1999 2008 ...
##  $ cyl         : int  4 4 4 4 6 6 6 4 4 4 ...
##  $ trans       : chr  "auto(l5)" "manual(m5)" "manual(m6)" "auto(av)" ...
##  $ drv         : chr  "f" "f" "f" "f" ...
##  $ cty         : int  18 21 20 21 16 18 18 18 16 20 ...
##  $ hwy         : int  29 29 31 30 26 26 27 26 25 28 ...
##  $ fl          : chr  "p" "p" "p" "p" ...
##  $ class       : chr  "compact" "compact" "compact" "compact" ...
ggplot(data = mpg, aes(x = displ, y = hwy, color = displ, size = hwy, fill = cty)) +
  geom_point()

Los facets de ggplot

Con el objetivo de mostrar categorías y subcatgarías podemos hacer uso de los facets. Las variables que usaremos deben ser discretas:

ggplot(data = mpg)+
  geom_point(mapping = aes(x = displ, y = hwy))+
  facet_wrap(~class, nrow = 3) # definimos la variable discreta y el n?mero de filas que queremos mostrar de los  gr?ficos. ?ste solo va relacionado con la distribuci?n de las variables.

Si queremos comparar dos variables, haremos uso de facet_grid()

ggplot(data = mpg)+
  geom_point(mapping = aes(x = displ, y = hwy))+
  facet_grid(drv~cyl) # taambi?n podr?amos usar (.~cyl) para dividirlo por una sola variable. Busca la geometria entre la variable(s) y los datos

Subplots con facets

?facet_wrap
## starting httpd help server ... done

La diferentes geometrias de ggplot2

El objeto geométrico es el que se usa en ggplot para representar un gráfico, como los gráficos de barra. Por ejemplo tenemos la opción de geometría suavizada:

ggplot(data = mpg)+
  geom_smooth(mapping = aes(x = displ, y = hwy))
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

Podemos añadir y modificar las lineas, por ejemplo como en el caso anterior:

ggplot(data = mpg)+
  geom_smooth(mapping = aes(x = displ, y = hwy, linetype = drv))
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

En este grafico veremos los datos por 3 categorías, los coches a 4 ruedas tienen un desplazamiento muy inferior que los de 2 delanteras. También podemos percibir la concentración de los datos, o detectar una desvación muy grande para las dos traseras, en displ +- displ.

También podemos combinar gráficos para añadir capas y ver mas información:

ggplot(data = mpg)+
  geom_point(mapping = aes(x = displ, y = hwy, color = drv))+
  geom_smooth(mapping = aes(x = displ, y = hwy, linetype = drv, color = drv))
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

Podemos encontrar más información de ggplot en el spreadsheet de RStudio

Combinar gráficos y añadir dimensiones de visualización

Existe una estética llamada group, para usar cualquier variable categórica para usar diferentes variables a la vez. Para cada variable que hayamos agrupado le podremos usar para analizar diferentes variables. Por si solo la variable group no nos dice nada, es por eso que deberemos añadir una leyenda:

ggplot(data = mpg)+
  geom_smooth(mapping = aes(x = displ, y = hwy, group = drv, color = drv),
              show.legend = T)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

Si queremos simplificar el código para no repetir constantemente la información de x y de y. Por lo tanto añadiremos los valores de x y de y en el ggplot:

ggplot(data = mpg,mapping = aes(x = displ, y = hwy))+
  geom_smooth()+
  geom_point()
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

En el caso anterior, sería una forma de configurar unos mapping globales desde ggplot, pero podemos seguir configurando mappings locales dentro de las propias geometrías.

ggplot(data = mpg,mapping = aes(x = displ, y = hwy))+
  geom_point(mapping = aes(shape = class))+
  geom_smooth(mapping = aes(color = drv))
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## Warning: The shape palette can deal with a maximum of 6 discrete values
## because more than 6 becomes difficult to discriminate; you have 7.
## Consider specifying shapes manually if you must have them.
## Warning: Removed 62 rows containing missing values (geom_point).

Podemos también usar un subconjunto de datos dentro del propio dataset con una geometría local, para así tener una información más específica:

ggplot(data = mpg,mapping = aes(x = displ, y = hwy))+
  geom_point(mapping = aes(color = class))+
  geom_smooth(data = filter(mpg, class == "suv"), se = F) # se nos  elimina la sombra alrededor de la linea
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

Usaremos el parámetro stroke para añadir gráficos que nos den más valor, por ejemplo:

ggplot(data = mpg,mapping = aes(x = displ, y = hwy, color = drv))+
  geom_point(mapping = aes(fill = drv), size = 4, shape = 23, col = "white", stroke = 2)

Tarea 4: geometrías con ggplot

ggplot(data = mpg, mapping = aes(x=displ, y = hwy,color = drv)) + 
  geom_point() + 
  geom_smooth( se = F)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

  1. EL parámtro show legend nos permite mostrar (o no mostrar) la leyenda de la información al lado derecho del gráfico. En el anterior gráico hace referencia a al color según la variable “drv”.

  2. El parámetro geom_smooth() nos permite ver la tendéncia de los datos. Cuando el própio gráfico tiene mucho ruido, o mucha información que no nos permite ver la tendencia que seguien los datos, usar geom_smooth() es una muy buena técnica. Si la quisatsemos no nos sería tan fácil ver como la tendencía de los datos.

ggplot(data = mpg, mapping = aes(x=displ, y = hwy)) + 
  geom_point() + 
  geom_smooth()
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

El primero nos mostrará un scatter plot de “displ” y “hwy”, y la tendencía que siguen estas dos variables.

ggplot(data = mpg) + 
  geom_point(mapping = aes(x=displ, y = hwy)) + 
  geom_smooth(mapping = aes(x=displ, y = hwy))
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

El segundo nos mostrará la misma información, pero las variables la habremos intruducido en cada uno de los tipos de geometrías que hemos insertado dentro del gráfico.

ggplot(mpg, aes(displ, hwy, line = drv)) +
  geom_point() +
  geom_smooth(se = F)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

ggplot(mpg, aes(displ, hwy, color = drv)) +
  geom_point() +
  geom_smooth(se = F)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

ggplot(mpg, aes(displ, hwy)) +
  geom_point(aes(color = drv, shape = drv)) +
  geom_smooth(se = F)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

ggplot(mpg, aes(displ, hwy)) +
  geom_point(aes(color = drv, shape = drv)) +
  geom_smooth(aes(linetype = drv), se = F)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

ggplot(data = mpg,mapping = aes(x = displ, y = hwy, color = drv))+
  geom_point(mapping = aes(fill = drv), size = 3, shape = 23, col = "white", stroke = 2)

Transformaciones estadísticas básicas

Trabajaremos con un dataset de ggplot2 llamado “diamantes”

diamonds <- ggplot2::diamonds

Empezemos a usar ggplot con este dataset, en concreto, los gráficos de barras:

ggplot(data = diamonds)+
  geom_bar(mapping = aes(x = cut))

# este grafico nos mostrara la frequencia  por cada una de las categorias

Con el uso de stat(), que quiere decir statistical transformation, podemos hacer cálculos útiles dentro de estos gráficos de barras. La gráfica que nos mostrará será exactamente igual que el anterior.

ggplot(data = diamonds)+
  stat_count(mapping = aes(x = cut))

Ahora miraremos como cambiar las frequencias estadísticas. Para eso usaremos la función “tribble” que nos permitirá crear un dataset donde nosotros hayamo hecho unos cálculos previos:

demo_diamonds <- tribble(
  ~cut,         ~freqs, # usamos la ~ para indicar que es una variable
  "Fair",       1610,
  "Good",       4906,
  "Very Good",  12082,
  "Premium",    13791,
  "Ideal",      21551
)

De esta forma vamos a poder hacer nosotros el gráfico de barras:

ggplot(data = demo_diamonds)+
  geom_bar(mapping = aes(x = cut, y = freqs), stat = "identity")

# con el stat identyty le subministramos al parametro geom_bar la variiable x e y, evitando que  R haga un conteo automatico de cada una  de las lineas como en el anterior plot.

Imaginemos que no queremos ver os valores absolutos, sino su peso proporcional respecto el total de valores. Se hará de la siguiente forma:

ggplot(data = diamonds)+
  geom_bar(mapping = aes(x = cut, y = ..prop.., group =1))

# la variable group nos dice --> quiero la proporci?n agrupada en la x (1)

Realizar una tranformación estadísitca para resumir cada uno de los valores de y en la varaible x:

ggplot(data = diamonds)+
  stat_summary(mapping = aes(x = cut, y = depth),
               fun.ymin = min,
               fun.ymax = max,
               fun.y = mean)

# calculara la media de la desviacion estandar y la pintara donde pertoque. usando las funciones fuera de los parametros esteticos, podemos visualizar otros parametros estadisticos que puedan ser relevantes, como el minimo, maximo, mediana o promedio.

Taera 5: transformaciones estadísticas con ggplot

  1. ¿Qué hace el parámetro geom_col? ¿En qué se diferencia de geom_bar?

  2. La gran mayoría de geometrías y de stats vienen por parejas que siempre se utilizan en conjunto. Por ejemplo geom_bar con stats_count. Haz una pasada por la documentación y la chuleta de ggplot y establece una relación entre esas parejas de funciones. ¿Qué tienen todas en común?

  3. ¿Qué variables calcula la función stat_smooth? ¿Qué parámetros controlan su comportamiento?

  4. Cuando hemos pintado nuestro diagrama de barras con sus proporciones, necesitamos configurar el parámetro group = 1. ¿Por qué?

  5. ¿Qué problema tienen los dos siguientes gráficos?

ggplot(data = diamonds) + 
  geom_bar(mapping = aes(x = cut, y = ..prop..))

ggplot(data = diamonds) + 
  geom_bar(mapping = aes(x = cut, fill = color, y = ..prop..))

El parámetro “position” en el gráfico

Podemos colorear los gráficos y dar formas para hacer los gráficos más representativos:

ggplot(data = diamonds)+
  geom_bar(mapping = aes(x = cut, fill = cut))

Position = “stack”

Pero podemos apilar información para sacar más insights, con el parámetro que viene por defecto, el position “stack”

ggplot(data = diamonds)+
  geom_bar(mapping = aes(x = cut, fill = color))

Position = “identity”

El parametro position nos permite personalizar la posición de la información de varios parametros en el gráfico. Por ejemplo, position “identity”,

ggplot(data = diamonds, mapping = aes(x = cut, fill = clarity))+
  geom_bar(alpha = 0.2, position = "identity")

# No se puede apreciar muy bien en la grafica, pero identity nos muestra todas las variables partiendo de  0, por lo tanto, para ideal, VS1 es la variable con mas observaciones

Para ver mas información, podríamos conservaar solo el borde:

ggplot(data = diamonds, mapping = aes(x = cut, colour = clarity))+
  geom_bar(fill = NA, position = "identity")

Position = “fill”

Este parámetro es muy similar al staked, opción original, y hace que todas las barres sean de la misma altura; ideal para comparar proporciones.

ggplot(data = diamonds, mapping = aes(x = cut, fill = clarity))+
  geom_bar(position = "fill")

Position = “dodge”

Esta posición coloca las barra que tengan overlaping una al lado de otro para evitar esa oclusión que ocurría en la posición de “identity”

ggplot(data = diamonds, mapping = aes(x = cut, fill = clarity))+
  geom_bar(position = "dodge")

Position = “jitter”

Hay otra parametro estadístico que puede añadir valor en gráficos como el scatter plot. Para evitar el overploting, que quiere decir que hay muchos puntos que se redondean, haciendo que caigan en la misma posición. Para evitar que ocurra esto usaremos el parametro “jitter”. Este parametro añade ruido aleatorio a cada punto para dispersarlos y ver la densidad de puntos por zona.

ggplot(data = mpg, mapping = aes(x = displ, y = hwy))+
  geom_point(position = "jitter")

Cambiando el sistema de coordenadas con ggplot2

Cambiar del sistema clásico de coordenadas a otros sistemas. Sistemas que usaremos:

  • coord_flip() -> cambia los papeles de x e y
ggplot(data = mpg, mapping = aes(x = class, y = hwy))+
  geom_boxplot()+
  coord_flip()

  • coord_quickmap() -> configura el aspecto ratio para mapas, ideal para hacer una representación de datos geoespaciales.

P.D.: si os interesa sacar el mapa de un pais, se puede hacer con map_data, un acceso rapido a determinados mapas de determinados paises

library(maps)
## 
## Attaching package: 'maps'
## The following object is masked from 'package:purrr':
## 
##     map
italy <- map_data("italy") # a?ades el codigo ISO de un pais, en este caso USA, que lo sacara del paquete de "maps"

Ara dibujaremos encima del mapa con ggplot:

ggplot(italy,mapping = aes(x = long, y = lat, group = group))+
  geom_polygon(fill = "blue", color = "white")+
  coord_quickmap()

# con quick_map evita que haya una deformación del mapa
  • coord_poolar() –> uso de als coordenadas polares para generar una conexión entre varios charts
ggplot(data = diamonds)+
  geom_bar( mapping = aes(x = cut, fill = cut), show.legend = F, width = 1)+
  theme(aspect.ratio = 1)+
  labs(x= NULL, y = NULL)+
  coord_polar()

La gramatica final de ggplot2

Es importante tener claro la estructura de un ggplot, que es la siguiente:

# PLANTILLA PARA HACER UNA REPRESENTACI?N GR?FICA EN GGPLOT
# ggplot(data = <DATA_FRAME>)+
#   <GEOM_FUNCTION>(
#                   mapping = aes(<MAPPING>),
#                   stat = <STAT>,
#                   position = <POSITION>
#                   ) +
#   <COORDINATE_FUNCTION>() +
#   <FACET_FUNCTION>()

Recordar que se puede ver mas información en el cheat sheet propio de ggplot2 Un ejemplo para mejorar la personalización de los gráficos:

ggplot(data = diamonds) +
  geom_bar(mapping = aes(x=clarity,fill=clarity,y = ..count..))+
  coord_polar()+
  facet_wrap(~cut)+
  labs(x=NULL,y=NULL,title="Ejemplo",
       caption="Otro ejemplo abajo",
       subtitle="Subt?tulo")

Assignment ajustes avanzados de ggplot

  1. El siguiente gráfico que genera el código de R es correcto pero puede mejorarse. ¿Qué cosas añadirías para mejorarlo?
ggplot(data = mpg, mapping = aes(x = cty, y = hwy )) + 
  geom_point() + geom_jitter()

ggplot(data = mpg, mapping = aes(x = cty, y = hwy )) + 
  geom_point() + geom_count()

  1. Investiga la documentación de geom_jitter(). ¿Qué parámetros controlan la cantidad de ruído aleatorio (jitter)?

  2. Compara las funciones geom_jitter contra geom_count y busca semejanzas y diferencias entre ambas.

  3. ¿Cual es el valor por defecto del parámetro position de un geom_boxplot? Usa el dataset de diamonds o de mpg para hacer una visualización que lo demuestre.

  4. Convierte un diagrama de barras apilado en un diagrama de sectores o de tarta usando la función coord_polar()

ggplot(data = diamonds) + 
  geom_bar(mapping = aes(x = cut, fill = color))+ 
  theme(aspect.ratio = 1) + 
  labs(x = NULL, y = NULL) + 
  coord_polar()

  1. ¿Qué hace la función labs()? Lee la documentación y explícalo correctamente.

  2. ¿En qué se diferencian las funciones coord_quickmap() y coord_map()?

  3. Investiga las coordenadas coord_fixed() e indica su función.

  4. Investiga la geometría de la función geom_abline(), geom_vline() y geom_hline() e indica su función respectivamente.

  5. ¿Qué nos indica el gráfico siguiente acerca de la relación entre el consumo en ciudad y en autopista del dataset de mpg?

ggplot(data = mpg, mapping = aes(x = cty, y = hwy )) + 
  geom_point() + 
  geom_abline() + 
  coord_fixed()