R-Conomics

Introducción

En la última entrada analizamos los gráficos de correlación, en los que básicamente relacionabamos dos variables que, teóricamente, se encuentran correlacionadas-valga la redundancia-o bien, donde una depende de la otra. En este caso vamos a hacer algo parecido, ya que de igual manera vamos a relacionar algunas variables pero con la diferencia de que ahora las vamos a ordenar para hacer un ranking, ya que de ésto se tratarán los gráficos de ésta entrada.

Gráfico de barras ordenadas

Cuando queremos hacer un gráfico que nos muestre a aquellas variables (países, personas, riquezas, etc) que han tenido más relevancia en, por ejemplo, un cierto periodo de tiempo, la mejor opción que tenemos para graficar eso son éste tipo de barplots. La lógica es la misma que con un gráfico de divergencia, pero con la diferencia de que en éste tipo de gráficos no solemos tener valores negativos, por lo que suelen estar pegados a la izquierda del eje.

Veamos un ejemplo de ello en R. Vamos a usar la base de datos gapminder_unfiltered del paquete gapminder, ya que cuenta con variables de tipo caracter que nos serán útiles para éste ejercicio. Primero que nada cargamos las librerias:

# Cargamos las librerías

library(echarts4r)
library(scales)
library(ggbump)
library(ggplot2)
library(dplyr) 
library(gapminder)
library(CGPfunctions)

Antes de continuar, quiero mencionar que existen varias formas de reordenar la base de datos como la necesitamos, pero la que a mi parecer es la más práctica es concatenando las funciones usadas a continuación con el operador %>%. Te recomiendo usarlo cuando trabajes con tidyverse, ya que te ahorrará algo de tiempo de escritura.

# Filtramos y reordenamos la base de datos

base_1 <- filter(gapminder_unfiltered, year == 1957) %>% # Para filtrar a un año
  arrange(pop) %>% # Para reordenar los valores de mayor a menor
  top_n(10, pop) # Para seleccionar los primeros 10 valores

base_1 %>% 
  e_charts(x = country) %>%
  e_bar(pop, legend = FALSE, name = "Población") %>% 
  e_labels(position = "right") %>% 
  e_tooltip() %>% 
  e_title("Población por país", "10 países con mayor población") %>% 
  e_flip_coords() %>% 
  e_y_axis(splitLine = list(show = FALSE)) %>% 
  e_color(color = "#5dabc9", background = NULL) %>% 
  e_theme("london") %>% 
  e_x_axis(show = FALSE) 

Hagamos un paréntesis para analizar un poco el código anterior, ya que no me gusta escribir cosas sin que entiendas por qué están ahí. Si leíste la entrada sobre bases de datos disponible aquí entonces se harán familiares las primeras dos funciones usadas. Primero, utilizamos filter() para poder filtrar la base únicamente a un año, en este caso a 1957, después utilizamos arrange() para reordenar los valores de mayor a menor y, finalmente, usamos top_n() para obtener los primeros 10 valores de la base de datos que previamente filtramos, todo esto concatenado en la misma función con el operador %>%. Pasando al código de la gráfica, primero que nada definimos la base de datos con la que vamos a trabajar (en este caso a la que filtramos previamente), con la función e_charts() definimos al eje de las \(X\). Con la función e_bar() definimos los datos que se usarán para un gráfico de barras, además de agregarles una etiqueta. El comando e_flip_coords() nos invertirá los ejes para tener barras a la izquierda. De hecho el gráfico ya funciona hasta este punto, el resto de comandos son solamente extras, como un cierto color con e_color(), un tema de fondo con e_theme() (puedes ver el resto de los temas disponibles escribiendo en la consola ?e_theme()) y opciones de visualización de datos con e_tooltip().

En los siguientes gráficos no voy a detenerme demasiado con el código, me limitaré a poner breves explicaciones ya que la mayoría seguirán una lógica parecida, pero en tanto entiendas como funciona el primer gráfico es más que suficiente para comprender el resto.

Por cierto, seguramente te estarás preguntando por qué la etiqueta del color en e_color() es un nombre tan raro. Ciertamente no me se de memoria el código de los colores, pero eso no importa, ya que basta con que escribas hex color en el buscador de Google para que nos arroje una pequeña app que nos muestra toda la gama de colores que existe. Debajo de la app nos dirá también el código del color, basta con que escojamos alguno que sea de nuestro agrado y copiemos el código para pegarlo aquí en el gráfico.

Gráfico de columnas ordenadas

Éste gráfico es muy parecido al anterior, ya que se basa igualmente en barras ordenadas, siendo la única diferencia que ahora están ordenadas en el eje de las \(X\) (en éste caso por población). Básicamente, lo único que tenemos que hacer es reordenar los ejes para éste caso. Vamos a ver un ejemplo en R utilizando la misma base filtrada del caso anterior:

# Gráfico de columnas

base_1 %>% 
  e_charts(x = country) %>%
  e_bar(pop, legend = FALSE, name = "Población") %>% 
  e_labels(position = "top") %>% 
  e_tooltip() %>% 
  e_title("Población por país", "10 países con mayor población") %>% 
  e_y_axis(splitLine = list(show = FALSE)) %>% 
  e_color(color = "#3269a8", background = NULL) %>% 
  e_theme("london") %>% 
  e_x_axis(show = TRUE) 

Notese que omití el comando e_flip_coords() para evitar que el gráfico invierta los ejes. En este caso solo hice pequeñas modificaciones, como escribir TRUE en la función e_x_axis(), para que nos muestre los países por con nombre y cambié la paleta de colores para diferenciarlo del otro gráfico.

En este punto te deberías estar preguntando: ¿cuando utilizo la primera y cuando la segunda? Realmente puedes usar cualquiera de las dos para los mismos casos, aunque te recomendaría utilizar la segunda gráfica cuando tengas una mayor cantidad de datos. Procura utilzar la primera cuando tengas no más de 15 barras.

Gráfico de burbujas ordenadas

Imaginemos que queremos mostrar una representación más exacta de la magnitud que tenemos en los datos, para ello podemos hacer un gráfico de burbujas ordenadas por tamaño, ya que nos mostrará una mejor proporción de la diferencia existente entre los datos. Vamos a ver un ejemplo en R con un gráfico de puntos ordenados por tamaño que además está animado. Existe la opción de hacer esto con ggplot() pero me voy a limitar a la forma más sencilla de hacerlo, para evitar complicarte demasido.

# Agregamos una variable z al data frame
base_2 <- mutate(base_1, pop2 = pop)


# Graficamos
base_2 %>% 
  head(10) %>% 
  e_charts(country) %>% 
  e_y_axis(splitLine = list(show = FALSE)) %>% 
  e_tooltip() %>% 
  e_title("Población por país", "10 países con mayor población") %>% 
  e_y_axis(splitLine = list(show = FALSE)) %>% 
  e_effect_scatter(pop, pop2, symbol_size = 5, name = "Población") %>% # Para darle una  animación a las burbujas
  e_visual_map(pop2) %>% 
  e_theme("london") %>% 
  e_legend(FALSE) 

En este caso las burbujas ya están ordenadas por altura (entre más alta se encuentre el valor es mayor), pero además de eso también le añadimos un tamaño a las burbujas para denotar la diferencia existente entre los valores de una manera más clara. Ahora, para poder añadir tamaño a las burbujas este gráfico no puede hacerlo si consideramos a la misma variable \(Y\) como una variable \(Z\) de tamaño, por lo que previamente hicimos uso de la función mutate() para añadir otra columna que es, simplemente, la misma variable \(Y\) pero considerada como \(Z\), para evitar que el gráfico se genere con errores.

Gráficos de pendiente

Éstos gráficos suelen ser útiles cuando queremos ver el cambio en las magnitudes de varias variables a lo largo del tiempo, es decir, cómo ha cambiado una variable de un periodo a otro. Aunque no siempre sean gráficos de ranking ordenados si son sumamemnte útiles para ver la progresión de diversas series durante, por ejemplo, 3 periodos de tiempo diferentes. Es recomendable usarlos cuando queremos comparar valores en no más de 5 periodos, pero que éstos periodos tengan una amplitud de tiempo considerable, por ejemplo: 5 años, 10 años, 15 años, etc.

Para este tipo de gráficos vamos a utilizar un paquete llamado CGPfunctions que nos ahorrará mucho trabajo, ya que facilita mucho la creación de éste tipo de gráficos. Para fines prácticos utilizaremos el ejemplo que viene por default en el paquete. Veamos un gráfico de éste estilo sobre sobrevivientes de cancer durante un periodo de 20 años. Primero que nada veamos los datos, para saber qué estamos graficando:

head(newcancer)
##      Year     Type Survival
## 1  5 Year Prostate       99
## 2 10 Year Prostate       95
## 3 15 Year Prostate       87
## 4 20 Year Prostate       81
## 5  5 Year  Thyroid       96
## 6 10 Year  Thyroid       96

Podemos observar que tenemos 3 columnas: Una con el periodo en años, otra con el tipo de cancer y otra con el porcentaje de superviviencia. Notese que cada 4 valores se habla de un mismo tipo de cancer, ya que la base nos estaría indicando que porcentaje de personas sobreviven después de tantos años a cada tipo de cancer. Ahora, vamos a graficar la serie de la siguiente manera, con la función newggslopegraph:

newggslopegraph(dataframe = newcancer,
                Times = Year,
                Measurement = Survival,
                Grouping = Type, 
                Title = "Porcentaje de sobrevientes de cancer",
                SubTitle = "Datos a 20 años",
                Caption = "Espero que te sirva este ejemplo"
                )

Lo que podemos notar es que ésta función nos pide por default los siguientes datos: dataframe para saber qué datos va a utilizar, Times para saber los periodos temporales a utilizar, Measurement para saber el valor que va a graficar a lo largo de los periodos temporales y, finalmente, Grouping para saber como va a agrupar los datos. Vamos a hacer una pequeña base de datos por si no has entendido del todo como funciona la función anterior. Supongamos por ejemplo que queremos saber la aprobación que tiene una ideología política en dos periodos de tiempo para 3 estados diferentes: EDOMEX, Nuevo Leon y Chihuahua, por lo que para ello vamos a proponer 2 fechas diferentes, asignarlas por estado y dar una aprobación fictiia. Vamos a crear el data frame de la siguiente manera:

# Creamos las variables
periodo <-c("01-01-2000","01-01-2010", "01-01-2020", "01-01-2000","01-01-2010", "01-01-2020", "01-01-2000","01-01-2010", "01-01-2020")
estados <- c("EDOMEX", "EDOMEX", "EDOMEX", "Nuevo Leon", "Nuevo Leon", "Nuevo Leon", "Chihuahua", "Chihuahua", "Chihuahua")
aceptacion <- c(50,70,40,30,60,80,40,30,70)

# Creamos el data frame
aprobacion <- data.frame(periodo, estados, aceptacion)

# Visualizamos los datos que hemos creado
head(aprobacion)
##      periodo    estados aceptacion
## 1 01-01-2000     EDOMEX         50
## 2 01-01-2010     EDOMEX         70
## 3 01-01-2020     EDOMEX         40
## 4 01-01-2000 Nuevo Leon         30
## 5 01-01-2010 Nuevo Leon         60
## 6 01-01-2020 Nuevo Leon         80

Ahora que ya tenemos nuestros datos ficticios podemos pasar a graficar de la misma manera que con los datos de cancer, por lo que tendremos lo siguiente:

# Creamos el gráfico con datos ficticios

newggslopegraph(dataframe = aprobacion,
                Times = periodo,
                Measurement = aceptacion,
                Grouping = estados, 
                Title = "Porcentaje de aceptación por estados",
                SubTitle = "Datos a 10 años",
                Caption = "Espero que te sirva este ejemplo"
                )

Como vemos, este gráfico nos da una buena visualización de variaciones al estilo ranking, pero es importante que no usemos demasiados periodos de tiempo, ya que tendríamos un grñafico demasiado complicado de interpretar.

Gráficos de paleta (lollipop)

Un gráfico de paleta es básicamente lo mismo que un gráfico de barras como el que hicimos al principio, solo que en este caso éstos gráficos suelen darle una mayor atención a lo que es el valor final, más que los gráficos de barras. Suelen ser útiles cuando queremos dejar en claro el valor que estamos graficando al final, además de que éstos gráficos tienen margen para agregar una mayor cantidad de valores.

Veamos un ejemplo en R utilizando los datos que ya teníamos previamente de población. Para éste tipo de gráficos usaremos la función geom_center() para crear las lineas y la función geom_point() para crear el punto final en cada linea, tal que:

# Quitamos la notación científica 
options(scipen = 999)

# Creamos el gráfico

ggplot(base_1, aes(x=country, y=pop)) +
  geom_segment( aes(x=country, xend=country, y=0, yend=pop), color="skyblue") +
  geom_point( color="blue", size=4, alpha=0.6) +
  theme_bw() +
  coord_flip() +
  theme(
    panel.grid.major.y = element_blank(),
    panel.border = element_blank(),
    axis.ticks.y = element_blank()
  )

Ahora, como podemos observar no tenemos un gráfico ordenado al estilo ranking, por lo que utilizando la función reorder() e incluyendo dentro a la variable \(X\), la cual estará ordenada en función de la variable \(Y\) ahora si podemos hacer un gráfico de ranking ordenado de mayor a menor, tal que:

# Reordenamos los datos

ggplot(base_1, aes(x=reorder(country, pop), y=pop)) +
  geom_segment( aes(x=reorder(country, pop), xend=reorder(country, pop), y=0, yend=pop), color="skyblue") +
  geom_point( color="blue", size=4, alpha=0.6) +
  theme_bw() +
  coord_flip() +
  theme(
    panel.grid.major.y = element_blank(),
    panel.border = element_blank(),
    axis.ticks.y = element_blank()
  )

Y ahora, para hacerlo más atractivo visualmente, agreguemos títulos, ejes, notas y ajustes de tamaño:

# Dandole formato al gráfico

ggplot(base_1, aes(x=reorder(country, pop), y=pop)) +
  geom_segment( aes(x=reorder(country, pop), xend=reorder(country, pop), y=0, yend=pop), color="skyblue") +
  geom_point( color="blue", size=4, alpha=0.6) +
  theme_bw() +
  coord_flip() +
  theme(
    panel.grid.major.y = element_blank(),
    panel.border = element_blank(),
    axis.ticks.y = element_blank()
  ) + 
  theme(legend.position = "bottom") +
  theme(legend.title = element_blank()) +
  guides(col = guide_legend(nrow = 1, byrow = TRUE)) + 
  xlab("País") + 
  ylab("Población")+ 
  theme(plot.title = element_text(size = 11, face = "bold", hjust = 0)) + 
  theme(plot.subtitle = element_text(size = 10, hjust = 0)) + 
  theme(plot.caption = element_text(size = 10, hjust = 0)) +
  theme(plot.margin = unit(c(1,1,1,1), "cm")) +
  labs(
    title = "Ejemplo de un gráfico de paleta de ranking.",
    subtitle = "Aquí va un subtítulo",
    caption = "Fuente: Elaboración propia. \nNotas: Espero que te sirva este ejemplo."
  )

Finalmente, vemos que los números de la parte de abajo son algo difíciles de leer, por lo que usando el paquete scales vamos agregarle algunas comas a los números con la función scale_y_continuous() de la siguiente manera:

# Cambiando el formato de los números

ggplot(base_1, aes(x=reorder(country, pop), y=pop)) +
  geom_segment( aes(x=reorder(country, pop), xend=reorder(country, pop), y=0, yend=pop), color="skyblue") +
  geom_point( color="blue", size=4, alpha=0.6) +
  theme_bw() +
  coord_flip() +
  theme(
    panel.grid.major.y = element_blank(),
    panel.border = element_blank(),
    axis.ticks.y = element_blank()
  ) + 
  theme(legend.position = "bottom") +
  theme(legend.title = element_blank()) +
  guides(col = guide_legend(nrow = 1, byrow = TRUE)) + 
  xlab("País") + 
  ylab("Población")+ 
  theme(plot.title = element_text(size = 11, face = "bold", hjust = 0)) + 
  theme(plot.subtitle = element_text(size = 10, hjust = 0)) + 
  theme(plot.caption = element_text(size = 10, hjust = 0)) +
  theme(plot.margin = unit(c(1,1,1,1), "cm")) +
  labs(
    title = "Ejemplo de un gráfico de paleta de ranking.",
    subtitle = "Aquí va un subtítulo",
    caption = "Fuente: Elaboración propia. \nNotas: Espero que te sirva este ejemplo."
  )+ 
  scale_y_continuous(labels = comma)

Ahora si, el gráfico ya es mucho más dijerible y presentable. En este caso preferí no convertir el gráfico a objeto y ahorrar lineas de código, ya que me interesa que veas el código final completo para que entiendas perfectamente como funciona el gráfico.

Gráficos de protuberancia (bump)

Estos son bastante parecidos a los gráficos de pendiente que vimos hace un par de puntos, pero considerablemente mejores para graficar datos con más periodos de tiempo. Estuve investigando por un rato y encontré un paquete sumamente interesante para crear este tipo de gráficos, llamado ggbump, el cual es una extensión de Ggplot2. En este caso usaré la documentación que hay al respecto como guía para crear el gráfico, ya que no tengo demasiada experiencia trabajando con éste tipo de gráficos.

¿Recuerdas el gráfico que hice hace un rato sobre aceptación política? Bueno, al ser un gráfico que tiene casi la misma lógica en este caso vamos a utilizar los mismos datos, tal que:

head(aprobacion)
##      periodo    estados aceptacion
## 1 01-01-2000     EDOMEX         50
## 2 01-01-2010     EDOMEX         70
## 3 01-01-2020     EDOMEX         40
## 4 01-01-2000 Nuevo Leon         30
## 5 01-01-2010 Nuevo Leon         60
## 6 01-01-2020 Nuevo Leon         80

Ahora, la documentación del gráfico nos dice que debemos incluir una variable ranking para enumerar de mayor a menor los datos, por lo que se hará con la ya conocida función mutate(), sin embargo, en este caso éste tipo de gráficos no aceptan variables de tipo fecha, por lo que vamos a crear una variable nueva que solo incluya el año y hacer otro data frame para este caso, tal que:

# Creamos los periodos considerando solo un año y un data frame nuevo con la función tibble
periodo_año <- c(2000, 2010, 2020, 2000, 2010, 2020, 2000, 2010, 2020)
aprobacion_1 <- tibble(periodo_año, estados, aceptacion)

# Creando una variable extra de ranking
aprobacion_1 <- mutate(aprobacion_1, rank = rank(aceptacion, ties.method = "random")) %>% 
  group_by(periodo_año) %>% 
  ungroup()

# Visualizamos los datos
head(aprobacion_1)
## # A tibble: 6 x 4
##   periodo_año estados    aceptacion  rank
##         <dbl> <chr>           <dbl> <int>
## 1        2000 EDOMEX             50     5
## 2        2010 EDOMEX             70     7
## 3        2020 EDOMEX             40     3
## 4        2000 Nuevo Leon         30     2
## 5        2010 Nuevo Leon         60     6
## 6        2020 Nuevo Leon         80     9

Bien, ahora que ya tenemos la base entonces podemos comenzar a trabajar en el gráfico, tal que:

# Gráfico en su forma más simple

ggplot(aprobacion_1, aes(periodo_año, aceptacion, color = estados)) +
    geom_bump()

Bien, ya tenemos un gráfico muy sencillo, pero ahora vamos a darle algo de color, cambiar fondos, paletas de colores, agregar algunos puntos, etc, tal que:

# Cargamos algunos paquetes extra que nos servirán para darle formato al gráfico
pacman::p_load(tidyverse, cowplot, wesanderson)
# Dándole formato al gráfico

ggplot(aprobacion_1, aes(x = periodo_año, y = aceptacion, color = estados)) +
  geom_point(size = 4) +
  # La función geom_text nos da el nombre de los estados dentro de la gráfica
  geom_text(data = aprobacion_1 %>% filter(periodo_año == min(periodo_año)),
            aes(x = periodo_año - .1, label = estados), size = 2, hjust = 1) + 
  geom_text(data = aprobacion_1 %>% filter(periodo_año == max(periodo_año)),
            aes(x = periodo_año + .1, label = estados), size = 2, hjust = 0) +
  geom_bump(size = 2, smooth = 8) +
  # Fondo utilizado con theme_minimal
  theme_minimal_grid(font_size = 10, line_size = 0) +
  theme(legend.position = "none",
        panel.grid.major = element_blank()) +
  scale_y_reverse() +
  # Escala de colores usada en el manual
  scale_color_manual(values = wes_palette(n = 3, name = "GrandBudapest1"))+
  guides(col = guide_legend(nrow = 1, byrow = TRUE)) + 
  ### a partir de aquí son los mismos comandos que siempre uso para márgenes y títulos
  xlab("Periodo") + 
    ylab("Ranking")+ 
  theme(plot.title = element_text(size = 11, face = "bold", hjust = 0)) + 
  theme(plot.subtitle = element_text(size = 10, hjust = 0)) + 
  theme(plot.caption = element_text(size = 10, hjust = 0)) +
  theme(plot.margin = unit(c(1,1,1,1), "cm")) +
  labs(
    title = "Gráfico de ranking con especializado",
    subtitle = "Ejemplo",
    caption = "Fuente: Elaboración propia. \nNotas: Espero que te sirva este ejercicio."
  )

Ahora ya tenemos un gráfico más bonito y mucho más digerible, con una paleta de colores que, a mi parecer, es bastante más atractiva que la que suele usar ggplot2 po default.

Algo interesante de éste tipo de gráficos es que puedes combinarlos con mapas, pero eso lo veremos en una futura entrada dedicada exclusivamente a la creación de mapas para análsis gráfico.

¡Muchas gracias por leerme! Sería de gran ayuda que compartieras ésta entrada con quien creas que pueda serle útil. Me ayudaría mucho que ésto llegue a más gente.

Esta entrada está dedicada a Alessandra Gutierrez Sosa, quien me apoyó y me inspiró para varios tópicos que vienen aquí

Referencias

[1] Urias, H. Q., & Salvador, B. R. P. (2014). Estadística para ingeniería y ciencias. Grupo Editorial Patria.

[2] Wickham, H., Chang, W., & Wickham, M. H. (2016). Package ‘ggplot2’. Create Elegant Data Visualisations Using the Grammar of Graphics. Version, 2(1), 1-189.

[3] Kuan, J. (2015). Learning Highcharts 4. Packt Publishing Ltd.

[4] Bivand, R. S., Pebesma, E. J., Gomez-Rubio, V., & Pebesma, E. J. (2013). Applied spatial data analysis with R (Vol. 2). New York: Springer.

[5] Smith, A. (2018). Visual Vocabulary. 4 de marzo de 2020, de Financial Times. Sitio web: https://github.com/ft-interactive/chart-doctor/tree/master/visual-vocabulary

[6] Coene, J. (2017). Maps. 26 de febrero de 2021, de echarts4r Sitio web: https://echarts4r.john-coene.com/articles/map.html

[7] Joberg, D. (2020). ggbump, documentation. 27 de marzo de 2021, de Github Sitio web: https://github.com/davidsjoberg/ggbump

R-Conomics
Todos los derechos reservados