Crea tablas con píldoras de colores usando {gt} en R

20/1/2026

tablas

En este tutorial veremos cómo convertir celdas de tus tablas a compactas píldoras usando {gt}, una excelente librería de R para crear tablas personalizables. El objetivo es presentar la información de forma más atractiva, permitiendo darle un color personalizado según el dato que se muestre, o bien, destacar determinados datos.

Si bien existen otras formas de hacer esto, aprender este método te entrega mucha más flexibilidad para trabajar tablas directamente con HTML en el paquete {gt}, desbloqueando su potencial! 🔥

Tablas básicas con {gt}

Primero cargamos los paquetes y creamos datos de prueba:

library(gt)
library(dplyr)
library(glue)

# crear datos de prueba
datos <- tibble(dato = c("A", "B", "C"),
                valor = c(1, 4, 8),
                tipo = c("bajo", "medio", "alto"))

Recordemos que para iniciar una tabla de {gt}, simplemente le ponemos la función gt() a los datos:

tabla <- datos |> gt()
dato valor tipo
A 1 bajo
B 4 medio
C 8 alto

Obtenemos una tabla básica.

Crear columnas con HTML y CSS

Ahora crearemos una columna con código HTML, el mismo que se usa para crear páginas web. Esto nos permite crear lo que se nos ocurra, y es la fortaleza principal de este método.

Simplemente creamos una columna que contenga el código:

tabla <- datos |> 
  # crear píldora html
  mutate(pildora = "<div style='padding: 2px 12px; 
                                border-radius: 12px; 
                                background: #9069C0; color: white;'>
                     Hola
                    </div>") |> 
  # hacer tabla
  gt()
dato valor tipo pildora
A 1 bajo <div style='padding: 2px 12px; border-radius: 12px; background: #9069C0; color: white;'> Hola </div>
B 4 medio <div style='padding: 2px 12px; border-radius: 12px; background: #9069C0; color: white;'> Hola </div>
C 8 alto <div style='padding: 2px 12px; border-radius: 12px; background: #9069C0; color: white;'> Hola </div>

¡Está horrible! 😣 Esto es porque hay que pedirle a {gt} interpretar la columna como HTML con la función fmt_markdown():

tabla <- datos |> 
  # crear píldora html
  mutate(pildora = "<div style='padding: 2px 12px; 
                                border-radius: 12px; 
                                background: #9069C0; color: white;'>
                     Hola
                    </div>") |> 
  # hacer tabla
  gt() |> 
  fmt_markdown(columns = "pildora")
dato valor tipo pildora
A 1 bajo
Hola
B 4 medio
Hola
C 8 alto
Hola

¡Ahora sí! Lo importante del código HTML es la etiqueta <div>, que crea un recuadro, y el atributo style, que define el estilo del mismo recuadro mediante código CSS. En este caso, le dimos un padding (espaciado interno), un borde redondeado (border-radius), un color de fondo (background), y un color de texto (color).

Aplicar píldoras a datos de una columna

Ahora podemos reemplazar el código anterior para que muestre el valor de la columna tipo. Para ello usamos la función glue(), que permite incrustar valores de R dentro de textos de una forma más cómoda que usar paste():

tabla <- datos |> 
  # crear píldora html
  mutate(tipo = glue(
    "<div style='padding: 2px 12px; 
                 border-radius: 12px; 
                 background: #9069C0; color: white;'>
      {tipo}
     </div>")) |> 
  # hacer tabla
  gt() |> 
  # que la columna se interprete como html
  fmt_markdown(columns = "tipo") |> 
  cols_align(tipo, align = "center")
dato valor tipo
A 1
bajo
B 4
medio
C 8
alto

Ahora la columna tipo muestra sus valores como píldoras. Hermoso!

Crear una función que cree columnas HTML

Hagamos que el código anterior sea más ordenado creando una función que haga las píldoras:

# crear una función que hace píldoras 
pildora <- function(valor) {
  # crear píldora html
  glue("<div style='padding: 2px 12px; 
                    border-radius: 12px; 
                    background: #9069C0; color: white;'>
         {valor}
        </div>")
}

La función es casi lo mismo que antes, solamente que recibe un valor llamado valor que se ubica dentro del glue(). Ahora veamos cómo se crea la tabla anterior pero usando la función nueva:

# aplicar función a la tabla
tabla <- datos |> 
  mutate(tipo = pildora(tipo)) |> 
  gt() |> 
  fmt_markdown(columns = "tipo")
dato valor tipo
A 1
bajo
B 4
medio
C 8
alto

El código queda mucho más compacto y ordenado!

Colores de píldoras según datos

Ahora complementemos la función que creamos, para que los colores de las píldoras dependan de los datos. Para ello, dentro de la función pildora() que creamos, podemos poner código que defina el color que tendrá cada píldora dependiendo de su valor:

# mejorar la función
pildora <- function(valor) {
  # definir colores en base a valores
  color <- case_match(valor,
                      "alto" ~ "#E56B6F",
                      "medio" ~ "#b56576",
                      "bajo" ~ "#6d597a")
  
  # crear píldora html
  glue("<div style='padding: 2px 12px; 
                    border-radius: 12px; 
                    background: {color}; color: white;'>
         {valor}
        </div>")
}

# aplicar función a la tabla
tabla <- datos |> 
  mutate(tipo = pildora(tipo)) |> 
  gt() |> 
  fmt_markdown(columns = "tipo")
dato valor tipo
A 1
bajo
B 4
medio
C 8
alto

Hermoso! Vimos que la función pildora() ahora usa valor para dos cosas: para determinar el color de fondo, y para poner el texto dentro de la píldora.

Variaciones de la función de píldoras

Finalmente, podemos crear distintas funciones de píldoras para distintos tipos de datos. Por ejemplo, una para variables categóricas, otra para variables numéricas, y otra para valores con color manual:

La función para variables categóricas, que ya vimos, entrega un color específico a valores específicos:

# función para variables categóricas
pildora_categorica <- function(valor) {
  # definir colores en base a valores
  color <- case_match(valor,
                      "alto" ~ "#E56B6F",
                      "medio" ~ "#b56576",
                      "bajo" ~ "#6d597a")
  
  # crear píldora html
  glue("<div style='padding: 2px 12px; 
                    border-radius: 12px; 
                    background: {color}; color: white;'>
         {valor}
        </div>")
}

La función para variables numéricas va a asignar color a las celdas dependiendo de si se cumple o no el criterio numérico que le demos:

# función para variables categóricas
pildora_numerica <- function(valor) {
  # definir colores en base a valores
  color <- case_when(valor >= 4 ~ "#749c75",
                     valor < 4 ~ "#b2bd7e")
  
  # crear píldora html
  glue("<div style='padding: 2px 12px; 
                    border-radius: 12px; 
                    background: {color}; color: white;'>
         {valor}
        </div>")
}

La tercera función simplemente le da el color que especifiquemos a todas las celdas por igual:

# función para color manual
pildora_manual <- function(valor, color) {
  # crear píldora html
  glue("<div style='padding: 2px 12px; 
                    border-radius: 12px; 
                    background: {color}; color: white;'>
         {valor}
        </div>")
}

Ahora apliquemos estos tres estilos a las tres columnas con {gt}

# aplicar función a la tabla
tabla <- datos |> 
  mutate(tipo = pildora_categorica(tipo),
         valor = pildora_numerica(valor),
         dato = pildora_manual(dato, "#355070")) |> 
  gt() |> 
  fmt_markdown(columns = c(tipo, valor, dato))
dato valor tipo
A
1
bajo
B
4
medio
C
8
alto

Destacar valores específicos

Otra variación de las funciones anteriores puede ser para que la píldora solamente destaque ciertos valores a los que queremos llamar la atención:

# función para color manual
pildora_alerta <- function(valor, alerta) {
  color_alerta <- "#ce4257"
  
  ifelse(valor == alerta,
         # si el valor coincide con la alerta, pildora
         glue("<div style='padding: 2px 12px; 
                    border-radius: 12px; 
                    background: {color_alerta}; color: white;'>
                {valor}
              </div>"),
         # si no, solo cifra con espaciado
         glue("<div style='padding: 2px 12px;'>{valor}</div>")
  )
}
# aplicar función a la tabla
tabla <- datos |> 
  mutate(dato = pildora_alerta(dato, alerta = "B"),
         tipo = pildora_alerta(tipo, alerta = "bajo")) |> 
  gt() |> 
  fmt_markdown(columns = c(dato, tipo))
dato valor tipo
A
1
bajo
B
4
medio
C
8
alto

Esta función nueva tiene la capacidad de que definas en cada caso el valor que quieres destacar, lo que permite reutilizarla en columnas distintas.

Función para degradado de colores

Finalmente, nos basamos en el código de las píldoras para variables numéricas para crear píldoras con un degradado de colores según el valor numérico.

Esto podemos hacerlo tomando el valor máximo de la columna y dividiéndolo por el valor de cada celda, para obtener la proporción (un número del 0 al 1), y usar este número para darle transparencia al color elegido. A su vez, podemos hacer que el texto de la píldora cambie de color si el color va a ser muy transparente, para asegurar buen contraste.

pildora_degradado <- function(valor, maximo, color) {
  # definir transparencia según valor máximo
  transparencia <- valor/maximo
  # definir color de texto según transparencia
  texto <- ifelse(transparencia > 0.5, "white", "black")
  # aplicar transparencia al color
  color <- scales::alpha(color, transparencia+0.1)
  
  glue("<div style='padding: 2px 12px; 
                    border-radius: 12px; 
                    background: {color}; color: {texto};'>
         {valor}
        </div>")
}

tabla <- datos |> 
  mutate(valor = pildora_degradado(valor, max(valor), color = "#E56B6F")) |> 
  gt() |> 
  fmt_markdown(columns = valor)
dato valor tipo
A
1
bajo
B
4
medio
C
8
alto

La función alpha() del paquete {scales} nos ayuda a crear colores transparentes a partir de un número entre el 0 (transparente) y el 1 (opaco).

El mismo código puede cambiarse un poco para crear un degradado entre dos colores:

pildora_degradado_2 <- function(valor, color_1, color_2) {
  # definir transparencia según valor máximo
  transparencia <- valor/max(valor)
  
  # opcional: escalar de 0 a 1
  # transparencia <- (transparencia-min(transparencia))/(max(transparencia)-min(transparencia))
  
  # crear colores de texto a partir de colores del degradado
  color_claro <- scales::col_mix("white", color_1, 0.4)
  color_oscuro <- scales::col_mix("black", color_2, 0.4)
  # definir color de texto según transparencia
  texto <- ifelse(transparencia > 0.5, color_claro, color_oscuro)
  
  # aplicar transparencia al color
  color <- scales::col_mix(color_1, color_2, transparencia-0.1)
  
  glue("<div style='padding: 2px 12px; 
                    border-radius: 12px; 
                    background: {color}; color: {texto};'>
         {valor}
        </div>")
}

tabla <- datos |> 
  mutate(valor = pildora_degradado_2(valor, 
                                     color_1 = "#e0b1cb", color_2 = "#5e548e")) |> 
  gt() |> 
  fmt_markdown(columns = valor)
dato valor tipo
A
1
bajo
B
4
medio
C
8
alto

En esta función usamos dos colores para crear un degradado entre el valor menor y el mayor de la columna, y incluso usamos estos colores para teñir los colores de los textos y así hacerlos más armónicos en vez de usar simplemente blanco y negro.


Y así se puede usar HTML para personalizar celdas de tus tablas hechas con {gt}. Si te interesa este paquete, tengo un tutorial más completo que puedes revisar.

Fecha de publicación:
January 20, 2026
Extensión:
8 minute read, 1632 words
Tags:
tablas
Ver también:
Visualización y scraping de resultados de las elecciones presidenciales 2025
Crea planillas de Excel con formato personalizado desde R con {openxlsx}
Repositorio de datos sociales