Cuando trabajamos con datos en R, una de las tareas más comunes es la visualización y presentación de los resultados en formato de tabla. R ofrece varios paquetes que permiten crear y personalizar tablas de diferentes formas y estilos, cada uno con características que se adaptan a necesidades específicas.
En esta sección, exploraremos algunos de los paquetes más utilizados para formatear y presentar tablas en R, como gt, reactable y flextable. Cada uno de estos paquetes tiene sus ventajas, y su elección depende de los requisitos del análisis o la presentación:
gt: Es un paquete diseñado para crear tablas estéticamente atractivas y fáciles de leer. Permite agregar formatos como colores, alineación de texto, bordes y más, lo que facilita la presentación de resultados en informes o documentos.
flextable: Es otro paquete que se destaca por su capacidad para personalizar tablas, permitiendo aplicar estilos detallados a celdas, columnas, filas y texto. Es especialmente útil cuando se necesita un control preciso sobre el diseño de las tablas en documentos interactivos o exportados.
reactable: Este paquete es perfecto para crear tablas interactivas y dinámicas. Permite la búsqueda, ordenamiento y filtrado, pero también ofrece una mayor flexibilidad para personalizar el diseño, la apariencia y la interacción con las tablas. reactable se utiliza especialmente en aplicaciones web y dashboards.
Vamos a explorar ejemplos prácticos que muestran cómo personalizar tablas utilizando las distintas funciones del paquete. Es importante identificar las secciones clave del código que nos permiten editar elementos específicos de la tabla, como la apariencia del encabezado, el estilo de las filas de datos y los detalles visuales generales. Esto nos permitirá crear tablas bien diseñadas y adaptadas a nuestras necesidades.
Cada ejemplo presenta la sintaxis los distintos paquetes que se pueden utilizar.
1.1Tablas con gt()
1.1.1 Tabla gt 1
library(gt)# Armar tabla con gtdatos_con_totales %>%gt(rowname_col ="Localidad") %>%# Especificamos que la columna 'Localidad' será la primera columna de la tabla# Títulos y subtítulostab_header(title =md("**Casos Epidemiológicos**"), # Título en negritasubtitle =md("Casos *confirmados* de dengue y chikungunya según zona y población, provincia, año 2024") # Subtítulo en cursiva ) %>%# Personalizar nombres de las columnascols_label(Localidad =md("Zona"), # Renombrar columna 'Localidad' a 'Zona'Casos_Dengue =md("Casos <br>Dengue"), # Renombrar con salto de línea en el nombreCasos_Chikungunya =md("Casos <br>Chikungunya"), # Lo mismo para la columna 'Casos_Chikungunya'Tasa_Dengue =md("Tasa <br>Dengue"),Tasa_Chikungunya =md("Tasa <br>Chikungunya") ) %>%# Alineación de las cabeceras de las columnasopt_align_table_header(align ="left") %>%# Definir el ancho de las columnas en píxelescols_width( Localidad ~px(200), Casos_Dengue ~px(150), Casos_Chikungunya ~px(150), Tasa_Dengue ~px(200), Tasa_Chikungunya ~px(200) ) %>%# Nota al pie de la tablatab_source_note(source_note =md("Fuente de datos: Sistema de Información Sanitaria de la Provincia.") ) %>%# Agregar una nota al pie para las columnas de tasastab_footnote(footnote ="Tasas calculadas por cada 100,000 habitantes",locations =cells_column_labels(columns =c(Tasa_Dengue, Tasa_Chikungunya)) # Aplica solo a las cabeceras de columnas de tasas ) %>%# Aplicar colores a las celdas de los casos, utilizando una paleta de coloresdata_color(columns =c(Casos_Dengue, Casos_Chikungunya), # Seleccionamos las columnas a colorearcolors = scales::col_numeric( # Usamos col_numeric para aplicar una paletapalette =c("#f7fcf5", "#bd0026"), # Color desde un amarillo claro hasta un rojodomain =c(0, 200) # Establecemos el rango de valores de la paleta ),rows =1:(nrow(datos_con_totales) -1) # Excluimos la última fila (Total) de la coloración ) %>%# Establecer la fuente a Helvetica y evitar la negrita en todo el textoopt_table_font(font ="Helvetica", weight ="normal" ) %>%# Alineación de las cabeceras de las columnas: columnas 1, 2, 3 alineadas a la izquierdatab_style(style =cell_text(align ="left"), locations =cells_column_labels(columns =c(1, 2, 3, 4, 5, 6)) # Localidad, Casos_Dengue, Casos_Chikungunya ) %>%# Aplicar negrita a la última fila (Total)tab_style(style =cell_text(weight ="bold"), # Aplicar negritalocations =cells_body(rows =nrow(datos_con_totales), # Seleccionamos la última fila (Total)columns =everything() # Aplicamos a todas las columnas de la fila ) ) %>%# Aplicar color de fondo gris claro a la última fila (Total)tab_style(style =cell_fill(color ="#f2f2f2"), # Color de fondo gris claro para la fila de totaleslocations =cells_body(rows =nrow(datos_con_totales), # Seleccionamos la última fila (Total)columns =everything() # Aplicamos a todas las columnas ) )
Casos Epidemiológicos
Casos confirmados de dengue y chikungunya según zona y población, provincia, año 2024
Casos Dengue
Poblacion
Casos Chikungunya
Tasa Dengue
1
Tasa Chikungunya
1
Zona Oeste
120
50000
30
240.0
60.0
Zona Este
45
35000
12
128.6
34.3
Zona Norte
80
40000
25
200.0
62.5
Zona Sur
60
45000
18
133.3
40.0
Total
305
170000
85
179.4
50.0
Fuente de datos: Sistema de Información Sanitaria de la Provincia.
1 Tasas calculadas por cada 100,000 habitantes
1.1.2 Tabla gt 2
# Crear una tabla 'gt' con los datosgt_tabla <-gt(datos_con_totales) %>%# Agregar un título y un subtítulo a la tablatab_header(title =md("**Casos Epidemiológicos**"), # Título en negrita usando Markdownsubtitle =md("Casos *confirmados* de dengue y chikungunya según zona y población, provincia, año 2024") # Subtítulo con formato Markdown ) %>%# Etiquetas de las columnas para mejorar la legibilidadcols_label(Localidad =md("Zona"), # Cambiar la etiqueta de la columna 'Localidad' a 'Zona' con formato MarkdownCasos_Dengue =md("Casos <br>Dengue"),Casos_Chikungunya =md("Casos <br>Chikungunya"),Tasa_Dengue =md("Tasa <br>Dengue"),Tasa_Chikungunya =md("Tasa <br>Chikungunya") ) %>%# Personalizar opciones generales de la tablatab_options(data_row.padding =px(6), # Define el relleno (padding) de las filas de datos en 6 píxelesheading.align ="left", # Alinear los encabezados (títulos) de la tabla a la izquierdacolumn_labels.background.color ="dodgerblue", # Color de fondo azul (dodgerblue) para las etiquetas de las columnasheading.title.font.size =px(26), # Tamaño de la fuente del título en 26 píxelesheading.subtitle.font.size =px(14), # Tamaño de la fuente del subtítulo en 14 píxelestable_body.hlines.width =px(1) # Establecer el grosor de las líneas horizontales en el cuerpo de la tabla a 1 píxel ) %>%# Alinear columnas específicas a la izquierdacols_align(align ="left", columns =c(1, 2)) %>%# Alinear otras columnas específicas al centrocols_align(align ="center", columns =c(3, 4, 5)) %>%# Aplicar estilo al título de la tablatab_style(style =cell_text(color ="dodgerblue", # Color del texto del título en azul (dodgerblue)weight ="bold", # Establecer el texto del título en negritafont ="helvetica"# Usar la fuente 'Helvetica' ),location =cells_title(groups ="title") # Aplicar este estilo al grupo de títulos de la tabla ) %>%# Aplicar color de fondo gris claro a las filas impares de la tablatab_style(style =cell_fill(color ="grey90"), # Color de fondo gris claro (grey90)locations =cells_body(rows =seq(1, nrow(datos_con_totales), 2)) # Aplica este estilo solo a las filas impares usando la secuencia de 1 a 'n_rows' ) # Mostrar la tabla con los estilos aplicadosgt_tabla
Casos Epidemiológicos
Casos confirmados de dengue y chikungunya según zona y población, provincia, año 2024
library(flextable)library(dplyr)# Definir el estilo de borde para las líneas verticalesborder_style <- officer::fp_border(color ="black", width =1)# Crear la flextable con el formato solicitadoflextable(datos_ordenados) %>%# Añadir una fila adicional de encabezadoadd_header_row(top =TRUE, values =c("Localidad", "Dengue", "", "Chikungunya", "") ) %>%# Renombrar las columnas para mejorar la legibilidad en la tablaset_header_labels(Localidad ="", Casos_Dengue ="Caso", Tasa_Dengue ="Tasa", Casos_Chikungunya ="Casos", Tasa_Chikungunya ="Tasas" ) %>%# Fusionar celdas en las secciones de encabezado para agrupar columnasmerge_at(i =1, j =2:3, part ="header") %>%merge_at(i =1, j =4:5, part ="header") %>%# Configurar estilos generales para el encabezado y contenidoborder_remove() %>%# Eliminar bordes predeterminadostheme_booktabs() %>%# Aplicar un estilo de tabla "booktabs"# Añadir líneas verticales para separar seccionesvline(part ="all", j =1, border = border_style) %>%vline(part ="all", j =3, border = border_style) %>%# Alinear columnas flextable::align(align ="left", j =1, part ="all") %>% flextable::align(align ="center", j =2:5, part ="all") %>%# Ajustar el ancho de las columnaswidth(j =1, width =2.7) %>%width(j =2, width =1.5) %>%width(j =c(4, 5), width =1.5) %>%# Estilizar las filas del cuerpobg(., part ="body", bg ="gray95") %>%bg(., j =c(1:5), i =~ Localidad =="Zona Sur", part ="body", bg ="#91c293") %>%bg(j =5, i =~ Tasa_Chikungunya >=55, part ="body", bg ="#f14d4d") %>%# Aplicar negrita en encabezados y filas específicasbold(i =1, bold =TRUE, part ="header") %>%bold(i =5, bold =TRUE, part ="body") %>%# Redondear números con formato adicional para columnas específicascolformat_num(j =c("Tasa_Dengue", "Tasa_Chikungunya"), digits =1)
Localidad
Dengue
Chikungunya
Caso
Tasa
Casos
Tasas
Zona Oeste
120
240.0
30
60.0
Zona Este
45
128.6
12
34.3
Zona Norte
80
200.0
25
62.5
Zona Sur
60
133.3
18
40.0
Total
305
179.4
85
50.0
1.3Tablas reactable()
1.3.1 Tabla 1 reactable()
library(reactable)# Función para colorear el valor máximocolor_max <-function(value, max_value) {if (value == max_value) {return("#f14d4d") # Rojo para el valor máximo } else {return(NA) # Sin color para otros valores }}# Calcular los valores máximosmax_tasa_dengue <-max(datos_ordenados$Tasa_Dengue)max_tasa_chikungunya <-max(datos_ordenados$Tasa_Chikungunya)# Crear tabla con reactablereactable( datos_ordenados,columns =list(Localidad =colDef(name ="Localidad", align ="left"),Casos_Dengue =colDef(name ="Caso", align ="center"),Tasa_Dengue =colDef(name ="Tasa",align ="center",style =function(value) {list(background =color_max(value, max_tasa_dengue), fontWeight ="bold") } ),Casos_Chikungunya =colDef(name ="Casos", align ="center"),Tasa_Chikungunya =colDef(name ="Tasas",align ="center",style =function(value) {list(background =color_max(value, max_tasa_chikungunya), fontWeight ="bold") } ) ),columnGroups =list(colGroup(name ="Dengue", columns =c("Casos_Dengue", "Tasa_Dengue")),colGroup(name ="Chikungunya", columns =c("Casos_Chikungunya", "Tasa_Chikungunya")) ),bordered =TRUE,striped =TRUE,highlight =TRUE,defaultColDef =colDef(align ="center" ),theme =reactableTheme(borderColor ="#cccccc", # Color de los bordesstripedColor ="#f9f9f9", # Color de filas alternadashighlightColor ="#e5f2ff", # Color al pasar el cursorheaderStyle =list(background ="#f7f7f7", # Fondo del encabezadofontWeight ="bold"# Negrita en el encabezado ) ))
1.3.2 Tabla 2 reactable()
# Función para colorear el valor máximocolor_max <-function(value, max_value) {# Si el valor es igual al valor máximo, asignar color rojo al fondoif (value == max_value) {return("#f14d4d") # Fondo rojo para el valor máximo } else {return(NA) # Sin color para otros valores }}# Calcular los valores máximos de las tasasmax_tasa_dengue <-max(datos_ordenados$Tasa_Dengue) # Valor máximo de Tasa_Denguemax_tasa_chikungunya <-max(datos_ordenados$Tasa_Chikungunya) # Valor máximo de Tasa_Chikungunya# Crear tabla con reactablereactable( datos_ordenados,# Opciones interactivasfilterable =TRUE, # Habilitar cuadros de filtro en las columnaspagination =TRUE, # Habilitar paginación para mostrar un número limitado de filasdefaultPageSize =5, # Mostrar 5 filas por páginahighlight =TRUE, # Resaltar filas al pasar el cursorgroupBy ="Localidad", # Agrupar las filas según la columna 'Localidad'# Personalización de columnascolumns =list(Localidad =colDef(name ="Localidad", # Nombre visible de la columnaalign ="left"# Alinear contenido a la izquierda ),Casos_Dengue =colDef(name ="Caso", # Renombrar la columna 'Casos_Dengue' como 'Caso'align ="center"# Alinear contenido al centro ),Tasa_Dengue =colDef(name ="Tasa Dengue", # Renombrar la columna 'Tasa_Dengue'align ="center", # Alinear contenido al centrostyle =function(value) { # Aplicar estilo condicional a las celdaslist(background =color_max(value, max_tasa_dengue), # Fondo rojo para el valor máximofontWeight ="bold"# Texto en negrita ) } ),Casos_Chikungunya =colDef(name ="Casos", # Renombrar la columna 'Casos_Chikungunya' como 'Casos'align ="center"# Alinear contenido al centro ),Tasa_Chikungunya =colDef(name ="Tasa Chikungunya", # Renombrar la columna 'Tasa_Chikungunya'align ="center", # Alinear contenido al centrostyle =function(value) { # Aplicar estilo condicional a las celdasif (value >50) { # Si el valor es mayor a 50:list(color ="red", # Texto en rojofontWeight ="bold"# Texto en negrita ) } } ) ),# Agrupación de columnas en el encabezadocolumnGroups =list(colGroup(name ="Dengue", # Grupo llamado 'Dengue'columns =c("Casos_Dengue", "Tasa_Dengue") # Columnas del grupo ),colGroup(name ="Chikungunya", # Grupo llamado 'Chikungunya'columns =c("Casos_Chikungunya", "Tasa_Chikungunya") # Columnas del grupo ) ),# Estilo personalizado de la tablatheme =reactableTheme(borderColor ="#cccccc", # Color de los bordesstripedColor ="#f9f9f9", # Color de las filas alternadashighlightColor ="#e0f7fa", # Color de las filas resaltadas al pasar el cursorheaderStyle =list(background ="#f0f0f0", # Fondo del encabezadofontWeight ="bold"# Texto en negrita en el encabezado ) ))
1.4Automatización de formatos()
Las funciones en R permiten encapsular estilos, configuraciones y opciones visuales dentro de una estructura reutilizable, lo que facilita la consistencia en el diseño y ahorra tiempo al aplicar los mismos formatos en diferentes tablas o conjuntos de datos.
Por ejemplo, en paquetes como reactable o gt, es posible definir funciones que apliquen colores, bordes, alineaciones, tamaños de texto y otras características estéticas a las tablas con solo una línea de código.
1.4.1 Función 1 reactable()
# Definir la función `mi_tema` para automatizar el formatomi_tema <-function(data) {reactable( data,bordered =TRUE, # Agregar bordes a la tablastriped =TRUE, # Filas alternadas con colorhighlight =TRUE, # Resaltar filas al pasar el cursordefaultPageSize =5, # Mostrar 5 filas por páginadefaultColDef =colDef(align ="center"# Alinear columnas al centro ),theme =reactableTheme(stripedColor ="#f7f7f7", # Color de filas alternadashighlightColor ="#e0f7fa", # Color al pasar el cursorborderColor ="#cccccc", # Color de los bordesheaderStyle =list(background ="#f0f0f0", # Fondo gris claro para encabezadosfontWeight ="bold"# Texto en negrita en el encabezado ) ) )}
1.4.1.1 Ejemplo Función 1 reactable()
# Datos de ejemplodatos <-data.frame(Localidad =c("Zona Oeste", "Zona Este", "Zona Norte", "Zona Sur"),Casos =c(120, 45, 80, 60),Tasa =c(240.0, 128.6, 200.0, 133.3))# Usar la función `mi_tema` para aplicar el formatomi_tema(datos)
1.4.2 Función 1 gt()
# Cargar la librería gtlibrary(gt)# Definir una función simplificada llamada 'funcion2'funcion2 <-function(gt_tbl) { gt_tbl %>%# Opciones generales para la tablatab_options(column_labels.background.color ="lightblue", # Fondo azul claro para las etiquetas de columnastable.border.top.color ="gray", # Borde superior de la tabla en gristable.border.bottom.color ="gray", # Borde inferior de la tabla en grisdata_row.padding =px(5) # Relleno de las filas de datos en 5 píxeles ) %>%# Estilo del encabezado de la tablatab_style(style =cell_text(weight ="bold"# Texto del encabezado en negrita ),location =cells_column_labels() # Aplicar a los encabezados de columna )}
1.4.2.1 Ejemplo Fución 1 gt()
datos <-data.frame(Localidad =c("Zona Oeste", "Zona Este", "Zona Norte", "Zona Sur"),Casos =c(120, 45, 80, 60),Tasa =c(240.0, 128.6, 200.0, 133.3))# Generar la tabla gt y aplicar 'funcion2'tabla <-gt(datos)funcion2(tabla)