Pido a Claude que genere un fichero de Quarto que muestre un ejemplo tutorial para el uso de gt en tablas con varias columnas y un interés en hacerlas más compactas. El prompt:
Quiero que me generes un fichero de quarto con un tutorial de uso de gt para mostrar una tabla relativamente ancha.
Para eso, en diferentes pasos, introduce el cambio a fuente "Arial Narrow", cambiar el tipo de letra, poner una columna como categoría par que aparezca como fila independiente y otras ideas que se te ocurran para mejorar la presentación de la tabla.
También añade la opción de darle un efecto pijama o cebra, sobreando filas pares /impares y para un intervalo determinado
El fichero Quarto generado tenía unos pocos bugs, que han sido fáciles de corregir. El resultado del html generado se muestra a continuación (si se prefiere se puede ver a pantalla completa en este enlace):
EL código Quarto generado y depurado:
---
title: "Tutorial: Optimización de Tablas Anchas con gt"
subtitle: "Técnicas avanzadas para mejorar la presentación de datos tabulares"
author: "Antonio de Lucas Sepúlveda / Claude.ai"
date: 2025-10-18
format:
html:
toc: true
toc-depth: 3
code-fold: false
code-tools: true
theme: cosmo
execute:
warning: false
message: false
lang: es
editor_options:
chunk_output_type: console
---
## Introducción
El paquete `gt` es una herramienta potente para crear tablas de alta calidad en R. Este tutorial se centra en técnicas específicas para optimizar la presentación de tablas anchas, un desafío común en el análisis de datos hidrológicos y ambientales.
```{r setup}
#| label: configuracion-inicial
# Cargar librerías necesarias
library(tidyverse)
library(gt)
library(paletteer) # Para paletas de colores adicionales
# Configuración global
options(scipen = 999) # Evitar notación científica
```
## Datos de ejemplo: Serie temporal hidrológica
Vamos a crear un conjunto de datos que simula mediciones hidrológicas mensuales en diferentes estaciones de aforo.
```{r datos}
#| label: crear-datos
# Simular datos de caudales mensuales en m³/s
set.seed(2024)
# Crear datos de ejemplo - Serie temporal hidrológica
datos_hidrologicos <- tibble(
estacion = rep(c("EA001_Río_Tajo", "EA002_Río_Duero", "EA003_Río_Ebro",
"EA004_Río_Guadalquivir", "EA005_Río_Guadiana"), each = 12),
mes = rep(month.name, 5),
caudal_medio = runif(60, 10, 500) |> round(2),
caudal_max = caudal_medio * runif(60, 1.2, 2.5) |> round(2),
caudal_min = caudal_medio * runif(60, 0.3, 0.8) |> round(2),
precipitacion = runif(60, 0, 150) |> round(1),
temperatura = runif(60, 5, 35) |> round(1),
evaporacion = runif(60, 20, 180) |> round(1),
nivel_embalse = runif(60, 30, 95) |> round(1),
calidad_agua = sample(c("Excelente", "Buena", "Aceptable", "Deficiente"), 60,
replace = TRUE, prob = c(0.3, 0.4, 0.2, 0.1))
) |>
mutate(
mes = factor(mes, levels = month.name),
cuenca = str_extract(estacion, "Río_.*") |> str_remove("Río_")
)
# Transformar a formato ancho para demostrar el problema
datos_anchos <- datos_hidrologicos |>
select(cuenca, mes, caudal_medio, precipitacion, temperatura) |>
pivot_wider(
names_from = mes,
values_from = c(caudal_medio, precipitacion, temperatura),
names_glue = "{mes}_{.value}"
)
glimpse(datos_anchos)
```
## Paso 1: Tabla básica con gt
Comenzamos creando una tabla básica para ver el punto de partida.
```{r tabla-basica}
#| label: tabla-basica
# Tabla básica sin formato
tabla_basica <- datos_anchos |>
gt() |>
tab_header(
title = "Datos Hidrológicos Mensuales por Cuenca",
subtitle = "Caudal medio (m³/s), Precipitación (mm) y Temperatura (°C)"
)
tabla_basica
```
## Paso 2: Cambiar a fuente Arial Narrow
La fuente Arial Narrow es ideal para tablas anchas porque permite mostrar más información en menos espacio horizontal.
```{r fuente-narrow}
#| label: cambiar-fuente
tabla_fuente <- datos_anchos |>
gt() |>
tab_header(
title = "Datos Hidrológicos Mensuales por Cuenca",
subtitle = "Caudal medio (m³/s), Precipitación (mm) y Temperatura (°C)"
) |>
# Aplicar Arial Narrow a toda la tabla
tab_options(
table.font.names = c("Arial Narrow", "Arial", "sans-serif"),
table.font.size = px(12),
heading.title.font.size = px(16),
heading.subtitle.font.size = px(14),
column_labels.font.size = px(11)
) |>
# Ajustar ancho de columnas
cols_width(
cuenca ~ px(100),
everything() ~ px(65)
)
tabla_fuente
```
## Paso 3: Organizar columnas por categorías
Vamos a agrupar las columnas por tipo de variable para mejorar la legibilidad.
```{r agrupar-columnas}
#| label: agrupar-columnas
# Reorganizar datos para mejor agrupación
datos_categorias <- datos_hidrologicos |>
select(cuenca, mes, caudal_medio, precipitacion, temperatura) |>
mutate(mes = as.character(mes))
tabla_categorias <- datos_categorias |>
gt(groupname_col = "cuenca") |>
tab_header(
title = "Análisis Hidrológico Mensual",
subtitle = "Principales variables por cuenca hidrográfica"
) |>
# Formato de fuente
tab_options(
table.font.names = c("Arial Narrow", "Arial", "sans-serif"),
table.font.size = px(11),
heading.title.font.size = px(18),
heading.subtitle.font.size = px(14),
row_group.font.weight = "bold",
row_group.background.color = "#E8F4F8"
) |>
# Etiquetas de columnas
cols_label(
mes = "Mes",
caudal_medio = "Caudal (m³/s)",
precipitacion = "Precip. (mm)",
temperatura = "Temp. (°C)"
) |>
# Formato de números
fmt_number(
columns = c(caudal_medio, precipitacion, temperatura),
decimals = 1,
sep_mark = ".",
dec_mark = ","
)
tabla_categorias
```
## Paso 4: Efecto cebra o pijama
Aplicamos diferentes estilos de sombreado para mejorar la legibilidad.
```{r efecto-cebra}
#| label: efecto-cebra
# Versión 1: Cebra simple (filas alternas)
tabla_cebra_simple <- datos_categorias |>
gt(groupname_col = "cuenca") |>
tab_header(
title = "Análisis Hidrológico - Estilo Cebra Simple",
subtitle = "Sombreado en filas alternas"
) |>
# Fuente Arial Narrow
tab_options(
table.font.names = c("Arial Narrow", "Arial", "sans-serif"),
table.font.size = px(11),
row_group.font.weight = "bold",
row_group.background.color = "#2C5F7C",
) |>
# Usar tab_style() para el color del texto:
tab_style(
style = cell_text(color = "white"),
locations = cells_row_groups() # ✅ Aplicar a los grupos de filas
) |>
# Efecto cebra en filas pares
tab_style(
style = cell_fill(color = "#F0F8FC"),
locations = cells_body(
rows = seq(2, nrow(datos_categorias), 2)
)
) |>
cols_label(
mes = "Mes",
caudal_medio = "Caudal (m³/s)",
precipitacion = "Precip. (mm)",
temperatura = "Temp. (°C)"
) |>
fmt_number(
columns = c(caudal_medio, precipitacion, temperatura),
decimals = 1
)
tabla_cebra_simple
```
## Paso 5: Efecto cebra en intervalo específico
Aplicamos el efecto cebra solo a un rango determinado de filas y añadimos resaltado condicional.
```{r cebra-intervalo}
#| label: cebra-intervalo
# Preparar datos con resumen
datos_con_resumen <- datos_hidrologicos |>
group_by(cuenca) |>
summarise(
caudal_anual = mean(caudal_medio, na.rm = TRUE),
precip_anual = sum(precipitacion, na.rm = TRUE),
temp_media = mean(temperatura, na.rm = TRUE),
.groups = "drop"
) |>
arrange(desc(caudal_anual))
tabla_cebra_intervalo <- datos_con_resumen |>
gt() |>
tab_header(
title = "Resumen Anual por Cuenca",
subtitle = "Efecto cebra aplicado a intervalo específico (filas 2-4)"
) |>
# Configuración de fuente
tab_options(
table.font.names = c("Arial Narrow", "Arial", "sans-serif"),
table.font.size = px(12),
heading.title.font.size = px(16),
heading.subtitle.font.size = px(14)
) |>
# Etiquetas
cols_label(
cuenca = "Cuenca",
caudal_anual = "Caudal Medio Anual (m³/s)",
precip_anual = "Precipitación Total (mm)",
temp_media = "Temperatura Media (°C)"
) |>
# Formato de números
fmt_number(
columns = c(caudal_anual, precip_anual, temp_media),
decimals = 1,
sep_mark = ".",
dec_mark = ","
) |>
# Efecto cebra solo en filas 2 a 4
tab_style(
style = cell_fill(color = "#E8F4F8"),
locations = cells_body(rows = c(2, 4))
) |>
# Resaltar valores máximos
tab_style(
style = list(
cell_fill(color = "#FFE5B4"),
cell_text(weight = "bold")
),
locations = cells_body(
columns = caudal_anual,
rows = caudal_anual == max(caudal_anual)
)
)
tabla_cebra_intervalo
```
## Paso 6: Tabla avanzada con múltiples mejoras
Combinamos todas las técnicas anteriores y añadimos elementos adicionales.
```{r tabla-avanzada}
#| label: tabla-avanzada
# Crear datos más complejos para demostración
datos_completos <- datos_hidrologicos |>
group_by(cuenca, trimestre = quarter(match(mes, month.name))) |>
summarise(
caudal_medio = mean(caudal_medio, na.rm = TRUE),
caudal_max_trim = max(caudal_max, na.rm = TRUE),
caudal_min_trim = min(caudal_min, na.rm = TRUE),
precipitacion = sum(precipitacion, na.rm = TRUE),
temperatura = mean(temperatura, na.rm = TRUE),
evaporacion = sum(evaporacion, na.rm = TRUE),
nivel_embalse = mean(nivel_embalse, na.rm = TRUE),
.groups = "drop"
) |>
mutate(
trimestre = paste0("T", trimestre),
balance_hidrico = precipitacion - evaporacion,
indice_sequia = case_when(
balance_hidrico < -100 ~ "Sequía severa",
balance_hidrico < 0 ~ "Déficit",
balance_hidrico < 100 ~ "Normal",
TRUE ~ "Excedente"
)
)
tabla_avanzada <- datos_completos |>
gt(groupname_col = "cuenca") |>
# Encabezado
tab_header(
title = md("**Sistema de Información Hidrológica**"),
subtitle = md("*Análisis trimestral con indicadores de gestión*")
) |>
# Spanners para agrupar columnas relacionadas
tab_spanner(
label = "CAUDALES (m³/s)",
columns = c(caudal_medio, caudal_max_trim, caudal_min_trim)
) |>
tab_spanner(
label = "BALANCE HÍDRICO",
columns = c(precipitacion, evaporacion, balance_hidrico)
) |>
tab_spanner(
label = "INDICADORES",
columns = c(nivel_embalse, indice_sequia)
) |>
# Etiquetas personalizadas
cols_label(
trimestre = "Periodo",
caudal_medio = "Media",
caudal_max_trim = "Máx",
caudal_min_trim = "Mín",
precipitacion = "P (mm)",
evaporacion = "E (mm)",
balance_hidrico = "P-E",
temperatura = "T (°C)",
nivel_embalse = "Embalse (%)",
indice_sequia = "Estado"
) |>
# Formato de números
fmt_number(
columns = c(caudal_medio, caudal_max_trim, caudal_min_trim,
precipitacion, evaporacion, balance_hidrico,
temperatura, nivel_embalse),
decimals = 1,
sep_mark = ".",
dec_mark = ","
) |>
# Ocultar columna de temperatura (ejemplo de optimización)
cols_hide(columns = temperatura) |>
# Estilos y colores
tab_options(
table.font.names = c("Arial Narrow", "Arial", "sans-serif"),
table.font.size = px(11),
heading.title.font.size = px(18),
heading.subtitle.font.size = px(14),
heading.background.color = "#1E3A5F",
column_labels.background.color = "#4A7BA7",
column_labels.font.weight = "bold",
row_group.background.color = "#2C5F7C",
row_group.font.weight = "bold",
table.border.top.width = px(3),
table.border.top.color = "#1E3A5F",
table.border.bottom.width = px(3),
table.border.bottom.color = "#1E3A5F"
) |>
tab_style(
style = cell_text(color = "white"),
locations = cells_title(groups = c("title", "subtitle"))
) |>
tab_style(
style = cell_text(color = "white"),
locations = cells_column_labels()
) |>
# Efecto cebra en todas las filas de datos
tab_style(
style = cell_fill(color = "#F5FBFF"),
locations = cells_body(rows = seq(2, nrow(datos_completos), 2))
) |>
# Colorear según el índice de sequía
tab_style(
style = list(
cell_fill(color = "#FFD6D6"),
cell_text(weight = "bold", color = "#8B0000")
),
locations = cells_body(
columns = indice_sequia,
rows = indice_sequia == "Sequía severa"
)
) |>
tab_style(
style = list(
cell_fill(color = "#FFF4E6"),
cell_text(color = "#CC6600")
),
locations = cells_body(
columns = indice_sequia,
rows = indice_sequia == "Déficit"
)
) |>
tab_style(
style = list(
cell_fill(color = "#E6F7E6"),
cell_text(color = "#006400")
),
locations = cells_body(
columns = indice_sequia,
rows = indice_sequia == "Excedente"
)
) |>
# Resaltar valores extremos de caudal
tab_style(
style = list(
cell_text(weight = "bold", color = "#0066CC")
),
locations = cells_body(
columns = caudal_max_trim,
rows = caudal_max_trim > quantile(caudal_max_trim, 0.9)
)
) |>
# Nota al pie
tab_footnote(
footnote = "P: Precipitación, E: Evapotranspiración, P-E: Balance hídrico",
locations = cells_column_spanners(spanners = "BALANCE HÍDRICO")
) |>
tab_footnote(
footnote = "Datos simulados para demostración",
locations = cells_title(groups = "title")
)
tabla_avanzada
```
## Paso 7: Técnicas adicionales para tablas muy anchas
Para tablas extremadamente anchas, aquí hay técnicas adicionales:
```{r tecnicas-adicionales}
#| label: tecnicas-adicionales
# Crear una tabla muy ancha con datos mensuales completos
datos_muy_anchos <- datos_hidrologicos |>
filter(str_detect(estacion, "EA001|EA002")) |>
select(cuenca, mes, caudal_medio, precipitacion) |>
pivot_wider(
names_from = mes,
values_from = c(caudal_medio, precipitacion),
names_glue = "{mes}_{.value}"
)
tabla_optimizada <- datos_muy_anchos |>
gt() |>
tab_header(
title = "Optimización para Tablas Muy Anchas",
subtitle = "Técnicas de compresión visual"
) |>
# Configuración extrema para ahorro de espacio
tab_options(
table.font.names = c("Arial Narrow", "Helvetica Narrow", "sans-serif"),
table.font.size = px(9),
data_row.padding = px(2), # Reducir padding
column_labels.font.size = px(8),
column_labels.padding = px(3),
heading.title.font.size = px(14),
heading.subtitle.font.size = px(11)
) |>
# Ancho mínimo de columnas
cols_width(
cuenca ~ px(80),
everything() ~ px(45)
) |>
# Rotar etiquetas de columnas para ahorrar espacio horizontal
tab_style(
style = css(transform = "rotate(-45deg)",
"white-space" = "nowrap",
"text-align" = "left"),
locations = cells_column_labels(
columns = -cuenca
)
) |>
# Formato compacto de números
fmt_number(
columns = -cuenca,
decimals = 0,
suffixing = TRUE # Usar notación K, M para números grandes
) |>
# Colores alternados por grupos de columnas
tab_style(
style = cell_fill(color = "#E8F0FE"),
locations = cells_body(
columns = contains("January") | contains("March") |
contains("May") | contains("July") |
contains("September") | contains("November")
)
) |>
tab_style(
style = cell_fill(color = "#FFF3E0"),
locations = cells_body(
columns = contains("February") | contains("April") |
contains("June") | contains("August") |
contains("October") | contains("December")
)
)
tabla_optimizada
```
## Paso 8: Función personalizada para aplicar estilos
Creamos una función reutilizable para aplicar nuestros estilos preferidos.
```{r funcion-personalizada}
#| label: funcion-estilo
# Función para aplicar estilo hidrológico estándar
aplicar_estilo_hidrologico <- function(tabla_gt,
efecto_cebra = TRUE,
filas_cebra = "pares",
fuente = "Arial Narrow",
tamano_fuente = 11) {
# Aplicar configuración base
tabla_estilizada <- tabla_gt |>
tab_options(
table.font.names = c(fuente, "Arial", "sans-serif"),
table.font.size = px(tamano_fuente),
heading.title.font.size = px(tamano_fuente + 5),
heading.subtitle.font.size = px(tamano_fuente + 2),
heading.background.color = "#1E3A5F",
column_labels.background.color = "#4A7BA7",
column_labels.font.weight = "bold",
table.border.top.width = px(2),
table.border.top.color = "#1E3A5F"
) |>
tab_style(
style = cell_text(color = "white"),
locations = cells_title(groups = c("title", "subtitle"))
) |>
tab_style(
style = cell_text(color = "white"),
locations = cells_column_labels()
)
n_filas <- tabla_gt$`_data` |> nrow()
# Aplicar efecto cebra si está activado
if (efecto_cebra) {
if (all(filas_cebra == "pares")) {
filas_a_colorear <- seq(2, n_filas * 2, 2) # toma el número de filas. Multiplico por 2 por asegurar en caso de encabezados de grupo
} else if (all(filas_cebra == "impares")) {
filas_a_colorear <- seq(1, n_filas * 2, 2)
} else if (is.numeric(filas_cebra)) {
filas_a_colorear <- filas_cebra
}
tabla_estilizada <- tabla_estilizada |>
tab_style(
style = cell_fill(color = "#F0F8FC"),
locations = cells_body(rows = filas_a_colorear)
)
}
return(tabla_estilizada)
}
# Ejemplo de uso de la función
datos_ejemplo <- datos_hidrologicos |>
filter(mes %in% c("January", "February", "March")) |>
group_by(cuenca) |>
summarise(
caudal_medio = mean(caudal_medio),
precipitacion = sum(precipitacion),
temperatura = mean(temperatura),
.groups = "drop"
)
tabla_con_funcion <- datos_ejemplo |>
gt() |>
tab_header(
title = "Tabla con Estilo Personalizado",
subtitle = "Usando función reutilizable"
) |>
cols_label(
cuenca = "Cuenca",
caudal_medio = "Q medio (m³/s)",
precipitacion = "P total (mm)",
temperatura = "T media (°C)"
) |>
fmt_number(
columns = where(is.numeric),
decimals = 1,
sep_mark = ".",
dec_mark = ","
) |>
aplicar_estilo_hidrologico(
efecto_cebra = TRUE,
filas_cebra = c(1, 3, 5), # Solo filas impares
tamano_fuente = 10
)
tabla_con_funcion
```
## Consejos finales para tablas anchas
### 1. **Optimización del espacio horizontal**
- Usar fuentes condensadas (Arial Narrow, Helvetica Narrow)
- Reducir el padding de las celdas
- Abreviar nombres de columnas cuando sea posible
- Considerar transponer la tabla si tiene pocas filas y muchas columnas
### 2. **Mejora de la legibilidad**
- Aplicar efectos cebra para distinguir filas
- Usar colores sutiles para agrupar columnas relacionadas
- Implementar bordes verticales solo cuando sea necesario
- Destacar valores importantes con formato condicional
### 3. **Organización de la información**
- Agrupar columnas relacionadas con `tab_spanner()`
- Usar filas de grupo para categorizar datos
- Ocultar columnas menos importantes con `cols_hide()`
- Considerar crear múltiples tablas más pequeñas en lugar de una muy ancha
### 4. **Exportación y visualización**
```{r exportacion, eval=FALSE}
#| label: exportar-tabla
# Guardar como HTML
gtsave(tabla_avanzada, "tabla_hidrologica.html")
# Guardar como imagen PNG (requiere webshot2)
# install.packages("webshot2")
# webshot2::install_chromote()
gtsave(tabla_avanzada, "tabla_hidrologica.png",
expand = 10) # Margen adicional
# Guardar como Word (a través de flextable)
# library(flextable)
# tabla_avanzada |>
# as_flex_table() |>
# save_as_docx(path = "tabla_hidrologica.docx")
```
## Ejemplo integrado: Dashboard de cuenca
Para finalizar, aquí hay un ejemplo que combina todas las técnicas para crear una tabla tipo dashboard:
```{r dashboard}
#| label: tabla-dashboard
# Preparar datos de resumen ejecutivo
resumen_cuencas <- datos_hidrologicos |>
group_by(cuenca) |>
summarise(
q_medio_anual = mean(caudal_medio),
q_max_anual = max(caudal_max),
q_min_anual = min(caudal_min),
p_total = sum(precipitacion),
t_media = mean(temperatura),
nivel_medio = mean(nivel_embalse),
meses_sequia = sum(precipitacion < 20),
.groups = "drop"
) |>
mutate(
estado = case_when(
nivel_medio > 70 ~ "Óptimo",
nivel_medio > 50 ~ "Normal",
nivel_medio > 30 ~ "Alerta",
TRUE ~ "Crítico"
),
tendencia = sample(c("↑", "↓", "→"), n(), replace = TRUE)
)
dashboard_final <- resumen_cuencas |>
gt() |>
tab_header(
title = md("**DASHBOARD HIDROLÓGICO ANUAL**"),
subtitle = md("*Sistema integrado de monitoreo de cuencas - Año 2024*")
) |>
tab_spanner(
label = md("**CAUDALES** (m³/s)"),
columns = c(q_medio_anual, q_max_anual, q_min_anual)
) |>
tab_spanner(
label = md("**METEOROLOGÍA**"),
columns = c(p_total, t_media)
) |>
tab_spanner(
label = md("**GESTIÓN**"),
columns = c(nivel_medio, meses_sequia, estado, tendencia)
) |>
cols_label(
cuenca = "",
q_medio_anual = "Media",
q_max_anual = "Máximo",
q_min_anual = "Mínimo",
p_total = "P anual (mm)",
t_media = "T media (°C)",
nivel_medio = "Embalse (%)",
meses_sequia = "Meses sequía",
estado = "Estado",
tendencia = "Tend."
) |>
# Formato de números
fmt_number(
columns = c(q_medio_anual, q_max_anual, q_min_anual, p_total, t_media, nivel_medio),
decimals = 1,
sep_mark = ".",
dec_mark = ","
) |>
# Estilos base
tab_options(
table.font.names = c("Arial Narrow", "Arial", "sans-serif"),
table.font.size = px(11),
heading.title.font.size = px(20),
heading.subtitle.font.size = px(14),
heading.background.color = "#0D47A1",
heading.padding = px(10),
column_labels.background.color = "#1976D2",
column_labels.font.weight = "bold",
column_labels.padding = px(8),
data_row.padding = px(5),
table.border.top.width = px(3),
table.border.top.color = "#0D47A1",
table.border.bottom.width = px(3),
table.border.bottom.color = "#0D47A1"
) |>
tab_style(
style = cell_text(color = "white"),
locations = cells_title(groups = c("title", "subtitle"))
) |>
tab_style(
style = cell_text(color = "white"),
locations = cells_column_labels()
) |>
# Efecto cebra sutil
tab_style(
style = cell_fill(color = "#F5F9FF"),
locations = cells_body(rows = seq(2, nrow(resumen_cuencas), 2))
) |>
# Colorear columna de estado
tab_style(
style = list(
cell_fill(color = "#C8E6C9"),
cell_text(weight = "bold", color = "#1B5E20")
),
locations = cells_body(
columns = estado,
rows = estado == "Óptimo"
)
) |>
tab_style(
style = list(
cell_fill(color = "#FFF9C4"),
cell_text(color = "#F57C00")
),
locations = cells_body(
columns = estado,
rows = estado == "Normal"
)
) |>
tab_style(
style = list(
cell_fill(color = "#FFE0B2"),
cell_text(weight = "bold", color = "#E65100")
),
locations = cells_body(
columns = estado,
rows = estado == "Alerta"
)
) |>
tab_style(
style = list(
cell_fill(color = "#FFCDD2"),
cell_text(weight = "bold", color = "#B71C1C")
),
locations = cells_body(
columns = estado,
rows = estado == "Crítico"
)
) |>
# Resaltar valores extremos
tab_style(
style = list(
cell_text(color = "#0D47A1", weight = "bold")
),
locations = cells_body(
columns = q_max_anual,
rows = q_max_anual == max(q_max_anual)
)
) |>
tab_style(
style = list(
cell_text(color = "#B71C1C", weight = "bold")
),
locations = cells_body(
columns = meses_sequia,
rows = meses_sequia > 3
)
) |>
# Notas al pie
tab_footnote(
footnote = md("**Nota:** Datos actualizados al último día del mes"),
locations = cells_title(groups = "subtitle")
) |>
tab_source_note(
source_note = md("*Fuente: Sistema Nacional de Información Hidrológica | Procesado con R + gt*")
)
dashboard_final
```
## Conclusión
El paquete `gt` ofrece una amplia gama de opciones para optimizar la presentación de tablas anchas. Las técnicas clave incluyen:
1. **Tipografía condensada** para maximizar el uso del espacio
2. **Agrupación lógica** de columnas y filas
3. **Efectos visuales** como el sombreado cebra para mejorar la legibilidad
4. **Formato condicional** para destacar información crítica
5. **Personalización avanzada** mediante funciones reutilizables
Estas herramientas son especialmente valiosas en el contexto de la gestión hidrológica, donde frecuentemente trabajamos con series temporales extensas y múltiples variables que requieren una presentación clara y profesional.
---
*Tutorial desarrollado para la aplicación de ciencia de datos en hidrología y gestión de recursos hídricos.*
