Hasta este punto en el curso, nos hemos enfocado en las diferentes etapas del trabajo con bases de datos para obtener un insumo limpio, ordenado, estructurado y listo para ser analizado. Este proceso incluye la apertura, limpieza, formateo, agregación y unificación de los datos. Una vez logrado esto, estamos preparados para presentar nuestros resultados a un público no necesariamente familiarizado con el análisis cuantitativo. Por ello, debemos procurar presentar nuestra información y contar la historia de la manera más clara y efectiva posible.

A esto se le conoce como visualización de datos o storytelling con datos. Existe una gran variedad de gráficos que se pueden utilizar, dependiendo del interés y los objetivos del investigador. Aquí algunos ejemplos útiles: https://www.data-to-viz.com/

La visualización de datos es importante, ya que ayuda a contar historias y a dar sentido a los datos con los que trabajamos, facilitando la comprensión de la información.

Sin embargo, es crucial tener en cuenta que la finalidad de la visualización es facilitar la comprensión, por lo que hay que ser cuidadosos con la elección de ciertos tipos de gráficos. Por ejemplo, el gráfico de sectores o pie chart puede no ser siempre la mejor opción, a pesar de que la variable analizada lo permita. Para profundizar en este tema: https://www.data-to-viz.com/caveat/pie.html

Veamos algunos ejemplos:

1. Gráficos de barras

Vamos a traer de un repo de Github la última ola del Barómetro de las Américas para medir el nivel de confianza en los medios de comunicación (b37) en la región:

library(rio)
lapop = import("LAPOP_reduced_merge.dta")

Para graficar los resultados de esta variable, hay que tomar en cuenta que tiene 7 categorías. Presentar tantas opciones en un gráfico, para varios países a la vez, podría confundir al espectador/a. Tenemos que manipular un poco la información.

# Explorar la variable de confianza en los medios (b37)
table(lapop$b37)
## 
##     1     2     3     4     5     6     7 
##  7257  5675  8471 12308 12922  9597  9407

Donde 1 es “nada de confianza” y 7 es “mucha confianza”, vamos a volver esta variable dicotómica para facilitar la visualización:

# Recodificar la variable b37 de 7 categorías a dicotómica
library(car)
## Loading required package: carData
lapop$b37r <- car::recode(lapop$b37, "1:4=0 ; 5:7=100")
table(lapop$b37r)
## 
##     0   100 
## 33711 31926

Al momento de leer la base de datos en R, el software importa las variables como numéricas. La variable “pais” se tiene que convertir en una variable de tipo “factor” y se tiene que etiquetar.

# Convertir la variable "pais" a factor y etiquetar los niveles
lapop$pais <- as.factor(lapop$pais)
levels(lapop$pais) <- c("México", "Guatemala", "El Salvador", "Honduras",
"Nicaragua","Costa Rica", "Panamá", "Colombia",
"Ecuador", "Bolivia", "Perú", "Paraguay",
"Chile", "Uruguay", "Brasil", "Venezuela",
"Argentina", "Rep. Dom.", "Haití", "Jamaica",
"Estados Unidos", "Canada")

table(lapop$pais)
## 
##         México      Guatemala    El Salvador       Honduras      Nicaragua 
##           3143           3142           3062           3120           3107 
##     Costa Rica         Panamá       Colombia        Ecuador        Bolivia 
##           3015           3080           3226           3078           3373 
##           Perú       Paraguay          Chile        Uruguay         Brasil 
##           4168           3043           3263           3095           3030 
##      Venezuela      Argentina      Rep. Dom.          Haití        Jamaica 
##           1558           3056           3034           2221           3028 
## Estados Unidos         Canada 
##           3000           3019
table(lapop$pais, lapop$year)
##                 
##                  2016 2017 2018 2019
##   México         1563    0    0 1580
##   Guatemala         0 1546    0 1596
##   El Salvador    1551    0 1511    0
##   Honduras       1560    0 1560    0
##   Nicaragua      1560    0    0 1547
##   Costa Rica     1514    0 1501    0
##   Panamá            0 1521 1559    0
##   Colombia       1563    0 1663    0
##   Ecuador        1545    0    0 1533
##   Bolivia           0 1691    0 1682
##   Perú              0 2647    0 1521
##   Paraguay       1528    0    0 1515
##   Chile             0 1625    0 1638
##   Uruguay           0 1514    0 1581
##   Brasil            0 1532    0 1498
##   Venezuela      1558    0    0    0
##   Argentina         0 1528    0 1528
##   Rep. Dom.      1518    0    0 1516
##   Haití             0 2221    0    0
##   Jamaica           0 1515    0 1513
##   Estados Unidos    0 1500    0 1500
##   Canada            0 1511    0 1508

Queremos hacer un gráfico de barras con intervalos de confianza para evaluar el nivel de confianza en los medios en perspectiva comparada. Para eso, necesitamos hacer una tabla que le saque el promedio a la variable (que es la proporción de personas que dicen confiar en los medios). La función summarySE es útil para eso:

# Calcular el promedio de confianza por país usando summarySE()
library(Rmisc)
## Loading required package: lattice
## Loading required package: plyr
df <- summarySE(data = lapop, measurevar = "b37r", groupvar = "pais", na.rm = TRUE)
df
##              pais    N     b37r       sd        se       ci
## 1          México 3072 41.76432 49.32510 0.8899331 1.744925
## 2       Guatemala 3051 53.75287 49.86713 0.9028036 1.770165
## 3     El Salvador 3046 50.36113 50.00691 0.9060768 1.776584
## 4        Honduras 3086 53.49968 49.88546 0.8979993 1.760737
## 5       Nicaragua 3058 62.09941 48.52189 0.8774432 1.720438
## 6      Costa Rica 2994 51.87041 49.97335 0.9132981 1.790756
## 7          Panamá 3056 60.20942 48.95459 0.8855575 1.736349
## 8        Colombia 3191 41.24099 49.23453 0.8715784 1.708911
## 9         Ecuador 3055 54.07529 49.84180 0.9017541 1.768106
## 10        Bolivia 3317 51.31143 49.99033 0.8679872 1.701845
## 11           Perú 4145 43.49819 49.58144 0.7701173 1.509843
## 12       Paraguay 2995 61.13523 48.75244 0.8908364 1.746713
## 13          Chile 3232 41.52228 49.28367 0.8668967 1.699723
## 14        Uruguay 3064 45.98564 49.84672 0.9005177 1.765680
## 15         Brasil 3005 52.51248 49.94515 0.9111105 1.786464
## 16      Venezuela 1533 51.79387 49.98412 1.2766179 2.504103
## 17      Argentina 3027 39.18071 48.82346 0.8874060 1.739980
## 18      Rep. Dom. 3000 65.83333 47.43475 0.8660361 1.698085
## 19          Haití 2032 39.12402 48.81481 1.0829035 2.123717
## 20        Jamaica 2664 38.40090 48.64514 0.9424803 1.848068
## 21 Estados Unidos 2995 27.31219 44.56373 0.8142976 1.596639
## 22         Canada 3019 43.12686 49.53355 0.9015045 1.767625

Con esta estructura de datos, ya podemos graficar. El nivel más sencillo de visualización sería con lenguaje base de R o códigos simples de la librería ggplot. Todo empezaría así:

library(ggplot2)
library(farver)
ggplot(df, aes(x=pais, y=b37r)) + 
  geom_bar(stat = "identity") 

Eso no dice básicamente nada. Mejoremos el gráfico un poco. Podríamos voltearlo para que tenga más sentido.

ggplot(df, aes(x=pais, y=b37r)) + 
  geom_bar(stat = "identity") + coord_flip()

Sigue sin ayudarnos a entender a qué país le va mejor y a cuál le va peor en términos de confianza en los medios. Cambiemos algunas cosas adicionales: reordenemos la columnas y pongamos títulos a los ejes:

# Mejorar el gráfico: voltear ejes, reordenar barras y agregar títulos
ggplot(df, aes(x = reorder(pais, b37r), y = b37r)) +
geom_bar(stat = "identity") +
coord_flip() +
labs(title = "Confianza en los medios en las Américas",
subtitle = "Barómetro de las Américas",
x = " ",
y = "Escala 0 - 100")

Eso está bastante mejor, pero sería bueno que pongamos el valor que obtiene cada país para ese año:

# Mejorar el gráfico: voltear ejes, reordenar barras, agregar títulos y porcentajes
ggplot(df, aes(x = reorder(pais, b37r), y = b37r)) +
geom_bar(stat = "identity") +
coord_flip() +
labs(title = "Confianza en los medios en las Américas",
subtitle = "Barómetro de las Américas",
x = " ",
y = "Escala 0 - 100") +
geom_text(aes(label = paste0(round(b37r, 0), "%")), vjust = 0.5, hjust = 1.2, color = "white", size = 3)

Se ve un poco feo. Cambiemos el tamaño, ubicación y color. También podemos ponerle el símbolo de % y una línea con el promedio para saber quiénes pasan y quiénes no:

ggplot(df, aes(x=reorder(pais,b37r), y=b37r), fill = select) + 
  geom_bar(stat = "identity") +
  coord_flip()+
  
  labs(title = "Confianza en los medios en las Américas",
       subtitle = "Barómetro de las Américas",
       x = " ",
       y = "Escala 0 - 100") +

    geom_hline(yintercept = mean(df$b37r) ,linetype="dashed", color="blue",size=1)+
  
    ylim(0, 80) +

    geom_text(aes(label=paste0(round(b37r,0),"%")), vjust=0.5, hjust = 1.2,color="white", size=3)
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

#procuremos de que empiece por 0 #se podría especificar de 0 a 100 para que visualmente se vea mejor

Faltan los intervalos de confianza: #Para esto se debe agregar la función de geom_bar

# Agregar línea de promedio e intervalos de confianza
g1 <- ggplot(df, aes(x = reorder(pais, b37r), y = b37r)) +
geom_bar(stat = "identity") +
geom_errorbar(aes(ymin = b37r - ci, ymax = b37r + ci), width = 0.2) +
coord_flip() +
labs(title = "Confianza en los medios en las Américas",
subtitle = "Barómetro de las Américas",
x = " ",
y = "Escala 0 - 100") +
geom_hline(yintercept = mean(df$b37r), linetype = "dashed", color = "blue", size = 1) +
ylim(0, 80) +
geom_text(aes(label = paste0(round(b37r, 0), "%")), vjust = 0.5, hjust = -1, color = "black", size = 3)

g1

El gráfico ya estaría prácticamente listo. Sin embargo, hay algunas librerías que aplican automaticamente “temas” al gráfico para mejorarlo. Una es ggthemes. Pueden jugar con sus funciones aquí: https://statisticsglobe.com/ggthemes-package-r. Veamos lo que puede hacer. También podemos ajustar los tamaños del gráfico en su conjunto:

# Aplicar temas predefinidos de ggplot2
library(ggthemes)
g1 + theme_economist_white()

Otro tema:

g1 + theme_economist()

¿Presentar más información? Qué pasa si queremos trabajar con barras agrupadas. Por ejemplo, si queremos mostrar no solo la confianza en los medios, sino también la atención que la ciudadanía le da a los medios. Hagamos el ejercicio.

La variable:

# Explorar la variable de atención a los medios (gi0)
str(lapop$gi0)
##  num [1:66861] 2 2 2 2 2 2 2 2 1 2 ...
##  - attr(*, "label")= chr "Frequency of Paying Attention to the News"
##  - attr(*, "format.stata")= chr "%36.0g"
##  - attr(*, "labels")= Named num [1:9] 1 2 3 4 5 NA NA NA NA
##   ..- attr(*, "names")= chr [1:9] "Daily" "A few times a week" "A few times a month" "Rarely" ...
table(lapop$gi0)
## 
##     1     2     3     4     5 
## 23162  8462  1009  3220  1290

Los valores están invertidos. Hacemos una recodificación simple.

# Recodificar la variable gi0
lapop$gi0r <- car::recode(lapop$gi0, "3:5=0 ; 1:2=100")
table(lapop$gi0r)
## 
##     0   100 
##  5519 31624

Construimos la tabla con todos los detalles.

# Calcular el promedio de atención por país usando summarySE()
df1 <- summarySE(data = lapop, measurevar = "gi0r", groupvar = "pais", na.rm = TRUE)
df1
##              pais    N     gi0r       sd        se       ci
## 1          México 1554 80.63063 39.53189 1.0028178 1.967020
## 2       Guatemala 1535 81.56352 38.79078 0.9900892 1.942071
## 3     El Salvador 1549 80.11620 39.92547 1.0144353 1.989812
## 4        Honduras 1552 82.21649 38.24971 0.9709174 1.904449
## 5       Nicaragua 1555 85.65916 35.06016 0.8890960 1.743954
## 6      Costa Rica 1513 88.16920 32.30793 0.8305956 1.629242
## 7          Panamá 1513 82.81560 37.73695 0.9701690 1.903020
## 8        Colombia 1561 86.86739 33.78649 0.8551486 1.677362
## 9         Ecuador 1540 85.71429 35.00408 0.8919865 1.749637
## 10        Bolivia 1683 88.53238 31.87254 0.7769171 1.523826
## 11           Perú 2635 89.44972 30.72586 0.5985683 1.173712
## 12       Paraguay 1495 87.75920 32.78661 0.8479612 1.663321
## 13          Chile 1621 87.72363 32.82671 0.8153345 1.599221
## 14        Uruguay 1512 93.12169 25.31686 0.6510794 1.277115
## 15         Brasil 1529 84.82668 35.88794 0.9177932 1.800268
## 16      Venezuela 1554 85.19949 35.52194 0.9010962 1.767494
## 17      Argentina 1527 88.93255 31.38314 0.8031135 1.575323
## 18      Rep. Dom. 1511 89.54335 30.60954 0.7874527 1.544617
## 19          Haití 2175 58.39080 49.30225 1.0571512 2.073133
## 20        Jamaica 1510 87.94702 32.56879 0.8381334 1.644030
## 21 Estados Unidos 1500 89.06667 31.21610 0.8059964 1.581000
## 22         Canada 3019 91.15601 28.39806 0.5168412 1.013397

Juntamos la información, pero antes necesitamos diferenciar una cosa de la otra:

# Crear una columna para diferenciar confianza y atención
df$type <- "Trust in media"
df1$type <- "Attention to news"

Los nombres de las columnas deben ser los mismos. Solo hay uno que se diferencia:

colnames(df)[3] = "value"
colnames(df1)[3] = "value"

Ahora sí. ¿Alguien sabe por qué no hice merge? #En ambas bases tienen los mismos nombres de variables, cuando se hace merge una se guarda como direccion x y “y”. Por lo que es mejor usar dff, para unir todo en una sola base

# Combinar los dataframes de confianza y atención
dff <- rbind(df, df1)

Graficamos. El principal detalle aquí está en position, donde ponemos dodge. Ver: https://r-graph-gallery.com/48-grouped-barplot-with-ggplot2

# Crear un gráfico de barras agrupadas para confianza y atención
g2 <- ggplot(dff, aes(x = reorder(pais, value), y = value, fill = type)) +
geom_bar(position = "dodge", stat = "identity") +
coord_flip() +
geom_errorbar(aes(ymin = value - ci, ymax = value + ci), position = position_dodge(0.95), width = 0.2) +
labs(title = "Confianza y atención a los medios en las Américas",
subtitle = "Barómetro de las Américas",
x = " ",
y = "Escala 0 - 100") +
geom_text(aes(label = paste0(round(value, 0), "%")), vjust = 0.5, hjust = -0.8, color = "black", size = 3,
position = position_dodge(width = 1)) +
theme(legend.position = "bottom") + labs(fill = ' ')

g2

Le damos un tema y cambiamos las dimensiones para que se vea mejor:

También podemos escoger paletas de colores interesantes que podemos agregar a nuestros gráficos en ggplot. Por ejemplo, la librería peRReo toma las paletas de colores de varios artistas: https://github.com/jbgb13/peRReo#building-palettes

#con esta funcion le estamos pidiendo que guarde la paleta babbunny2, estamos trabajando con una variable numerica, por lo que pedimos que la escala sea continua

#install.packages("devtools")
library(callr)
devtools::install_github("jbgb13/peRReo") 
## Skipping install of 'peRReo' from a github remote, the SHA1 (aadce920) has not changed since last install.
##   Use `force = TRUE` to force installation
#install.packages("peRReo")
library(peRReo)
pal=latin_palette("shakira",2,type="continuous")

#scale_fill_manual es para que rellene los vacios de color manualmente

También tenemos de Taylor Swift:

Instalamos esto en R y llamamos a la librería “taylor”

#remotes::install_github("wjakethompson/taylor")

Más información sobre esta librería por aquí: https://taylor.wjakethompson.com/index.html

Pueden encontrar más alternativas en: taylor_album_songs

# Hacer el gráfico interactivo con plotly
library(plotly)
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following objects are masked from 'package:plyr':
## 
##     arrange, mutate, rename, summarise
## The following object is masked from 'package:rio':
## 
##     export
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
gg <- ggplotly(g3)
gg

2. Gráficos de líneas

¿Cómo ha evolucionado el país en términos de democratización? Al hablar de “evolución”, nos referimos inevitablemente a un componente temporal. Un gráfico de líneas puede ser útil. Traigamos una base para ejemplificarlo:

# Cargar la base de datos de V-Dem
vdem <- import("vdemdata.csv")
# Filtrar los datos para Perú
per <- vdem[vdem$country_name == "Peru",]

Podemos ver la evolución de la democracia en el Perú:

# Crear un gráfico de líneas básico para la evolución de la democracia en Perú
g1 <- ggplot(per, aes(x = year, y = v2x_polyarchy)) +
geom_line()

Podemos mejorarlo bastante. Lo bueno de ggplot es que sigue la misma lógica para casi todos los gráficos:

# Mejorar el gráfico con títulos, etiquetas y tema
g2 <- ggplot(per, aes(x = year, y = v2x_polyarchy)) +
geom_line() +
labs(title = "Índice de democracia electoral - Perú",
subtitle = "V-Dem",
x = "Año",
y = "Escala 0 - 1") +
guides(col = guide_legend("Grupo:")) +
theme_fivethirtyeight()

g2
## Warning: Removed 32 rows containing missing values or values outside the scale range
## (`geom_line()`).

# Hacer el gráfico interactivo con plotly
gg1 <- ggplotly(g2)
gg1

¿Lo vemos en perspectiva comparada? Para eso necesitaríamos el promedio regional. Apliquemos funciones de dplyr que vimos en la clase de agregación de datos:

# Calcular el promedio regional de democracia por año usando dplyr
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:plyr':
## 
##     arrange, count, desc, failwith, id, mutate, rename, summarise,
##     summarize
## The following object is masked from 'package:car':
## 
##     recode
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
reg <- vdem %>%
group_by(year) %>%
summarise(democracy = mean(v2x_polyarchy, na.rm = TRUE))

Agregamos la identificación:

# Agregar una columna para identificar los datos regionales
reg$group <- "AL"

Necesitamos modificar la estructura de la base de Perú para juntar la información:

# Modificar la estructura de los datos de Perú para unirlos con los datos regionales
per <- per[, c(3, 4)]
per$group <- "PER"
colnames(per)[2] <- "democracy"

Juntamos todo. De nuevo, no hago merge, ¿se va entendiendo el tipo de estructura que necesitamos?

# Combinar los datos de Perú y los datos regionales
democ <- rbind(reg, per)
table(democ$group) # Verificar que todo esté bien
## 
##  AL PER 
## 232 232
# Crear un gráfico de líneas para comparar la evolución de la democracia en Perú y América Latina
g3 <- ggplot(democ, aes(x = year, y = democracy, colour = group, group = group)) +
geom_line() +
labs(title = "Índice de democracia electoral - Perú y América Latina",
subtitle = "V-Dem",
x = "Año",
y = "Escala 0 - 1") +
guides(col = guide_legend("Grupo:")) +
theme_fivethirtyeight()

g3
## Warning: Removed 32 rows containing missing values or values outside the scale range
## (`geom_line()`).

# Hacer el gráfico interactivo con plotly
gg2 <- ggplotly(g3)
## Warning: plotly.js does not (yet) support horizontal legend items 
## You can track progress here: 
## https://github.com/plotly/plotly.js/issues/53
gg2

3. Gráfico de dispersión de puntos

¿Tendrá una relación el apoyo a la democracia con el nivel de democratización de un país? Podríamos explorar una correlación entre ambas cosas. Traigamos la base:

# Cargar la base de datos
points <- import("scatter_data.csv")
# Crear un gráfico de dispersión básico
g1 <- ggplot(points, aes(x = v2x_polyarchy, y = democracy)) +
geom_point()

g1
## Warning: Removed 4 rows containing missing values or values outside the scale range
## (`geom_point()`).

Parece que hay una relación, pero no sabemos qué país representa cada punto. No son muchos, por lo que podríamos visualizar esto sin problema. Juguemos un poco con las funciones que estamos viendo en los ejemplos previos:

# Mejorar el gráfico de dispersión
g2 <- ggplot(points, aes(x = v2x_polyarchy, y = democracy)) +
geom_point(size = 1.5, shape = 23) +
geom_text(label = points$pais, vjust = -0.5, hjust = 1, color = "black", size = 3) +
labs(title = "Apoyo a la democracia e índice de democracia electoral \nen América Latina y El Caribe",
subtitle = "Barómetro de las Américas y V-Dem",
x = "Índice de democracia electoral",
y = "Apoyo a la democracia") +
theme_fivethirtyeight()

g2
## Warning: Removed 4 rows containing missing values or values outside the scale range
## (`geom_point()`).
## Warning: Removed 4 rows containing missing values or values outside the scale range
## (`geom_text()`).

# Hacer el gráfico interactivo con plotly
gg1 <- ggplotly(g2)
gg1

Eso está bastante mejor. Se podría decir que a mayor avance de democratización, mayor apoyo a la democracia. Pero vemos que Perú es un caso atípico. Podríamos resaltar esa diferencia con respecto al patrón observado:

Primero señalamos Perú en la base con un condicional simple:

# Resaltar Perú como un caso atípico
points$atipico <- factor(ifelse(points$pais == "Peru", 1, 0))
# Crear un gráfico de dispersión resaltando Perú
g3 <- ggplot(points, aes(x = v2x_polyarchy, y = democracy, color = atipico)) +
geom_point(size = 3, shape = 20) +
geom_text(label = points$pais, vjust = -0.5, hjust = 1, color = "black", size = 3) +
labs(title = "Apoyo a la democracia e índice de democracia electoral \nen América Latina y El Caribe",
subtitle = "Barómetro de las Américas y V-Dem",
x = "Índice de democracia electoral",
y = "Apoyo a la democracia") +
scale_color_manual(values = c('Blue', 'Red')) +
theme_fivethirtyeight()

g3

# Ocultar la leyenda
g4 <- g3 + theme(legend.position = "none")
# Hacer el gráfico interactivo con plotly
gg2 <- ggplotly(g4)
gg2

4. Barras de error

Cuando trabajamos con encuestas, hay que recordar que lo que obtenemos de la muestra son estimadores que, dentro de un intervalo de confianza, nos permiten hablar de la población en su conjunto a un % de confianza. ¿Cómo graficamos todo eso? Veamos:

Traigamos una base de datos que contiene información sobre un índice que muestra la disposición de la ciudadanía en el Perú a movilizarse políticamente para empujar ciertas demandas. Los datos provienen del Latinobarómetro para el año 2020:

# Cargar la base de datos
errorbars <- import("parpol_age.csv")

Arrancamos con lo más básico. Queremos ver si esta disposición varía entre grupos etarios:

# Crear un gráfico básico de líneas con barras de error
g1 <- ggplot(errorbars, aes(x = age, y = media, group = 1, label = media)) +
geom_line() +
geom_errorbar(width = .1, aes(ymin = media - ci, ymax = media + ci))

g1

No está tan mal, pero podríamos mejorarlo bastante. Lo primero sería ordenar el eje de las edades y asignarles nombres a cada categoría:

# Ordenar el eje de las edades y asignar nombres a cada categoría
errorbars$age <- factor(errorbars$age, levels = c(1:6), labels = c("25 o menos", "Entre 26 y 35",
"Entre 36 y 45", "Entre 46 y 55",
"Entre 56 y 65", "De 66 a más"))
 ggplot(errorbars, aes(x=age, y=media, group=1, label = media)) +
    geom_line() +
      geom_errorbar(width=.1, aes(ymin=media-ci, ymax=media+ci)) 

Ahora apliquemos las funciones de ggplot y ggthemes:

# Crear un gráfico mejorado con las funciones de ggplot y ggthemes
g2 <- ggplot(errorbars, aes(x = age, y = media, group = 1, label = media)) +
geom_line() +
geom_errorbar(width = .1, aes(ymin = media - ci, ymax = media + ci)) +
geom_point(shape = 21, size = 3, fill = "white") +
ylim(45, 80) +
labs(x = "Grupo etario",
y = "Índice de participación") +
geom_text(aes(label = round(media, 2)), vjust = -2, hjust = 1.3, color = "black", size = 4) +
scale_color_fivethirtyeight() +
theme_fivethirtyeight()

g2

# Hacer el gráfico interactivo con plotly
gg1 <- ggplotly(g2)
## Warning: plotly.js does not (yet) support horizontal legend items 
## You can track progress here: 
## https://github.com/plotly/plotly.js/issues/53
gg1

¿Podemos darle a esto una mirada comparada y diferenciar la participación según temáticas de interés? Claro! Traigamos la base de datos: #ncol = columnas #nrw= filas

# Cargar la base de datos para la comparación
errorbars2 <- import("parpol_wvs.csv")
# Crear un gráfico comparativo con facetas
g3 <- ggplot(errorbars2, aes(x = year, y = media, group = Group, color = Group, label = media)) +
geom_line() +
geom_errorbar(width = .1, aes(ymin = media - ci, ymax = media + ci)) +
geom_point(shape = 21, size = 3, fill = "white") +
ylim(45, 75) +
labs(x = "Año",
y = "Porcentaje") +
geom_text(aes(label = paste0(round(media, 0), "%")), vjust = 0, hjust = 1.3, color = "black", size = 3) +
facet_wrap(~type, ncol = 3, dir = "v") +
scale_color_fivethirtyeight() +
theme_fivethirtyeight()

g3

# Hacer el gráfico interactivo con plotly
gg2 <- ggplotly(g3)
## Warning: plotly.js does not (yet) support horizontal legend items 
## You can track progress here: 
## https://github.com/plotly/plotly.js/issues/53
gg2 <- gg2 %>% layout(title = list(text = paste0("Porcentaje de participación por tipo<br>",
"<sup>", "World Values Survey", "</sup>"),
y = 0.97, # Ajustar la posición vertical del título
yanchor = "top", # Anclar el título a la parte superior
yref = "container", # Referencia para la posición vertical
pad = list(b = 80))) # Espacio entre el título y el gráfico

gg2

5. Gráficos de densidad

Ahora, qué pasa cuando queremos evaluar la distribución o el comportamiento de una variable continua. Para ello, los gráficos de densidad son bastante útiles. Traigamos una base de datos sobre las últimas EG para ver el comportamiento del voto en segunda vuelta a nivel distrital.

# Cargar la base de datos
dens <- import("EG_2021.csv")

Podemos ver la distribuciones del voto por cada candidato por separado:

# Separar los datos por candidato
pl <- dens[dens$ganador == "PL", ]
fp <- dens[dens$ganador == "FP", ]

Comportamiento del voto en distritos en los cuales ganó Perú Libre. El gráfico más básico:

# Crear un gráfico básico de densidad para los distritos ganados por Perú Libre
g1 <- ggplot(pl, aes(x = VALIDOS_PL, fill = VALIDOS_PL)) +
theme(legend.position = "bottom") +
geom_density(alpha = 0.4, color = "red", fill = "red", linetype = "dashed")

g1

# Hacer el gráfico interactivo con plotly
gg1 <- ggplotly(g1)
gg1

Agregamos algunas cosas:

# Mejorar el gráfico de densidad para los distritos ganados por Perú Libre
g2 <- ggplot(pl, aes(x = VALIDOS_PL, fill = VALIDOS_PL)) +
theme(legend.position = "bottom") +
geom_density(alpha = 0.4, color = "red", fill = "red", linetype = "dashed") +
ggtitle("Distritos ganados por Perú Libre") +
xlab("Votos válidos") +
ylab("Densidad") +
geom_vline(aes(xintercept = mean(VALIDOS_PL)), color = "black", linetype = "dashed", size = 0.5) +
theme_fivethirtyeight()

g2

# Hacer el gráfico interactivo con plotly
gg2 <- ggplotly(g2)
gg2

Hacemos lo mismo para los distritos en los que gana Fuerza Popular:

# Crear un gráfico de densidad para los distritos ganados por Fuerza Popular
g3 <- ggplot(fp, aes(x = VALIDOS_FP, fill = VALIDOS_FP)) +
theme(legend.position = "bottom") +
geom_density(alpha = 0.4, color = "orange", fill = "orange", linetype = "dashed") +
ggtitle("Distritos ganados por Fuerza Popular") +
xlab("Votos válidos") +
ylab("Densidad") +
geom_vline(aes(xintercept = mean(VALIDOS_FP)), color = "black", linetype = "dashed", size = 0.5) +
theme_fivethirtyeight()

g3

# Hacer el gráfico interactivo con plotly
gg3 <- ggplotly(g3)
gg3
# Crear un dataframe con los datos de ambos candidatos
dens_combined <- rbind(
data.frame(candidato = "Perú Libre", votos = pl$VALIDOS_PL),
data.frame(candidato = "Fuerza Popular", votos = fp$VALIDOS_FP)
)

# Crear el gráfico de densidad superpuesto
g4 <- ggplot(dens_combined, aes(x = votos, fill = candidato)) +
geom_density(alpha = 0.4) +
scale_fill_manual(values = c("Perú Libre" = "red", "Fuerza Popular" = "orange")) +
ggtitle("Distribución de votos válidos por candidato") +
xlab("Votos válidos") +
ylab("Densidad") +
theme_fivethirtyeight() +
theme(legend.position = "bottom")

# Hacer el gráfico interactivo con plotly
gg4 <- ggplotly(g4)
## Warning: plotly.js does not (yet) support horizontal legend items 
## You can track progress here: 
## https://github.com/plotly/plotly.js/issues/53
gg4

6. Mapas

Valdría la pena mirar esto a nivel georreferenciado:

#Solucionando el problema de los ubigeos:
dens$CCODI_UBIGEO=stringr::str_pad(dens$CCODI_UBIGEO, 6, side = "left", pad = 0)
dens$UBIGEO = substr(dens$CCODI_UBIGEO,1,2)
dens$UBIGEO = paste0(dens$UBIGEO, "0000")

Agrupamos los datos por departamento:

map = dens %>%
  group_by(DEPA,UBIGEO) %>%
  summarise(PL_DEPA = sum(VOTOS_PL, na.rm = T),
            FP_DEPA = sum(VOTOS_FP, na.rm = T))
## `summarise()` has grouped output by 'DEPA'. You can override using the
## `.groups` argument.

Sacamos el porcentaje del voto por cada partido:

map$total = map$PL_DEPA+map$FP_DEPA
map$FP_FREQ = map$FP_DEPA/map$total
map$PL_FREQ = map$PL_DEPA/map$total
map$VIC = factor(ifelse(map$PL_DEPA>map$FP_DEPA,1,0))
map$VIC = factor(map$VIC, levels = c(0:1), labels = c("FP","PL"))

Abrimos los shapes. Recordamos la primera sesión!

Juntamos la información con la data geolocalizada:

También podemos hacer mapas de calor, tomando como variable continua el porcentaje del total de votos que obtuvo cada partido:

# Hacer el gráfico interactivo con plotly
ggmapa3 <- ggplotly(mapa3)
ggmapa3