Interactividad
en tablas y gráficos
Añadiendo interactividad a documentos Quarto
Introducción
En esta sesión veremos cómo podemos utilizar Quarto para crear documentos interactivos que incorporan tablas y gráficos que permiten la exploración de los datos.
Paso 1 - Tablas
El primer paso en la preparación de cualquier análisis es abrir los datos. En este ejemplo utilizaremos el conjunto de datos world del paquete poliscidata, que contiene información sobre diferentes países y sus niveles de democracia.
Podríamos recurrir a otros paquetes y funciones que abrieran archivos en R para cargar datos. No obstante, para efectos de demostración, resulta más fácil emplear datos disponibles en algún paquete de R. El paquete poliscidata contiene datos sobre los países del mundo y sobre los estados de EE.UU. Se tratan de datos de interés para politólogos, de modo que nos facilitan la vida.
El código abajo carga los datos del paquete poliscidata y los almacena en un data frame llamado w. Luego, utiliza la función reactable del paquete reactable para crear una tabla interactiva que muestra algunas columnas seleccionadas del data frame w. La tabla permite ordenar, redimensionar y buscar en los datos.
Code
# Carga los datos del paquete
# poliscidata con datos de
# ciencia política
# Si no lo tienes instalado,
# pudes hacerlo con:
# install.packages("poliscidata")
library(poliscidata)
w <- world
# Usar la función reactable
# para visualizar los datos
library(reactable)
reactable(w[, c("country", "dem_level4", "regime_type3","pop_total")],
sortable = T,
resizable = T,
searchable = T)Reactable
La clave aquí está en el paquete reactable. Posee una enorme capacidad de configuración y personalización, como la inclusión de mini-gráficos en las columnas, el uso de imágenes, entre otras funcionalidades muy útiles, como la posibilidad de ordenar, filtrar o buscar valores, así como de cambiar el ancho de las columnas.
Miremos la página de Reactable para conocer más sobre cómo podemos crear tablas interactivas de distintos formatos en R y Quarto.
Reactablefmtr
Si reactable ya era muy potente, el paquete reactablefmtr lo lleva a otro nivel. Este paquete extiende las funcionalidades de reactable y permite crear tablas aún más personalizadas e interactivas. Con reactablefmtr, podemos agregar barras de progreso, mini-gráficos y otros elementos visuales a nuestras tablas.
Code
# install.packages("reactablefmtr")
library(reactablefmtr)
dt <- w[1:10, c("country", "dem_level4", "regime_type3","pop_total")]
# Crear una tabla con reactablefmtr
reactable(
dt,
defaultColDef = colDef(
cell = data_bars(dt, text_position = "outside-base")
)
)KableExtra
Otro paquete muy útil para crear tablas en R y Quarto es kableExtra. Este paquete permite crear tablas con un formato atractivo y personalizable. Aunque no es tan interactivo como reactable, kableExtra ofrece muchas opciones para mejorar la apariencia de las tablas.
Code
library(kableExtra)
# Crear una tabla con kableExtra
kable(w[1:10, c("country", "dem_level4", "regime_type3","pop_total")]) |>
kable_classic(full_width = F, html_font = "Cambria")| country | dem_level4 | regime_type3 | pop_total |
|---|---|---|---|
| Afghanistan | Authoritarian | Dictatorship | 29.1 |
| Albania | Hybrid | Parliamentary democ | 3.2 |
| Algeria | Authoritarian | Dictatorship | 35.4 |
| Angola | Authoritarian | Dictatorship | 19.0 |
| Argentina | Part Democ | Presidential democ | 40.7 |
| Armenia | Hybrid | NA | 3.1 |
| Australia | Full Democ | Parliamentary democ | 21.5 |
| Austria | Full Democ | Parliamentary democ | 8.4 |
| Azerbaijan | Authoritarian | Dictatorship | 8.9 |
| Bahrain | Authoritarian | Dictatorship | 0.8 |
Resulta especialmente útil para crear tablas que puedan ser exportadas tanto a pdfs como a html.
GT
Otro paquete interesante para crear tablas en R es gt. Este paquete permite crear tablas con un formato atractivo y personalizable, similar a kableExtra. Además, gt ofrece funcionalidades adicionales para agregar títulos, subtítulos y pies de página a las tablas. Se trata del niño bonito de las tablas, porque se incluye en tidyverse. Ah, tidyverse…
Si queréis podéis mirarlo, pero yo prefiero las dos versiones anteriores.
DT
El paquete DT es otra opción popular para crear tablas interactivas en R. Basado en la biblioteca JavaScript DataTables, DT permite crear tablas con funcionalidades como paginación, búsqueda y ordenamiento. Es una opción sólida para quienes buscan interactividad en sus tablas.
No es tan adaptable como reactable, pero es una buena opción si ya estás familiarizado con DataTables.
Code
library(DT)
# Crear una tabla con DT
datatable(w[, c("country", "dem_level4", "regime_type3","pop_total")],
options = list(pageLength = 5,
autoWidth = TRUE))Stargazer
Para los que trabajan con modelos estadísticos, el paquete stargazer es una herramienta útil para crear tablas de resumen de modelos. Aunque no es interactivo, stargazer facilita la presentación de resultados de modelos en un formato claro y profesional. Básicamente, coge los resultados de los métodos estadísticos y los convierte en una tabla formatada como se debe.
Code
library(stargazer)
# Crear una tabla de resumen de modelos con stargazer
model1 <- lm(pop_total ~ dem_level4 + regime_type3, data = w)
model2 <- lm(pop_total ~ dem_level4, data = w)
stargazer(model1, model2, type = "html",
title = "Resumen de Modelos",
dep.var.labels = "Población Total",
covariate.labels = c("Nivel de Democracia", "Tipo de Régimen"),
out = "model_summary.html")| Dependent variable: | ||
| Población Total | ||
| (1) | (2) | |
| Nivel de Democracia | 30.895 | 10.536 |
| (46.351) | (36.122) | |
| Tipo de Régimen | 8.882 | -11.065 |
| (53.505) | (37.858) | |
| dem_level4Authoritarian | 45.125 | 13.678 |
| (61.225) | (36.010) | |
| regime_type3Parliamentary democ | 31.899 | |
| (48.999) | ||
| regime_type3Presidential democ | 18.086 | |
| (44.121) | ||
| Constant | 7.213 | 36.562 |
| (57.604) | (29.787) | |
| Observations | 133 | 166 |
| R2 | 0.010 | 0.005 |
| Adjusted R2 | -0.029 | -0.014 |
| Residual Std. Error | 163.336 (df = 127) | 145.924 (df = 162) |
| F Statistic | 0.246 (df = 5; 127) | 0.253 (df = 3; 162) |
| Note: | p<0.1; p<0.05; p<0.01 | |
Ejercicios
- Crea una tabla interactiva utilizando el paquete
reactableque muestre las columnascountry,dem_level4,regime_type3ygdp_per_capitadel data framew. Asegúrate de que la tabla sea ordenable, redimensionable y buscable.
Code
# Solución
reactable(w[, c("country", "dem_level4", "regime_type3", "gdp_per_capita")],
sortable = T,
resizable = T,
searchable = T)- Utiliza el paquete
reactablefmtrpara crear una tabla que incluya barras de progreso en la columnagdp_per_capita. ¿Cómo puedes personalizar la apariencia de las barras?
Code
# Solución
library(reactablefmtr)
dt <- w[1:10, c("country", "dem_level4", "regime_type3","gdp_per_capita")]
# Crear una tabla con reactablefmtr
reactable(
dt,
defaultColDef = colDef(
cell = data_bars(dt, text_position = "outside-base")
)
)- Crea una tabla utilizando el paquete
kableExtraque muestre las primeras 10 filas del data framewcon las columnascountry,dem_level4,regime_type3ypop_total. Aplica un estilo clásico a la tabla.
Code
# Solución
library(kableExtra)
kable(w[1:10, c("country", "dem_level4", "regime_type3","pop_total")]) |>
kable_classic(full_width = F, html_font = "Cambria")Paso 2 - Gráficos
Lo más habitual es que los gráficos en R y Quarto sean estáticos. Sin embargo, existen paquetes que permiten crear gráficos interactivos, lo que puede mejorar la experiencia del usuario al explorar los datos. Son varios paquetes los que permiten crear gráficos interactivos en R. A continuación, echemos un vistazo a algunos:
ggiraph: Este paquete extiende las capacidades de ggplot2 para crear gráficos interactivos. Permite agregar interactividad a los elementos del gráfico, como puntos, líneas y barras, mediante la función
girafe(). Los gráficos creados con ggiraph pueden incluir tooltips, enlaces y otras funcionalidades interactivas. Documentación aquí.plotly: Plotly es una biblioteca de gráficos interactivos que se integra bien con R. Permite crear gráficos interactivos a partir de ggplot2 utilizando la función
ggplotly(). Los gráficos de Plotly son altamente personalizables y pueden incluir zoom, desplazamiento y otras interacciones. Documentación aquí.networkD3: Este paquete se utiliza para crear gráficos de redes interactivas. Permite visualizar relaciones entre nodos y enlaces de manera interactiva, lo que es útil para analizar datos de redes sociales, biológicas y otras estructuras de red. Documentación aquí.
highcharter: Highcharter es un paquete que proporciona una interfaz para la biblioteca de gráficos Highcharts. Permite crear gráficos interactivos con una amplia variedad de tipos de gráficos, como líneas, barras, áreas y más. Los gráficos de Highcharter son altamente personalizables y pueden incluir animaciones y otras interacciones. Documentación aquí.
leaflet: Este paquete se utiliza para crear mapas interactivos en R. Permite agregar capas de datos, marcadores y otras funcionalidades interactivas a los mapas, lo que es útil para visualizar datos geoespaciales. Documentación aquí.
r2d3: Este paquete permite integrar visualizaciones D3.js en R. D3.js es una biblioteca de JavaScript para crear gráficos interactivos y visualizaciones de datos. El paquete r2d3 facilita la creación de gráficos D3.js utilizando datos de R. Documentación aquí.
tenet: El paquete
tenetincluye funciones específicas para crear gráficos interactivos en el contexto del análisis de texto. Permite visualizar resultados de análisis de texto de manera interactiva, facilitando la exploración y comprensión de los datos textuales. Documentación aquí. Aplicaciones a textos literarios aquí.
GGiraph
En este ejemplo, utilizaremos el paquete ggiraph para crear un gráfico interactivo que muestre la relación entre el nivel de democracia y el porcentaje de población mayor de 65 años en diferentes países. Agregaremos tooltips para proporcionar información adicional sobre cada país cuando el usuario pase el cursor sobre los puntos del gráfico.
Primero empezamos preparando los datos:
Code
wm <- w
wm$regionun <- as.character(wm$regionun)
wm$regionun[wm$regionun=="Australia/New Zealand/Oceania"] <- "Oceania"
wm$regionun[wm$regionun%in%c("Latin America/Caribbean","USA/Canada") ] <- "America"
wa <- wm[! is.na(wm$dem_level4),]
wa$religoin[wa$name=="United States"] <- "Other Christian"
wa <- wa[!is.na(wa$religoin),]
wa$frac_eth <- round(wa$frac_eth, 3)
wa$tooltip_scat <- paste0("<b>", wa$name, "</b><br>Democratic Score: ", wa$dem_score14, "<br>HDI: ", wa$hdi, "<br>Religion: ", wa$religoin)
wa$tooltip_scat2 <- paste0("<b>", wa$name, "</b><br>Democratic Score: ", wa$dem_score14, "<br>Gender Inequality Index: ", wa$gender_unequal, "<br>Region: ", wa$regionun)
wa$name <- wa$country
wa$name <- gsub("'","", wa$name, fixed = T)
dd <- data.frame(wa[,c("dem_score14","gender_unequal","frac_eth","gini10","pop_65_older","hdi", "lifeex_total")])
dd$geometry <- NULL
# Calculate corNULL
# # Calculate correlation matrix
co <- cor(dd, use="pairwise.complete.obs")
# Reshape for ggplot2
mt <- reshape2::melt(co)
colnames(mt) <- c("Var1", "Var2", "value")luego, creamos el gráfico normal (sin interactividad):
Code
library(ggplot2)
library(ggiraph)
p1 <- ggplot(wa, aes(x = dem_level4, y = pop_65_older, group=dem_level4, fill=dem_level4)) +
geom_violin() +
geom_point_interactive(aes(tooltip = paste0("<b>", name, "</b><br>Score: ", dem_score14, "<br>Pop. 65+ (%): ", pop_65_older), data_id = name)) +
theme_minimal() +
labs(title = "Democratic Level and Pop. 65 or Older",
x = "Democracy Level",
y = "Population Aged 65 or Older (%)") +
theme(legend.position = "none", plot.title=ggtext::element_markdown(size=16, face = "bold"))+
scale_fill_brewer(palette="Dark2", direction = 1)
p1
finalmente, añadimos la interactividad con ggiraph:
Code
girafe(ggobj = p1,
options = list(
opts_hover(css = "fill:yellow;r:5pt;"),
opts_tooltip(css = "background-color:lightblue; color:black; font-size:16px; padding:5px; border-radius:5px;")
)
)Ejercicios
- Crea un gráfico interactivo utilizando
ggiraphque muestre la relación entre el índice de desarrollo humano (HDI) y el puntaje democrático (dem_score14) para diferentes países. Utiliza colores para diferenciar las religiones principales (religoin) y agrega tooltips que muestren el nombre del país, el puntaje democrático y el HDI.
Code
# Solución
# Crea el tootltip
wa$tooltip_scat <- paste0("<b>", wa$name, "</b><br>Democratic Score: ", wa$dem_score14, "<br>HDI: ", wa$hdi)
# Crea el gráfico interactivo
p2 <- ggplot(wa,
aes(x = hdi, y = dem_score14, color = religoin, group=religoin)) +
geom_point_interactive(aes(tooltip = tooltip_scat, data_id = name)) +
theme_minimal() +
theme(panel.grid.major = element_blank(),
legend.position = "bottom",
plot.title=ggtext::element_markdown(size=16, face = "bold")) +
labs(y="Democratic Score", x="Human Development Indicator", title="Democracy and Human Development")+
scale_color_brewer(palette="Dark2", direction = 1, name="Religion")
# Añade la interactividad
girafe(ggobj = p2,
options = list(
opts_hover(css = "fill:orange;r:5pt;"),
opts_tooltip(css = "background-color:lightgreen; color:black; font-size:16px; padding:5px; border-radius:5px;")
)- Genera un scatter plot interactivo utilizando
ggiraphque muestre la relación entre el puntaje democrático (dem_score14) y el índice de desigualdad de género (gender_unequal). Utiliza colores para diferenciar las regiones (regionun) y agrega tooltips que muestren el nombre del país, el puntaje democrático y el índice de desigualdad de género.
Code
# Solución
# colores
col <- c("#3d98d3","#EC0B88","#5e35b1","#f9791e","#3dd378","#c6c6c6")
# Crea el tootltip
wa$tooltip_scat <- paste0("<b>", wa$name, "</b><br>Democratic Score: ", wa$dem_score14, "<br>Gender Ineq.: ", wa$gender_unequal)
p3 <- ggplot(wa,
aes(x = gender_unequal, y = dem_score14, color = regionun, group=regionun)) +
geom_point_interactive(aes(tooltip = tooltip_scat, data_id = name)) +
theme_minimal() +
theme(panel.grid.major = element_blank(),
legend.position = "bottom",
plot.title=ggtext::element_markdown(size=16, face = "bold")) +
labs(y="Democratic Score", x="Gender Inequality Index", title="Democracy and Gender Inequality")+
scale_color_manual(values=pal$cat.awtools.ppalette.8[2:7], name="Region")
# Añade la interactividad
girafe(ggobj = p3,
options = list(
opts_hover(css = "fill:orange;r:5pt;"),
opts_tooltip(css = "background-color:lightgreen; color:black; font-size:16px; padding:5px; border-radius:5px;")
))Conectando todo
Hemos visto cómo crear tablas y gráficos interactivos por separado. Ahora, veamos cómo podemos combinar ambos elementos en un documento Quarto para crear una experiencia de usuario más completa.
Aquí entra el paquete patchwork, que permite combinar múltiples gráficos de ggplot2 en una sola figura. Podemos utilizar patchwork junto con ggiraph para crear un documento que incluya tanto tablas como gráficos interactivos.
Antes de seguir, echemos un vistazo al paquete patchwork. La documentación está disponible aquí.
Code
# Crea el tootltip
wa$tooltip_scat <- paste0("<b>", wa$name, "</b><br>Democratic Score: ", wa$dem_score14, "<br>HDI: ", wa$hdi)
# Crea el gráfico interactivo
p2 <- ggplot(wa,
aes(x = hdi, y = dem_score14, color = religoin, group=religoin)) +
geom_point_interactive(aes(tooltip = tooltip_scat, data_id = name)) +
theme_minimal() +
theme(panel.grid.major = element_blank(),
legend.position = "bottom",
plot.title=ggtext::element_markdown(size=16, face = "bold")) +
labs(y="Democratic Score", x="Human Development Indicator", title="Democracy and Human Development")+
scale_color_brewer(palette="Dark2", direction = 1, name="Religion")
# colores
col <- c("#3d98d3","#EC0B88","#5e35b1","#f9791e","#3dd378","#c6c6c6")
# Crea el tootltip
wa$tooltip_scat <- paste0("<b>", wa$name, "</b><br>Democratic Score: ", wa$dem_score14, "<br>Gender Ineq.: ", wa$gender_unequal)
p3 <- ggplot(wa,
aes(x = gender_unequal, y = dem_score14, color = regionun, group=regionun)) +
geom_point_interactive(aes(tooltip = tooltip_scat, data_id = name)) +
theme_minimal() +
theme(panel.grid.major = element_blank(),
legend.position = "bottom",
plot.title=ggtext::element_markdown(size=16, face = "bold")) +
labs(y="Democratic Score", x="Gender Inequality Index", title="Democracy and Gender Inequality")+
scale_color_manual(values=pal$cat.awtools.ppalette.8[2:7], name="Region")
library(patchwork)
# Añade la interactividad
girafe(ggobj = (p1+p2)/p3, height_svg = 10, width_svg = 10,
options = list(
opts_hover(css = "fill:orange;r:5pt;"),
opts_tooltip(css = "background-color:lightgreen; color:black; font-size:16px; padding:5px; border-radius:5px;")
))Un plus: Leaflet
Finalmente, veamos cómo podemos utilizar el paquete leaflet para crear mapas interactivos en R y Quarto. En este ejemplo, crearemos un mapa simple que muestre la ubicación de un punto específico con un marcador y un popup.
Code
# install.packages("leaflet")
library(leaflet)
leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lat=40.9695, lng=-5.6767, popup="Nosotros estamos aquí")Opciones de los bloques de código
eval: Esta opción controla si el código dentro del bloque se evalúa o no. Si se establece en
FALSE, el código no se ejecutará, pero aún así se mostrará en el documento. Esto es útil para mostrar ejemplos de código sin ejecutarlos.echo: Esta opción determina si el código dentro del bloque se muestra en el documento final. Si se establece en
FALSE, el código no se mostrará, pero los resultados de su ejecución sí lo harán. Esto es útil cuando deseas mostrar solo los resultados sin revelar el código subyacente.message: Esta opción controla si los mensajes generados durante la ejecución del código se muestran en el documento final. Si se establece en
FALSE, los mensajes no se mostrarán. Esto es útil para evitar que mensajes innecesarios o de advertencia aparezcan en el documento.warning: Similar a
message, esta opción controla si las advertencias generadas durante la ejecución del código se muestran en el documento final. Si se establece enFALSE, las advertencias no se mostrarán. Esto es útil para mantener el documento limpio y libre de advertencias que no son relevantes para el lector.results: Esta opción determina cómo se muestran los resultados de la ejecución del código. Puede tomar valores como
asis,hold,markup, entre otros. Por ejemplo, si se establece enasis, los resultados se mostrarán tal como son generados por el código, sin ningún formato adicional. Esto es útil para mostrar resultados en formatos específicos, como tablas HTML o gráficos.
Opciones como fig.width y fig.height también son comunes para controlar el tamaño de las figuras generadas por el código. Estas opciones permiten personalizar la apariencia de los gráficos y otros elementos visuales en el documento final.
Opciones de Quarto:
- code-fold: Esta opción permite controlar si el bloque de código está plegado (oculto) o desplegado (visible) por defecto en el documento final. Si se establece en
true, el bloque de código estará plegado, lo que significa que solo se mostrará un botón para expandirlo. Esto es útil para mantener el documento limpio y permitir a los lectores expandir solo los bloques de código que les interesan.
Opciones de layout:
column: Esta opción permite especificar cómo se distribuye el contenido del bloque de código en diferentes columnas dentro del documento. Por ejemplo, si se establece en
screen, el bloque de código ocupará todo el ancho disponible en la pantalla. Si se establece enpage, el bloque de código se ajustará al ancho de la página impresa. Esta opción es útil para controlar la presentación del contenido en documentos con múltiples columnas o diseños específicos. Ver el artículo sobre Article Layout para saber las opciones completas.figuras de márgenes: Quarto permite ajustar los márgenes de las figuras generadas por bloques de código. Esto se puede hacer utilizando opciones como
fig.margin, que permite especificar los márgenes alrededor de una figura. Por ejemplo, se puede establecerfig.margin: 10pxpara agregar un margen de 10 píxeles alrededor de la figura. Esta opción es útil para mejorar la apariencia visual de las figuras y asegurarse de que no estén demasiado cerca del texto u otros elementos en el documento. También resulta válido para tablas.notas en los márgenes: Quarto permite agregar notas en los márgenes de las páginas, así como las referencias bibliográficas. Eso permite un estilo de escritura más personalizado.
citas: Quarto soporta citas bibliográficas utilizando el formato CSL (Citation Style Language). Puedes agregar citas en el texto utilizando el formato
[@clave], dondeclavees la clave de la referencia en tu archivo bibliográfico (por ejemplo, un archivo.bib). Quarto generará automáticamente la lista de referencias al final del documento según el estilo especificado en el archivo CSL. Esto facilita la gestión de referencias y asegura que las citas estén correctamente formateadas según las normas académicas o de publicación. Ver más en Citations in Quarto.