Capítulo 21 Visualizando datos: incursión a ggplot2

Una de las principales fortalezas de R frente a Python es el manejo de datos con tidyverse, entorno en el que se incluye el paquete ggplot2.

La visualización de datos o dataviz debería ser una parte fundamental de todo análisis de datos. No es solo que nuestro trabajo sea más presentable y estético (algo fundamental). La visualización de datos es fundamental para convertir el dato en información, y usar dicha información para contar una historia con nuestros datos: no solo importa lo que cuentas sino cómo lo cuentas.

21.1 Grammar of graphics (gg): entendiendo la gramática ggplot2

La idea de la filosofía detrás del paquete ggplot2 (ya incluido en tidyverse) es entender los gráficos como parte integrada del flujo de procesamiento, depuración y modelado de los datos, dándoles una gramática, basándose en la idea de «The Grammar of Graphics» de Leland Wilkinson. Puedes profundizar en esa idea de Grammar of Graphics en las siguientes obras de referencia del dataviz

La documentación del paquete puedes consultarla en https://ggplot2-book.org/introduction.html y nos permitirá combinar diferentes elementos gráficos y ligarlos a los datos. El objetivo es empezar con un lienzo en blanco e ir añadiendo capas a tu gráfico, como harías por ejemplo en Photoshop, con la diferencia de que nuestras capas podemos ligarlas al conjunto de datos, tanto las capas estéticas como las estadísticas. Y dicho paquete nos permite hacerlo con la misma filosofía con la que hemos procesado los datos

Idea detrás de la «Grammar of graphics» de Wilkinson.

Imagen/gráfica 21.2: Idea detrás de la «Grammar of graphics» de Wilkinson.

La ventaja del sistema ggplot2 es poder mapear atributos estéticos (color, forma, tamaño) de objetos geométricos (puntos, barras, líneas) en función de los datos, añadiendo transformaciones de los datos, resúmenes estadísticos y transformaciones de las coordenadas.

Un gráfico se compondrá de las siguientes capas

  • Datos: nuestro gráfico estará vinculado a un conjunto de datos.
  • Mapeado de elementos (aesthetics): ejes, color, forma, tamaño, etc (en función de los datos)
  • Elementos geométricos (geom): puntos, líneas, barras, polígonos, etc.
  • Componer gráficas (facet): visualizar varias gráficas a la vez.
  • Transformaciones estadísticas (stat): ordenar, resumir, agrupar, etc.
  • Sistema de coordenadas (coord): coordenadas, grids, etc.
  • Temas (theme): fuente, tamaño de letra, subtítulos, captions, leyenda, ejes, etc.

21.2 Primer intento: scatter plot o diagrama de puntos

Veamos un primer intento para entender la filosofía. Imagina que queremos dibujar un scatter plot o diagrama de (dispersión) de puntos.

21.2.1 Datos: gapminder

Para ello vamos a usar el conjunto de datos gapminder, del paquete homónimo: un fichero con datos de esperanzas de vida, poblaciones y renta per cápita de distintos países en distintos momentos temporales.

library(gapminder)
gapminder
## # A tibble: 1,704 × 6
##    country     continent  year lifeExp      pop gdpPercap
##    <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
##  1 Afghanistan Asia       1952    28.8  8425333      779.
##  2 Afghanistan Asia       1957    30.3  9240934      821.
##  3 Afghanistan Asia       1962    32.0 10267083      853.
##  4 Afghanistan Asia       1967    34.0 11537966      836.
##  5 Afghanistan Asia       1972    36.1 13079460      740.
##  6 Afghanistan Asia       1977    38.4 14880372      786.
##  7 Afghanistan Asia       1982    39.9 12881816      978.
##  8 Afghanistan Asia       1987    40.8 13867957      852.
##  9 Afghanistan Asia       1992    41.7 16317921      649.
## 10 Afghanistan Asia       1997    41.8 22227415      635.
## # … with 1,694 more rows
glimpse(gapminder)
## Rows: 1,704
## Columns: 6
## $ country   <fct> "Afghanistan", "Afghanistan", "Afghanistan", "Afghanistan", …
## $ continent <fct> Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, …
## $ year      <int> 1952, 1957, 1962, 1967, 1972, 1977, 1982, 1987, 1992, 1997, …
## $ lifeExp   <dbl> 28.801, 30.332, 31.997, 34.020, 36.088, 38.438, 39.854, 40.8…
## $ pop       <int> 8425333, 9240934, 10267083, 11537966, 13079460, 14880372, 12…
## $ gdpPercap <dbl> 779.4453, 820.8530, 853.1007, 836.1971, 739.9811, 786.1134, …

Para empezar con algo sencillo filtraremos los datos de 1997 haciendo uso de filter().

gapminder_1997 <- gapminder %>% filter(year == 1997)
gapminder_1997
## # A tibble: 142 × 6
##    country     continent  year lifeExp       pop gdpPercap
##    <fct>       <fct>     <int>   <dbl>     <int>     <dbl>
##  1 Afghanistan Asia       1997    41.8  22227415      635.
##  2 Albania     Europe     1997    73.0   3428038     3193.
##  3 Algeria     Africa     1997    69.2  29072015     4797.
##  4 Angola      Africa     1997    41.0   9875024     2277.
##  5 Argentina   Americas   1997    73.3  36203463    10967.
##  6 Australia   Oceania    1997    78.8  18565243    26998.
##  7 Austria     Europe     1997    77.5   8069876    29096.
##  8 Bahrain     Asia       1997    73.9    598561    20292.
##  9 Bangladesh  Asia       1997    59.4 123315288      973.
## 10 Belgium     Europe     1997    77.5  10199787    27561.
## # … with 132 more rows

Vamos a realizar un diagrama de puntos enfrentando en el eje Y la población (variable pop) y en el eje X la renta per cápita (variable gdpPercap). ¿Qué necesitamos?

  • Datos: el conjunto filtrado gapminder_1997.
  • Mapeado: indicarle en aes() (aesthetics) las variables a pintar en cada coordenada. Todo lo que esté asignado dentro de aes() dependerá de una variable contenida en los datos. En este caso, el eje X dependerá de la variable gdpPercap, y el eje Y de la variable pop.
  • Elegir una geometría: optaremos en este primer caso por puntos.
ggplot(gapminder_1997, aes(x = gdpPercap, y = pop)) +
  geom_point() # Geometría

21.2.2 Mapeado de elementos (aesthetics)

21.2.2.1 Variables de los ejes

Para profundizar en el mapeado de aes() vamos a hacer lo mismo pero cambiando el rol de los ejes, intercambiando las variables, en este caso aes(y = gdpPercap, x = pop)

ggplot(gapminder_1997, aes(y = gdpPercap, x = pop)) +
  geom_point()

La idea podemos repetirla enfrentando ahora la esperanza de vida en el eje X (variable lifeExp) y la renta per cápita en el eje Y (variable gdpPercap).

ggplot(gapminder_1997, aes(y = gdpPercap, x = lifeExp)) +
  geom_point()

21.2.2.2 Colores, formas, tamaños

¿Cómo podemos dar color y tamaño a nuestro gráfico?

La opción más sencilla es indicándole, dentro de geom_point() el color de la geometría con color = ... (en este caso, el color del punto), mediante un color fijo, bien sea con alguno de los colores reservados que tiene R, bien sea con su código hexadecimal

# Color con palabra reservada
ggplot(gapminder_1997, aes(y = gdpPercap, x = lifeExp)) +
  geom_point(color = "red")
# Color en hexadecimal, de la página https://htmlcolorcodes.com/es/
ggplot(gapminder_1997, aes(y = gdpPercap, x = lifeExp)) +
  geom_point(color = "#2EA2D8")

De la misma manera podemos indicarle el tamaño de la geometría (en este caso del punto) con size = ..., incluso el porcentaje transparencia que queremos para un color dado con alpha = ... (entre 0 - transparente - y 1 - totalmente opaco).

# Color opaco
ggplot(gapminder_1997, aes(y = gdpPercap, x = lifeExp)) +
  geom_point(color = "#A02B85", size = 4)
# alpha = 50%
ggplot(gapminder_1997, aes(y = gdpPercap, x = lifeExp)) +
  geom_point(color = "#A02B85", size = 8, alpha = 0.4)

Si te fijas dichos parámetros se los hemos pasado fijos y constantes, pero podemos mapear en aes() para que dependan de los datos, por ejemplo, asignándole un color a cada dato en función de su continente.

ggplot(gapminder_1997, aes(y = gdpPercap, x = lifeExp, color = continent)) +
  geom_point(size = 4.5)

Podemos combinarlo con lo que hemos hecho anteriormente e indicarle además que queremos el tamaño en función de la población, con cierto grado de transparencia.

ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp, color = continent, size = pop)) +
  geom_point(alpha = 0.7)

En lugar de jugar con el color, también podríamos añadir las variables en función de la forma de la geometría (en este caso la forma de los «puntos») con shape = ..., haciéndola depender de continent (suficientes variables podríamos incluir, solo con ejes + colores + tamaños + formas + transparencia, hasta 6 variables distintas).

ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp, shape = continent, size = pop)) +
  geom_point(alpha = 0.7)

21.2.3 Scales y paletas de colores

Reflexionemos sobre el gráfico que acabamos de hacer

ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent, size = pop)) +
  geom_point(alpha = 0.7)

Usando los datos hemos conseguido dibujar en un gráfico bidimensional 4 variables (lifeExp y gdpPercap en los ejes \((X,Y)\), continent como color y pop como tamaño de la geometría) con muy pocas líneas de código. A veces nos puede ser más conveniente representar alguna de las variables en escala logarítmica (importante indicarlo en el gráfico), lo que podemos hacer facilmente con scale_x_log10() y scale_y_log10()

ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent, size = pop)) +
  geom_point(alpha = 0.7) +
  # Eje Y con escala logarítmica
  scale_y_log10()

Respecto a los colores, si te fijas R ha elegido automáticamente la paleta de colores pero podemos indicarle alguna paleta concreta de varias maneras.

La primera y más inmediata es indicarle los colores manualmente: con scale_color_manual le podemos indicar un vector de colores.

ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent, size = pop)) +
  geom_point(alpha = 0.7) +
  # Eje Y con escala logarítmica
  scale_y_log10() +
  # Escala manual de colores
  scale_color_manual(values = c("#A02B85", "#2DE86B", "#4FB2CA",
                                "#E8DA2D", "#E84C2D"))

Otra opción es elegir alguna de las paletas de colores disponibles en el paquete ggthemes, como scale_color_economist(), scale_color_excel() o scale_color_tableau().

library(ggthemes)

# scale_color_economist()
ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent, size = pop)) +
  geom_point(alpha = 0.8) +
  # Eje Y con escala logarítmica
  scale_y_log10() +
  scale_color_economist()
# scale_color_excel()
ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent, size = pop)) +
  geom_point(alpha = 0.8) +
  # Eje Y con escala logarítmica
  scale_y_log10() +
  scale_color_excel()
# scale_color_tableau()
ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent, size = pop)) +
  geom_point(alpha = 0.8) +
  # Eje Y con escala logarítmica
  scale_y_log10() +
  scale_color_tableau()

También existen múltiples paquetes que nos proporcionan paletas de colores basados en películas (paquete harrypotter descargado desde el repositorio de Github), pájaros (paquete Manu) o cuadros (paquete {MetBrewer}).

devtools::install_github(repo = "https://github.com/aljrico/harrypotter")
library(harrypotter)
ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent, size = pop)) +
  geom_point(alpha = 0.9) +
  scale_y_log10() +
  scale_color_hp_d(option = "gryffindor")
ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent, size = pop)) +
  geom_point(alpha = 0.9) +
  scale_y_log10() +
  scale_color_hp_d(option = "hufflepuff")
devtools::install_github("G-Thomson/Manu")
library(Manu)
ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent, size = pop)) +
  geom_point(alpha = 0.9) +
  scale_y_log10() +
  # paleta del pájaro Takahē - Porphyrio hochstetteri
  scale_colour_manual(values = get_pal("Takahe"))
devtools::install_github("BlakeRMills/MetBrewer") 
library(MetBrewer)
MetBrewer::met.brewer("Renoir")
MetBrewer::met.brewer("Monet")
MetBrewer::met.brewer("Hokusai")
ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent, size = pop)) +
  geom_point(alpha = 0.9) +
  scale_y_log10() +
  scale_colour_manual(values = met.brewer("Klimt"))

21.2.4 Geometrías (geom)

Hemos jugado un poco con las formas, tamaños y colores, pero siempre ha sido un diagrama de dispersión con puntos. Al igual que hemos usado geom_point(), podríamos usar otras geometrías como líneas con geom_line().

# Sin separar por continente
ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp)) +
  geom_line(alpha = 0.8) +
  scale_y_log10() +
  scale_color_tableau()
# Separando por continente
ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent)) +
  geom_line(alpha = 0.8) +
  scale_y_log10() +
  scale_color_tableau()

Fíjate que la filosofía es la misma: dado que cada elemento lo podemos tratar de forma individual, pasar de un gráfico a otro es relativamente sencillo, sin más que cambiar geom_point() por geom_line().

De la misma manera podemos dibujar un diagrama de dispersión con formas hexagonales con geom_hex(). Ahora el parámetro color corresponderá al cortono de la forma, y fill al relleno de la misma (fíjate que también cambiamos scale_color_tableau() por scale_fill_tableau())

ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           fill = continent, size = pop)) +
  geom_hex(alpha = 0.8) +
  scale_y_log10() + scale_fill_tableau()

Con geom_tile() también podemos dibujar en mosaico (como en baldosas).

ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent, size = pop)) +
  geom_tile(alpha = 0.8) +
  scale_y_log10() +
  scale_color_tableau()

Por último, con geom_text() podemos hacer que en lugar de una forma geométrica aparezcan textos que tengamos en alguna variable, que la pasaremos en aes() por el parámetro label (en este caso, la variable de la que tomará los nombres será country).

ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent, size = pop, label = country)) +
  geom_text(alpha = 0.8) +
  scale_y_log10() +
  scale_color_tableau()

21.2.5 Componer (facets)

Hasta ahora hemos pintado una sola gráfica, codificando en colores y formas. Pero también podemos dividir/desagregar los gráficos (facetar) por variables, pintando por ejemplo un gráfico por continente, mostrando todos los gráficos a la vez pero por separado, con facet_wrap().

ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp)) +
  geom_point(alpha = 0.9) +
  scale_y_log10() +
  facet_wrap(~ continent)

Le podemos pasar argumentos opcionales para indicarle el número de columnas o de filas que queremos.

ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp)) +
  geom_point(alpha = 0.9) +
  scale_y_log10() +
  facet_wrap(~ continent, nrow = 3)
ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp)) +
  geom_point(alpha = 0.9) +
  scale_y_log10() +
  facet_wrap(~ continent, ncol = 4)

De esta manera podríamos incluso visualizar el fichero de datos originales incluye hasta 5 variables: las variables pop y lifeExp en los ejes, la variable gdpPercap en el tamaño, la variable continent en el color y la variable year en la composición de facet_wrap().

library(MetBrewer)
ggplot(gapminder,
       aes(y = lifeExp, x = pop, size = gdpPercap, color = continent)) +
  geom_point(alpha = 0.6) +
  scale_x_log10() +
  scale_colour_manual(values = met.brewer("Klimt")) +
  facet_wrap(~ year)

Con facet_grid() podemos incluso organizar una cuadrícula en base a dos variables, por ejemplo que haya una fila por año (vamos a usar la tabla original en los años 1952, 1972, 1982 y 2002) y una columna por continente.

ggplot(gapminder %>% filter(year %in% c(1952,  1972, 1982,  2002)),
       aes(y = gdpPercap, x = lifeExp)) +
  geom_point(alpha = 0.9) +
  scale_y_log10() +
  facet_grid(year ~ continent)

21.2.6 Coordenadas y tema

Los gráficos pueden además personalizarse añadiendo, por ejemplo, títulos y subtítulos de la gráfica con labs(), asignando textos a title, subtitle y caption.

ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent, size = pop)) +
  geom_point(alpha = 0.8) +
  # Eje Y con escala logarítmica
  scale_y_log10() +
  scale_color_tableau() +
  labs(title = "EJEMPLO DE SCATTERPLOT CON GGPLOT2",
       subtitle =
         "Esperanza vida vs renta per cápita (año 1997)",
       caption = "Autor: Javier Álvarez Liébana | Datos: gapminder")

También podemos personalizar algunos aspectos extras, como el título que vamos a dar a los ejes o el título de las leyendas.

ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent, size = pop)) +
  geom_point(alpha = 0.8) +
  # Eje Y con escala logarítmica
  scale_y_log10() +
  scale_color_tableau() +
  labs(x = "Esperanza de vida", y = "Renta per cápita",
       color = "Continente", size = "Población",
       title = "EJEMPLO DE SCATTERPLOT CON GGPLOT2",
       subtitle =
         "Esperanza vida vs renta per cápita (año 1997)",
       caption = "Autor: Javier Álvarez Liébana | Datos: gapminder")

También podemos ocultar algún nombre de las leyendas (o ambos) si ya es explícito de lo que se está hablando. Por ejemplo, vamos a indicarle que no queremos el nombre de la leyenda en continentes, haciendo color = NULL (la variable que codifica los continentes a NULL).

ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent, size = pop)) +
  geom_point(alpha = 0.8) +
  # Eje Y con escala logarítmica
  scale_y_log10() +
  scale_color_tableau() +
  labs(x = "Esperanza de vida",
       y = "Renta per cápita",
       color = NULL, size = "Población",
       title = "EJEMPLO DE SCATTERPLOT CON GGPLOT2",
       subtitle =
         "Esperanza vida vs renta per cápita (año 1997)",
       caption = "Autor: Javier Álvarez Liébana | Datos: gapminder")

Incluso podemos ocultar la leyenda en sí de alguna de alguna de las variables con guides(size = "none") (en este caso, size = "none" nos elimina la leyenda que codifica el tamaño de los puntos).

ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent, size = pop)) +
  geom_point(alpha = 0.8) +
  # Eje Y con escala logarítmica
  scale_y_log10() +
  scale_color_tableau() +
  guides(size = "none") +
  labs(x = "Esperanza de vida",
       y = "Renta per cápita",
       color = NULL, size = "Población",
       title = "EJEMPLO DE SCATTERPLOT CON GGPLOT2",
       subtitle =
         "Esperanza vida vs renta per cápita (año 1997)",
       caption = "Autor: Javier Álvarez Liébana | Datos: gapminder")
ggplot(gapminder_1997,
       aes(y = gdpPercap, x = lifeExp,
           color = continent, size = pop)) +
  geom_point(alpha = 0.8) +
  # Eje Y con escala logarítmica
  scale_y_log10() +
  scale_color_tableau() +
  guides(size = "none", color = "none") +
  labs(x = "Esperanza de vida",
       y = "Renta per cápita",
       color = NULL, size = "Población",
       title = "EJEMPLO DE SCATTERPLOT CON GGPLOT2",
       subtitle =
         "Esperanza vida vs renta per cápita (año 1997)",
       caption = "Autor: Javier Álvarez Liébana | Datos: gapminder")

21.3 Segundo intento: diagrama de barras

Veamos un segundo intento dibujando un diagrama de barras.

La forma más inmediata de hacerlo es haciendo uso de geom_col() para un diagrama de barras vertical, al que le pasaremos la variable gdpPercap a representar en el eje Y (la altura de las barras) y yearen el eje X (tendremos una barra por año, con la altura del total mundial para ese año)

ggplot(gapminder,
     aes(y = gdpPercap, x = year)) +
  geom_col()

Lo que hemos hecho con geom_col() es sumar todos los valores de renta per cápita, de todos los países, para cada año.

¿Cómo podríamos dibujar, para cada año, una barra para cada continente (con su suma)?

Primero vamos a obtener los datos agrupados por continente y año.

gapminder_por_continente <-
  gapminder %>% group_by(year, continent) %>%
  summarise(sum_gdpPercap = sum(gdpPercap))
gapminder_por_continente
## # A tibble: 60 × 3
## # Groups:   year [12]
##     year continent sum_gdpPercap
##    <int> <fct>             <dbl>
##  1  1952 Africa           65134.
##  2  1952 Americas        101977.
##  3  1952 Asia            171451.
##  4  1952 Europe          169832.
##  5  1952 Oceania          20596.
##  6  1957 Africa           72032.
##  7  1957 Americas        115401.
##  8  1957 Asia            190995.
##  9  1957 Europe          208890.
## 10  1957 Oceania          23197.
## # … with 50 more rows

Será ese conjunto gapminder_por_continente el que usaremos para dibujar nuestro diagrama de barras.

ggplot(gapminder_por_continente,
     aes(y = sum_gdpPercap, x = year,
         fill = continent)) +
  geom_col() +
  scale_fill_tableau()

Esta forma de dibujar las barras es lo que se conoce como formato stack o apilado: las barras de cada año las ha apilado unas encima de otras. Si queremos que las barras desapiladas (por separado) indicándole position = "dodge2" en la función geom_col()

ggplot(gapminder_por_continente,
     aes(y = sum_gdpPercap, x = year,
         fill = continent)) +
  geom_col(position = "dodge2") +
  scale_fill_tableau()

El formato de barras apiladas nos da una información más limpia en este caso pero no permite una buena comparación entre contienentes con valores similares, dependiendo además de la renta per cápita global (la altura de la barra total). Para facilitar esa comparación podemos indicarle position = "fill", que hará cada barra de igual longitud, permitiéndonos visualizar los datos en relativo.

ggplot(gapminder_por_continente,
     aes(y = sum_gdpPercap, x = year,
         fill = continent)) +
  geom_col(position = "fill") +
  scale_fill_tableau()

Las barras además pueden ser horizontales, añadiendo coord_flip(). Además vamos a darle un título y otros elementos que hemos visto anteriormente

ggplot(gapminder_por_continente,
     aes(y = sum_gdpPercap, x = year,
         fill = continent)) +
  geom_col() + coord_flip() +
  scale_fill_tableau() +
  labs(x = "Renta per cápita",
       y = "Año", color = "Continente",
       title = "EJEMPLO DE DIAGRAMA DE BARRAS CON GGPLOT2",
       subtitle =
         "Barras horizontales apiladas (agrupadas por continente y año)",
       caption = "Autor: Javier Álvarez Liébana | Datos: gapminder")

21.4 📝 Ejercicios

(haz click en las flechas para ver soluciones)

📝Ejercicio 1: del conjunto starwars (del entorno de paquetes tidyverse), filtra solo los registros que no tenga ausente NA en las columnas mass, height, eye_color

  • Solución:
# Eliminamos NA
starwars_filtro <- starwars %>% drop_na(c(mass, height, eye_color))

 

📝Ejercicio 2: con ese conjunto filtrado dibuja un diagrama de puntos enfrentando x = height en el eje X e y = mass en el eje Y.

  • Solución:
ggplot(starwars_filtro, aes(x = height, y = mass)) +
  geom_point()

 

📝Ejercicio 3: modifica el código del gráfico anterior para asignar el tamaño de los puntos en función de la variable mass.

  • Solución:
ggplot(starwars_filtro,
       aes(x = height, y = mass, size = mass)) +
  geom_point()

 

📝Ejercicio 4: modifica el código del gráfico anterior para asignar el color en función de su color de ojos guardado en eye_color. Antes procesa la variable para quedarte con colores reales: si hay dos colores, quédate con el primero; el color "hazel" pásalo a "brown"; los colores "unknown" pásalo a gris.

  • Solución:
# Transformar colores
starwars_filtro <-
   starwars_filtro %>%
    mutate(eye_color =
             case_when(eye_color == "blue-gray" ~ "blue",
                       eye_color == "hazel" ~ "brown",
                       eye_color == "unknown" ~ "gray",
                       eye_color == "green, yellow" ~ "green",
                       TRUE ~ eye_color))

# Visualizamos
ggplot(starwars_filtro,
       aes(x = height, y = mass, size = mass, color = eye_color)) +
  geom_point() +
  scale_color_manual(values =
                       c("black", "blue", "brown", "gray", "green",
                         "orange", "red", "white", "yellow"))

 

📝Ejercicio 5: repite el gráfico anterior localizando ese dato con un peso extremadamente elevado (outlier), elimínalo y vuelve a repetir la visualización.

  • Solución:
# Localizamos el valor
starwars_filtro %>% slice_max(mass, n = 5)
## # A tibble: 5 × 14
##   name    height  mass hair_color skin_color  eye_color birth_year sex    gender
##   <chr>    <int> <dbl> <chr>      <chr>       <chr>          <dbl> <chr>  <chr> 
## 1 Jabba …    175  1358 <NA>       green-tan,… orange         600   herma… mascu…
## 2 Grievo…    216   159 none       brown, whi… green           NA   male   mascu…
## 3 IG-88      200   140 none       metal       red             15   none   mascu…
## 4 Darth …    202   136 none       white       yellow          41.9 male   mascu…
## 5 Tarfful    234   136 brown      brown       blue            NA   male   mascu…
## # … with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## #   vehicles <list>, starships <list>
starwars_filtro %>% slice_max(mass, n = 5) %>% pull(name)
## [1] "Jabba Desilijic Tiure" "Grievous"              "IG-88"                
## [4] "Darth Vader"           "Tarfful"
starwars_filtro <- starwars_filtro %>%
  filter(name != "Jabba Desilijic Tiure")

# Visualizamos
ggplot(starwars_filtro,
       aes(x = height, y = mass,
           size = mass, color = eye_color)) +
  geom_point() +
  scale_color_manual(values =
                       c("black", "blue", "brown", "gray", "green",
                         "orange", "red", "white", "yellow"))

 

📝Ejercicio 6: repite el gráfico anterior eliminando la leyenda del tamaño del punto y cambia el título de la leyenda del color de ojos a castellano. Añade además transparencia alpha = 0.6 a los puntos.

  • Solución:
ggplot(starwars_filtro,
       aes(x = height, y = mass,
           size = mass, color = eye_color)) +
  geom_point(alpha = 0.6) +
  guides(size = "none") +
  scale_color_manual(values =
                       c("black", "blue", "brown", "gray", "green",
                         "orange", "red", "white", "yellow")) +
  labs(color = "color de ojos")

 

📝Ejercicio 7: repite el gráfico modificando los títulos de los ejes (a castellano) y escribiendo título, subtítulo y caption.

  • Solución:
ggplot(starwars_filtro,
       aes(x = height, y = mass,
           size = mass, color = eye_color)) +
  geom_point(alpha = 0.6) +
  guides(size = "none") +
  scale_color_manual(values =
                       c("black", "blue", "brown", "gray", "green",
                         "orange", "red", "white", "yellow")) +
  labs(color = "color de ojos",
       x = "altura (cm)", y = "peso (kg)",
       title = "STARWARS",
       subtitle = "Diagrama de puntos altura vs peso",
       caption = "Autor: Javier Álvarez Liébana | Datos: starwars")

 

📝Ejercicio 8: repite el gráfico anterior explicitando los cortes en los ejes con scale_x_continuous() y scale_y_continuous(): el eje X de 60 a 240 (de 30 en 30 cada marca), el eje Y de 20 a 160 (de 20 en 20 cada marca).

  • Solución:
ggplot(starwars_filtro,
       aes(x = height, y = mass,
           size = mass, color = eye_color)) +
    geom_point(alpha = 0.6) +
    guides(size = "none") +
    scale_color_manual(values =
                           c("black", "blue", "brown", "gray", "green",
                             "orange", "red", "white", "yellow")) +
  scale_y_continuous(breaks = seq(20, 160, by = 20)) +
  scale_x_continuous(breaks = seq(60, 240, by = 30)) +
  labs(color = "color de ojos",
       x = "altura (cm)", y = "peso (kg)",
       title = "STARWARS",
       subtitle = "Diagrama de puntos altura vs peso",
       caption = "Autor: Javier Álvarez Liébana | Datos: starwars")

 

📝Ejercicio 9: del conjunto de datos original, elimina los registros que tengan ausente la variable sex. Agrupa por dicha variable y contabiliza los personajes de cada sexo. Visualízalo en un diagrama de barras vertical, con la escala de colores de scale_fill_tableau(), cambiando el nombre de leyenda y de ejes, y poniéndo títulos y subtítulos.

  • Solución:
library(ggthemes)
starwars_filtro <- starwars %>% drop_na(sex)

# Vertical
ggplot(starwars_filtro %>% group_by(sex) %>% count(),
       aes(x = sex, y = n, fill = sex)) +
  geom_col() +
  scale_fill_tableau() +
  labs(fill = "Sexo",
       x = "Sexo", y = "Número de personajes",
       title = "STARWARS",
       subtitle = "Diagrama de barras verticales",
       caption = "Autor: Javier Álvarez Liébana | Datos: starwars")
# Horizontal
ggplot(starwars_filtro %>% group_by(sex) %>% count(),
       aes(x = sex, y = n, fill = sex)) +
  geom_col() +
  coord_flip() +
  scale_fill_tableau() +
  labs(fill = "Sexo",
       x = "Sexo", y = "Número de personajes",
       title = "STARWARS",
       subtitle = "Diagrama de barras vertical",
       caption = "Autor: Javier Álvarez Liébana | Datos: starwars")