Esta publicación tiene dos objetivos, uno personal y otro general. El objetivo personal es recolectar en un solo archivo todo lo que he aprendido sobre gráficos utilizando el paquete ggplot2; por lo que este script es la recopilación de ciertos códigos y comandos que he aprendido hasta ahora. El segundo objetivo, el general, es simplemente compartirlo a todo aquel que guste.
No hay comando en este script que no se encuentre en sitios y foros como stackoverflow, repositorios de github, rpubs, los manuales de Wickham, The R graph gallery, etc.
Aviso: Este blog tiene como propósito exponer comandos para la elaboración de gráficos en ggplot2, sin embargo, como una forma de ampliar su alcance y mejorar respecto a Apuntes de ggplot2 pt. 1, en esta entrega se presenta la manipulación necesaria de los dataframes, los cuales están elaborados con la librería pwt10. Esta librería es una base de datos que recoge información sobre los niveles relativos de ingresos, producción, insumos y productividad de 183 países entre 1950 y 2019. Para más información visita su sitio web.
Si algún enlace no abre click izquierdo, intenta usar click derecho y abrir en otra pestaña.
Por último, hay comandos que no me detendré a explicar ampliamente porque ya fueron explicados en la primera parte de estos apuntes.
Cualquier corrección o comentario házmelo saber por este medio o a través de mi twitter ecodiegoale.
En este blog encontrarás principalmente códigos sobre la realización de gráficos con ggplot2, como la manipulación y diseño de la caja de leyendas en los gráficos, manejo de escalas de colores, principalmente con el paquete RColorBrewer, manipulación y diseño del panel de fondo y los bordes de los gráficos, texto de las leyendas en los gráficos de línea, anotaciones sobre el área del gráfico, entre otros. En cuanto a la manipulación de los dataframes, se verán comandos que ayuden a pasar una tabla de vertical a horizontal, manipulación de columnas y filas, filtrar valores, calcular tasas de crecimiento, etc., todo con la librería tidyverse.
Preparamos el directorio de trabajo.
#setwd("C:/Users/Ejemplo/Documents/R")
rm(list = ls()) #para borrar todos los objetos en la memoria de la consola
options(scipen=999) #para desactivar la notación científica
Ahora los paquetes.
#Si no cuentas con los paquetes, instálalos utilizando el comando install.packages("ejemplo")
library(pwt10)
library(tidyverse)
library(gridExtra)
library(ggthemes)
library(ggrepel)
library(scales)
library(RColorBrewer)
library(reshape2)
library(geomtextpath)
library(ggtext)
Para esto es necesario instalar la librería pwt10 (install.packages(“pwt10”)). Una vez instalada procedemos a explorar la base de datos. Para esto puedes correr el siguiente código en tu consola:
#??pwt10
Haciendo esto aparecerá la documentación de la librería, donde podrás ver todas las variables que contiene y el número de observaciones (52 y 12,810 respectivamente).
Por el momento solo usaremos las variables country, isocode, year y rgdpe. La variable rgdpe, como explica la documentación o el sitio web, es el PIB real por el lado del gasto a valores PPP (paridad de poder adquisitivo) en millones de dólares de 2017.
Una vez reconocida la base procedemos a crear nuestro dataframe.
ppp.DF <- data.frame(country = pwt10.0$country, isocode = pwt10.0$isocode,
year = pwt10.0$year, gdp = pwt10.0$rgdpe)
El resultado será una base 4 variables con 12,810 observaciones.
Ahora bien, una variable que puede resultar interesante pero que explícitamente no viene en la librería es el PIB per cápita, el cual no es más que el PIB dividido por la población respectiva de cada país. Podemos generar esta variable con la información disponible.
ppp.DF$pc.GDP <- (pwt10.0$rgdpe / pwt10.0$pop) / 1000.0
#Al dividir entre 1000 estamos definiendo al PIB per cápita en miles de dólares
Vemos la información relevante de la base ya completa.
dplyr::glimpse(ppp.DF)
## Rows: 12,810
## Columns: 5
## $ country <fct> "Aruba", "Aruba", "Aruba", "Aruba", "Aruba", "Aruba", "Aruba",~
## $ isocode <fct> ABW, ABW, ABW, ABW, ABW, ABW, ABW, ABW, ABW, ABW, ABW, ABW, AB~
## $ year <int> 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 19~
## $ gdp <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA~
## $ pc.GDP <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA~
Con el comando anterior podemos ver resumidas las filas y columnas y el tipo de datos que es cada variable.
Con tanta información para tantos años podemos preguntarnos muchas cosas, por ejemplo, yo me pregunto cuáles son los 15 países con mayor PIB para el último año disponible.
Para responder esta pregunta, procedemos a crear el dataframe que nos ayudará a saber y ver la respuesta.
pib2019<-ppp.DF %>% dplyr::filter(year==2019) %>%
select(country, year, gdp, pc.GDP)
#filtramos la variable year con 2019, pues es el último año disponible.
#Seleccionamos únicamente la variable country, year y gdp.
pib2019<-dplyr::arrange(pib2019, desc(gdp))#ordenamos la variable pib de mayor a menor
pib2019<-data.frame(pib2019[1:15,])
#seleccionamos únicamente las primeras 15 filas y todas las columnas.
Vemos el resultado:
head(pib2019)
## country year gdp pc.GDP
## 1 United States of America 2019 20856496 63.381099
## 2 China 2019 17681532 12.332078
## 3 India 2019 8939604 6.542365
## 4 Japan 2019 5023986 39.602507
## 5 Germany 2019 4431448 53.060396
## 6 Russian Federation 2019 4191903 28.736808
Procedemos a graficar.
pib2019.plot<-ggplot(data=pib2019, aes(country, gdp)) +
geom_bar(stat = 'identity')
pib2019.plot
Este gráfico no luce muy bien ni responde claramente nuestra pregunta. Primero, necesitamos que los países estén ordenados de mayor a menor como en la tabla que hicimos.
pib2019.plot<-ggplot(data=pib2019, aes(reorder(country, gdp, sum), gdp))+
#para reordenarlos
geom_bar(stat = 'identity')+
coord_flip()#para cambiar la orientación del gráfico
pib2019.plot
El gráfico claramenre resuelve nuestra pregunta, pero podemos mejorar aún más la visualización de datos. Lo primero que podemos hacer es agregar títulos y nombres apropiados a los ejes, así como separar con comas los miles en el eje x (gdp).
pib2019.plot+
labs(title = "Los 15 países con mayor PIB para 2019",
x="",
y ="PIB real (PPP) en millones de dólares de 2017",
caption="Fuente: Elaboración propia con información de Penn World Table 10.0")+
scale_y_continuous(label=comma)
¿Puede verse todavía mejor? Claro que sí. Empecemos por cambiar el fondo del área del gráfico y sus márgenes. Para eso usaremos panel.background y panel.border dentro de la función theme(). Como lo único que deseo es que el fondo sea blanco y los bordes negros haré lo siguiente: panel.background=element_blank(), para indicar que lo quiero en blanco, y panel.border=element_rect(colour = "black", fill=NA, size=1) para indicar los bordes negros.
pib2019.plot<-ggplot(data=pib2019, aes(reorder(country, gdp, sum), gdp))+
geom_bar(stat = 'identity')+
coord_flip()+
labs(title = "Los 15 países con mayor PIB para 2019",
x="",
y ="PIB real (PPP) en millones de dólares de 2017",
caption="Fuente: Elaboración propia con información de Penn World Table 10.0")+
scale_y_continuous(label=comma)+
theme(plot.caption=element_text(hjust=0,size=9),
plot.title=element_text(hjust=0.5, size=14,face="bold"),
legend.position="none",
panel.background = element_blank(),
panel.border = element_rect(colour = "black", fill=NA, size=1),
axis.title.x=element_text(size=6),
axis.text.x=element_text(angle =0,vjust =0.2,
hjust=0.5, colour = "black"),
axis.text.y = element_text(hjust = 1,
colour = "black",
size = 8),
)
pib2019.plot
Este gráfico ya es claro y visualmente agradable, sin embargo, bastante triste; vamos a agregar colores. Para esto usaremos la librería RColorBrewer. Esta librería cuenta con distintas y variadas paletas de colores; la paleta que usaré se llama RdYlBu. Para más detalle sobre estas paletas revisa aquí.
Sin embargo, esta paleta no tiene los suficientes colores para abarcar los 15 países del gráfico, por lo que procederemos a ampliarla de la siguiente manera:
colourCount = length(unique(pib2019$country))#ampliamos la selección de colores de las paletas de RColorBrewer
getPalette = colorRampPalette(brewer.pal(15, "RdYlBu")) #selecciono la paleta RdYlBu
Una vez ampliada, procedemos a poner un color diferente a cada país, para esto hay que poner atención en dos cosas: la primera es que en el comando aes() al momento de definir los valores de cada eje agregaremos el comando fill=country para indicar que cada columna del gráfico será de un color diferente dependiendo del país; lo segundo es la función scale_fill_manual() para indicar la paleta a usar.
pib2019.plot<-ggplot(data=pib2019, aes(reorder(country, gdp, sum), gdp, fill=country))+
geom_bar(stat = 'identity')+
coord_flip()+
labs(title = "Los 15 países con mayor PIB para 2019",
x="",
y ="PIB real (PPP) en millones de dólares de 2017",
caption="Fuente: Elaboración propia con información de Penn World Table 10.0")+
scale_y_continuous(label=comma)+
theme(plot.caption=element_text(hjust=0,size=9),
plot.title=element_text(hjust=0.5, size=14,face="bold"),
legend.position="none",
panel.background = element_blank(),
panel.border = element_rect(colour = "black", fill=NA, size=1),
axis.title.x=element_text(size=6),
axis.text.x=element_text(angle =0,vjust =0.2,
hjust=0.5, colour = "black"),
axis.text.y = element_text(hjust = 1,
colour = "black",
size = 8),
)+
scale_fill_manual(values = getPalette(colourCount))+
geom_text(aes(label = scales::comma(round(gdp,-1))),
size = 3, hjust = 1, nudge_x = -0.5, vjust=-0.5)
pib2019.plot
Una cosa es el PIB de las economías, y otra muy distinta es su PIB per cápita, por ejemplo, es bien sabido que India es un país con mucha pobreza, sin embargo, vemos que para 2019 fue la tercera economía más grande. Para ver la evolución del PIB per cápita de las tres economías más grandes y de México haremos un gráfico de líneas.
Antes de graficar, necesitamos hacer un nuevo dataframe. Sabemos que para 2019 las tres economías más grandes fueron Estados Unidos, China e India, además queremos comparar con México.
CHN.DF<- ppp.DF %>% filter(isocode == "CHN")
USA.DF<- ppp.DF %>% filter(isocode == "USA")
MEX.DF<- ppp.DF %>% filter(isocode == "MEX")
IND.DF<- ppp.DF %>% filter(isocode == "IND")
PIBpc<-rbind(CHN.DF,USA.DF,MEX.DF,IND.DF)
head(PIBpc)
## country isocode year gdp pc.GDP
## 1 China CHN 1950 NA NA
## 2 China CHN 1951 NA NA
## 3 China CHN 1952 616191.9 1.063175
## 4 China CHN 1953 695048.7 1.179414
## 5 China CHN 1954 645550.1 1.076019
## 6 China CHN 1955 707586.1 1.156086
Tenemos un dataframe de 5 columnas con 280 filas, una columna para todos los países, otra para los años y otra para los valores de la serie que nos interesan. Sin embargo, de la forma en que está acomodado este dataframe no nos es posible graficar una gráfica de líneas con ggplot2, necesitamos un dataframe con columnas para cada país. Por lo tanto procedemos con lo siguiente:
pib.pc<-data.frame(dcast(PIBpc, year ~ country, value.var='pc.GDP'))
head(pib.pc)
## year China India Mexico United.States.of.America
## 1 1950 NA 0.9423045 4.951872 15.73751
## 2 1951 NA 0.9647629 5.205037 16.56401
## 3 1952 1.063175 0.9747174 5.301661 16.89387
## 4 1953 1.179414 1.0079172 5.013598 17.43327
## 5 1954 1.076019 1.0323809 5.410807 17.04305
## 6 1955 1.156086 1.0354973 5.686141 18.02090
De esta manera se han ido las columnas isocode y gdp, pues solo queremos el pc.GDP de cada país, asimismo, ahora cada país tiene su propia columna. Ya transformado nuestro cuadro, procedemos a graficar.
pibpc.plot<-ggplot(data=pib.pc, aes(x=year))+
geom_line(aes(y=China, color = 'China'), cex = 1)+
geom_line(aes(y=India, color = 'India'), cex = 1)+
geom_line(aes(y=Mexico, color = 'México'),cex = 1)+
geom_line(aes(y=United.States.of.America, color = 'Estados Unidos'),cex = 1)+
scale_colour_brewer(name=" ",
palette="RdYlBu",
direction = -1)+
theme(plot.caption=element_text(hjust=0,size=9),
plot.title=element_text(hjust=0.5, size=14,face="bold"),
plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
axis.text.x=element_text(angle =0,vjust =1,
hjust=1, colour = "black"),
legend.position=c(0.2,0.7),
legend.title = element_blank(),
legend.background = element_rect(fill = NA,
colour = 1),
panel.background = element_blank(),
panel.border = element_rect(colour = "black", fill=NA, size=1),
axis.text.y = element_text(hjust = 0,
colour = "black",
size = 8))+
labs(title="Evolución del PIB per cápita real (PPA)",
subtitle = "Miles de dólares de 2017",
caption="Fuente: Elaboración propia con información de Penn World Table 10.0")+
xlab(" ")+
ylab("")+
scale_y_continuous(label=comma)
pibpc.plot
Los resultados contrastan con el primer gráfico, México fue de las 15 economías más grandes del 2019 por debajo de EE.UU., India y China, empero, en términos per cápita, muestra un mejor desempeño a lo largo de los años.
Con el gráfico anterior hicimos que la caja de leyenda esté dentro del área del gráfico, definimos bordes negros y fondo blanco para dicha caja, ahora bien, si no queremos cajas de leyenda pero aún así queremos que cada línea esté identificada con un color distinto y su nombre haremos lo siguiente:
PIBpc<-PIBpc%>%select(-isocode, -gdp) #eliminamos las columnas isocode y gdp
PIBpc$label <- NA #creamos una nueva columna llamada label llena de NAs
PIBpc=select(PIBpc,year,pc.GDP,country,label) #ordenamos las columnas en el orden que queremos
PIBpc$country<-as.character(PIBpc$country) #convertimos los valores de la columna country de factor a character, de otra manera no podremos agregar las etiquetas directamente a las líneas del gráfico
PIBpc$label[which(PIBpc$year == max(PIBpc$year))] <-
PIBpc$country[which(PIBpc$year == max(PIBpc$year))] #con esta instrucción indicamos que en la columna NA solo agregue el nombre del país correspondiente al último año (2019)
tail(PIBpc)
## year pc.GDP country label
## 275 2014 5.164249 India <NA>
## 276 2015 5.463602 India <NA>
## 277 2016 5.770233 India <NA>
## 278 2017 6.027555 India <NA>
## 279 2018 6.364329 India <NA>
## 280 2019 6.542365 India India
Ya con el dataframe en mano pasamos a graficar.
pibpc2.plot<-ggplot(data=PIBpc,
aes(x=year, y=pc.GDP, col=country))+
geom_line(cex = 1)+
theme(plot.caption=element_text(hjust=0,size=9),
plot.title=element_text(hjust=0.5, size=14,face="bold"),
plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
legend.position="none",
legend.title = element_blank(),
panel.background = element_blank(),
panel.border = element_rect(colour = "black", fill=NA, size=1),
axis.text.x=element_text(angle =0,vjust =1,
hjust=1, colour = "black"),
axis.text.y = element_text(hjust = 0,
colour = "black",
size = 8)
)+
scale_colour_brewer(name=" ",
palette="RdYlBu",
direction = 1)+
geom_label_repel(aes(label = label),
nudge_x = 1,
na.rm = TRUE)+
labs(title="Evolución del PIB per cápita real (PPA)",
subtitle = "Miles de dólares de 2017",
caption="Fuente: Elaboración propia con información de Penn World Table 10.0")+
xlab(" ")+
ylab("")+
scale_y_continuous(label=comma)
pibpc2.plot
Una tasa de crecimiento (TDC) es el cambio positivo en porcentaje de una variable entre dos momentos distintos del tiempo. La fórmula para calcularla es:
\(TDC=\left(\frac{V_1}{V_0}-1\right)\times100\)
donde \(V_1\) es el valor presente y \(V_0\) el valor pasado.
Vamos a calcular la tasa de crecimiento del PIB per cápita para México. El resultado será una serie de 1951 a 2019. 1950 no cuenta porque es el año inicial.
MEX.TDC=MEX.DF%>%
mutate(Diff_year = year - lag(year), # Restar los años tiempo en caso de que haya brechas (año actual - año anterior)
Diff_growth = pc.GDP - lag(pc.GDP), # Restar al valor presente del pib pc el valor inmediato anterior
Rate_percent = (Diff_growth / Diff_year)/pc.GDP * 100) # TDC en %)
head(MEX.TDC)
## country isocode year gdp pc.GDP Diff_year Diff_growth Rate_percent
## 1 Mexico MEX 1950 137629.6 4.951872 NA NA NA
## 2 Mexico MEX 1951 148785.0 5.205037 1 0.25316433 4.863834
## 3 Mexico MEX 1952 155934.0 5.301661 1 0.09662417 1.822526
## 4 Mexico MEX 1953 151800.3 5.013598 1 -0.28806260 -5.745626
## 5 Mexico MEX 1954 168725.3 5.410807 1 0.39720864 7.341024
## 6 Mexico MEX 1955 182697.1 5.686141 1 0.27533432 4.842200
MEX.TDC.plot<-ggplot(data=MEX.TDC,
aes(x=year, y=Rate_percent))+
geom_line(cex = 0.8, col="#4575b4")+
geom_hline(yintercept = 0, size=0.8, col="black")+
theme(plot.caption=element_text(hjust=0,size=9),
plot.title=element_text(hjust=0.5, size=14,face="bold"),
plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
legend.position="none",
legend.title = element_blank(),
panel.background = element_blank(),
panel.border = element_rect(colour = "black", fill=NA, size=1),
axis.text.x=element_text(angle =0,vjust =1,
hjust=1, colour = "black"),
axis.text.y = element_text(hjust = 0,
colour = "black",
size = 8)
)+
labs(title="Variación anual del PIB real per cápita de México",
caption="Fuente: Elaboración propia con información de Penn World Table 10.0")+
xlab(" ")+
ylab("Puntos porcentuales")
MEX.TDC.plot
Con esto podemos observar cómo creció la serie del PIB per cápita para México cada año en más de 50 años, podemos observar los principales picos y caídas en el ingreso, pero si lo que queremos saber es cuánto creció el ingreso en promedio cada año para todo el periodo, lo que necesitamos es calcular es la tasa de crecimiento promedio (TDCP), esta es el promedio básico de tasas de crecimiento para una secuencia de periodos. Su fórmula es la siguiente:
\(TDCP=\left(\left(\frac{V_f}{V_i}\right)^\frac{1}{n}-1\right)\times100\)
donde \(V_f\) es el valor final de la serie (el PIB pc para 2019), \(V_i\) el valor inicial de la serie (el PIB pc para 1950) y \(n\) el número de periodos (años).
Procedemos a calcularlo:
V_i<-MEX.DF%>%
filter(year==1950)%>%
select(pc.GDP)
V_f<-MEX.DF%>%
filter(year==2019)%>%
select(pc.GDP)
n<-length(MEX.DF$year)
TDCP=((V_f/V_i)^(1/n)-1)*100
TDCP
## pc.GDP
## 1 1.961655
En promedio, cada año el ingreso per cápita de México creció un 1.96% en 70 años. Podemos agregar esto al gráfico anterior.
texto.PIBpc <- 'La tasa de crecimiento medio del PIB per cápita en <br><br><span style="color:#4575b4;">**México**</span> para el periodo 1950-2019 es de <span style="color:#d73027;">**1.96%**</span>'
MEX.TDC.plot+
geom_hline(yintercept = 1.96, size=0.8, col="#d73027",linetype = 'dashed')+
annotate(geom = "richtext",
x = 1970, y = 11,
label = texto.PIBpc,
label.colour = NA, fill = NA,
fontface = "bold",
color = "black",
size = 2.5)
Feenstra, Robert C., Robert Inklaar and Marcel P. Timmer (2015), “The Next Generation of the Penn World Table” American Economic Review, 105(10), 3150-3182, available for download at www.ggdc.net/pwt