Tablas con gt: sencillas, pero chulas

Módulo práctico de ITA
(Grupo M)

Pedro J. Pérez

Tablas con gt

Ya sabemos hacer gráficos. Pero muchas veces los resultados se presentan mejor en una tabla. Vamos a hacer tablas sencillas, pero chulas, con el paquete gt. Y al final las llevaremos a Word o a Excel.

¿por qué tablas?

  • Un gráfico enseña muy bien la idea general; una tabla, los valores exactos. En un informe casi siempre hacen falta las dos cosas
  • ¿Te acuerdas de las slides de manejo de datos? Para enseñar los resultados usábamos gt::gt(aa). Ahora vamos a ver cómo hacer esas tablas más bonitas


el paquete gt

  • gt (grammar of tables) es a las tablas lo que ggplot2 a los gráficos: la tabla se construye por partes, añadiendo funciones con %>%
install.packages("gt")   #- solo hay que instalarlo una vez

library(gt)

primero, los datos … y una tabla básica con gt()

Como siempre, primero preparamos los datos. Queremos una tabla con algunos datos de cada continente en 2007. ¿Te acuerdas de group_by() + summarise()?

df_tabla <- gapminder %>%
  filter(year == 2007) %>%
  group_by(continent) %>%
  summarise(n_paises = n(),
            media_lifeExp = mean(lifeExp),
            media_gdpPercap = mean(gdpPercap),
            pob_millones = sum(pop) / 1000000)

Hacer una tabla básica es muy fácil: basta con gt()

gt(df_tabla)
continent n_paises media_lifeExp media_gdpPercap pob_millones
Africa 52 54.80604 3089.033 929.53969
Americas 25 73.60812 11003.032 898.87118
Asia 33 70.72848 12473.027 3811.95383
Europe 30 77.64860 25054.482 586.09853
Oceania 2 80.71950 29810.188 24.54995

  • No está mal, pero se puede mejorar casi todo: no tiene título, los números tienen demasiados decimales, los nombres de las columnas son los de las variables … Vamos a ello

una tabla gt, paso a paso

df_tabla %>%
df_tabla %>%
  gt() %>%
df_tabla %>%
  gt() %>%
  tab_header(title = "Los continentes en 2007",
             subtitle = "Datos de gapminder") %>%
df_tabla %>%
  gt() %>%
  tab_header(title = "Los continentes en 2007",
             subtitle = "Datos de gapminder") %>%
  cols_label(continent = "Continente",
             n_paises = "Nº de países",
             media_lifeExp = "Esperanza de vida",
             media_gdpPercap = "Renta per cápita",
             pob_millones = "Población (millones)") %>%
df_tabla %>%
  gt() %>%
  tab_header(title = "Los continentes en 2007",
             subtitle = "Datos de gapminder") %>%
  cols_label(continent = "Continente",
             n_paises = "Nº de países",
             media_lifeExp = "Esperanza de vida",
             media_gdpPercap = "Renta per cápita",
             pob_millones = "Población (millones)") %>%
  fmt_number(columns = c(media_lifeExp, media_gdpPercap,
                         pob_millones),
             decimals = 1,
             sep_mark = ".", dec_mark = ",") %>%
df_tabla %>%
  gt() %>%
  tab_header(title = "Los continentes en 2007",
             subtitle = "Datos de gapminder") %>%
  cols_label(continent = "Continente",
             n_paises = "Nº de países",
             media_lifeExp = "Esperanza de vida",
             media_gdpPercap = "Renta per cápita",
             pob_millones = "Población (millones)") %>%
  fmt_number(columns = c(media_lifeExp, media_gdpPercap,
                         pob_millones),
             decimals = 1,
             sep_mark = ".", dec_mark = ",") %>%
  tab_source_note("Fuente: gapminder")
#> # A tibble: 5 × 5
#>   continent n_paises media_lifeExp media_gdpPercap pob_millones
#>   <fct>        <int>         <dbl>           <dbl>        <dbl>
#> 1 Africa          52          54.8           3089.        930. 
#> 2 Americas        25          73.6          11003.        899. 
#> 3 Asia            33          70.7          12473.       3812. 
#> 4 Europe          30          77.6          25054.        586. 
#> 5 Oceania          2          80.7          29810.         24.5
continent n_paises media_lifeExp media_gdpPercap pob_millones
Africa 52 54.80604 3089.033 929.53969
Americas 25 73.60812 11003.032 898.87118
Asia 33 70.72848 12473.027 3811.95383
Europe 30 77.64860 25054.482 586.09853
Oceania 2 80.71950 29810.188 24.54995
Los continentes en 2007
Datos de gapminder
continent n_paises media_lifeExp media_gdpPercap pob_millones
Africa 52 54.80604 3089.033 929.53969
Americas 25 73.60812 11003.032 898.87118
Asia 33 70.72848 12473.027 3811.95383
Europe 30 77.64860 25054.482 586.09853
Oceania 2 80.71950 29810.188 24.54995
Los continentes en 2007
Datos de gapminder
Continente Nº de países Esperanza de vida Renta per cápita Población (millones)
Africa 52 54.80604 3089.033 929.53969
Americas 25 73.60812 11003.032 898.87118
Asia 33 70.72848 12473.027 3811.95383
Europe 30 77.64860 25054.482 586.09853
Oceania 2 80.71950 29810.188 24.54995
Los continentes en 2007
Datos de gapminder
Continente Nº de países Esperanza de vida Renta per cápita Población (millones)
Africa 52 54,8 3.089,0 929,5
Americas 25 73,6 11.003,0 898,9
Asia 33 70,7 12.473,0 3.812,0
Europe 30 77,6 25.054,5 586,1
Oceania 2 80,7 29.810,2 24,5
Los continentes en 2007
Datos de gapminder
Continente Nº de países Esperanza de vida Renta per cápita Población (millones)
Africa 52 54,8 3.089,0 929,5
Americas 25 73,6 11.003,0 898,9
Asia 33 70,7 12.473,0 3.812,0
Europe 30 77,6 25.054,5 586,1
Oceania 2 80,7 29.810,2 24,5
Fuente: gapminder

¿qué ha hecho cada función?

función ¿qué hace?
gt() convierte el data frame en una tabla
tab_header() añade el título (y el subtítulo)
cols_label() cambia los nombres que se ven en las columnas
fmt_number() da formato a los números: decimales, separador de miles y de decimales
tab_source_note() añade una nota debajo de la tabla; normalmente, la fuente de los datos

  • Fíjate en los nombres: las funciones tab_*() añaden partes a la tabla, las fmt_*() dan formato a los valores y las cols_*() cambian las columnas

  • ¡Ojo! cols_label() solo cambia lo que se ve. En el resto de funciones las columnas se siguen llamando igual: media_lifeExp, media_gdpPercap, pob_millones …

Haciéndola más chula

Con la tabla ya hecha, unos pocos retoques la mejoran mucho: un estilo, colores según el valor o destacar una fila

lo más rápido: un estilo con opt_stylize()

Guardamos la tabla en un objeto, tt, y le añadimos un estilo. Hay 6 estilos (style = 1 … 6) y varios colores

tt %>% opt_stylize(style = 1, color = "green")

 

tt %>% opt_stylize(style = 1, color = "green")
Los continentes en 2007
Datos de gapminder
Continente Nº de países Esperanza de vida Renta per cápita Población (millones)
Africa 52 54,8 3.089,0 929,5
Americas 25 73,6 11.003,0 898,9
Asia 33 70,7 12.473,0 3.812,0
Europe 30 77,6 25.054,5 586,1
Oceania 2 80,7 29.810,2 24,5
Fuente: gapminder
tt %>% opt_stylize(style = 3, color = "blue")
Los continentes en 2007
Datos de gapminder
Continente Nº de países Esperanza de vida Renta per cápita Población (millones)
Africa 52 54,8 3.089,0 929,5
Americas 25 73,6 11.003,0 898,9
Asia 33 70,7 12.473,0 3.812,0
Europe 30 77,6 25.054,5 586,1
Oceania 2 80,7 29.810,2 24,5
Fuente: gapminder
tt %>% opt_stylize(style = 6, color = "gray")
Los continentes en 2007
Datos de gapminder
Continente Nº de países Esperanza de vida Renta per cápita Población (millones)
Africa 52 54,8 3.089,0 929,5
Americas 25 73,6 11.003,0 898,9
Asia 33 70,7 12.473,0 3.812,0
Europe 30 77,6 25.054,5 586,1
Oceania 2 80,7 29.810,2 24,5
Fuente: gapminder

otra forma rápida: los temas de gtExtras

El paquete gtExtras tiene temas que cambian de golpe el aspecto de la tabla, imitando el de periódicos, webs o programas (hay que instalarlo antes: install.packages("gtExtras"))

tt %>% gtExtras::gt_theme_nytimes()

 

tt %>% gtExtras::gt_theme_nytimes()
Los continentes en 2007
Datos de gapminder
Continente Nº de países Esperanza de vida Renta per cápita Población (millones)
Africa 52 54,8 3.089,0 929,5
Americas 25 73,6 11.003,0 898,9
Asia 33 70,7 12.473,0 3.812,0
Europe 30 77,6 25.054,5 586,1
Oceania 2 80,7 29.810,2 24,5
Fuente: gapminder
tt %>% gtExtras::gt_theme_guardian()
Los continentes en 2007
Datos de gapminder
Continente Nº de países Esperanza de vida Renta per cápita Población (millones)
Africa 52 54,8 3.089,0 929,5
Americas 25 73,6 11.003,0 898,9
Asia 33 70,7 12.473,0 3.812,0
Europe 30 77,6 25.054,5 586,1
Oceania 2 80,7 29.810,2 24,5
Fuente: gapminder
tt %>% gtExtras::gt_theme_espn()
Los continentes en 2007
Datos de gapminder
Continente Nº de países Esperanza de vida Renta per cápita Población (millones)
Africa 52 54,8 3.089,0 929,5
Americas 25 73,6 11.003,0 898,9
Asia 33 70,7 12.473,0 3.812,0
Europe 30 77,6 25.054,5 586,1
Oceania 2 80,7 29.810,2 24,5
Fuente: gapminder
tt %>% gtExtras::gt_theme_excel()
Los continentes en 2007
Datos de gapminder
Continente Nº de países Esperanza de vida Renta per cápita Población (millones)
Africa 52 54,8 3.089,0 929,5
Americas 25 73,6 11.003,0 898,9
Asia 33 70,7 12.473,0 3.812,0
Europe 30 77,6 25.054,5 586,1
Oceania 2 80,7 29.810,2 24,5
Fuente: gapminder

colores según el valor: data_color()

tt %>%
  data_color(columns = media_lifeExp,
             palette = "Greens")
  • data_color() colorea las celdas de una columna según su valor: cuanto más alto, más oscuro

  • Así se ve de un vistazo qué continente tiene la esperanza de vida más alta (¿y la más baja?)

Los continentes en 2007
Datos de gapminder
Continente Nº de países Esperanza de vida Renta per cápita Población (millones)
Africa 52 54,8 3.089,0 929,5
Americas 25 73,6 11.003,0 898,9
Asia 33 70,7 12.473,0 3.812,0
Europe 30 77,6 25.054,5 586,1
Oceania 2 80,7 29.810,2 24,5
Fuente: gapminder

destacar una fila: tab_style()

tt %>%
  tab_style(
1    style = list(cell_fill(color = "lightyellow"),
                 cell_text(weight = "bold")),
2    locations = cells_body(
      rows = continent == "Europe"))
1
cómo queremos las celdas: fondo amarillo y letra en negrita
2
qué celdas: las de la fila de Europa
Los continentes en 2007
Datos de gapminder
Continente Nº de países Esperanza de vida Renta per cápita Población (millones)
Africa 52 54,8 3.089,0 929,5
Americas 25 73,6 11.003,0 898,9
Asia 33 70,7 12.473,0 3.812,0
Europe 30 77,6 25.054,5 586,1
Oceania 2 80,7 29.810,2 24,5
Fuente: gapminder

Tarea: haz tu tabla

Haz una tabla con la esperanza de vida y la renta per cápita de España, Francia, Italia, Portugal y Alemania en 2007. La tabla tiene que tener:

  • un título y la fuente de los datos

  • nombres de columnas “bonitos” y los números con un decimal

  • … y un estilo, o algún color, que te guste

  • Primero, los datos: filter() para quedarte con 2007 y con los 5 países (¿te acuerdas de %in%?) y select() para quedarte con las columnas que necesitas

  • Después, la tabla: gt(), tab_header(), cols_label(), fmt_number(), tab_source_note() … y, por ejemplo, opt_stylize()

df_tarea <- gapminder %>%
  filter(year == 2007) %>%
  filter(country %in% c("Spain", "France", "Italy", "Portugal", "Germany")) %>%
  select(country, lifeExp, gdpPercap)

df_tarea %>%
  gt() %>%
  tab_header(title = "Algunos países europeos en 2007") %>%
  cols_label(country = "País", lifeExp = "Esperanza de vida", gdpPercap = "Renta per cápita") %>%
  fmt_number(columns = c(lifeExp, gdpPercap), decimals = 1, sep_mark = ".", dec_mark = ",") %>%
  tab_source_note("Fuente: gapminder") %>%
  opt_stylize(style = 3, color = "green")
Algunos países europeos en 2007
País Esperanza de vida Renta per cápita
France 80,7 30.470,0
Germany 79,4 32.170,4
Italy 80,5 28.569,7
Portugal 78,1 20.509,6
Spain 80,9 28.821,1
Fuente: gapminder

Exportar las tablas

Igual que con los gráficos, muchas veces queremos llevar la tabla a un informe (Word) o a una hoja de cálculo (Excel)

llevar la tabla a Word: gtsave()

Para guardar una tabla en un fichero se usa gtsave(). El formato lo decide la extensión del fichero


1tt_final <- tt %>% opt_stylize(style = 1, color = "green")

2gtsave(tt_final, "tabla_continentes.docx")
1
Guardamos en un objeto la tabla que queremos exportar
2
Con la extensión .docx se guarda como un documento de Word



  • El fichero se guarda en la carpeta del proyecto. Al abrirlo con Word verás que es una tabla de Word: puedes cambiar lo que quieras, o copiarla y pegarla en tu informe
  • Puede que algún adorno (un color, un borde) no salga exactamente igual que en R. Si no te gusta, se retoca en Word

llevar la tabla a Excel

gt no sabe guardar las tablas en Excel, pero tenemos 2 opciones:


  1. Copiar y pegar: guardamos la tabla como página web, la abrimos con el navegador, la seleccionamos y la copiamos (Ctrl + C); después, en Excel, Ctrl + V
gtsave(tt_final, "tabla_continentes.html")
  • Se mantiene (más o menos) el formato: negritas, colores, …


  1. Exportar los datos con rio::export() y darles formato en Excel
rio::export(df_tabla, "tabla_continentes.xlsx")
  • Ojo: así llegan los datos, no la tabla: el título, los nombres bonitos o los colores se los tendrás que poner en Excel. Lo veremos en las slides de Excel

un truco: la tabla como imagen

  • gtsave() también puede guardar la tabla como imagen (.png). Después la metes en Word o en Excel igual que un gráfico: Insertar > Imágenes
install.packages("webshot2")   #- para guardar como imagen hace falta este paquete

gtsave(tt_final, "tabla_continentes.png")

¿Imagen o tabla? Con la imagen la tabla se ve exactamente igual que en R, pero ya no la puedes cambiar. Con el .docx (o el copiar y pegar) sí la puedes cambiar

Tarea: exporta tu tabla

  1. Guarda en un objeto la tabla que hiciste en la tarea anterior

  2. Expórtala a Word con gtsave(). Abre el fichero: ¿se ve igual que en R?

  3. Llévala también a Excel, de las 2 formas: copiando y pegando, y exportando los datos con rio::export()


  • ¿Qué forma te ha resultado más cómoda? ¿Con cuál queda mejor la tabla?

Resumen

Todo lo que hemos visto, en una sola tabla (como siempre, primero los datos con dplyr y después la tabla con gt):

df_tabla %>%
1  gt() %>%
2  tab_header(title = "Los continentes en 2007") %>%
3  cols_label(continent = "Continente",
             n_paises = "Nº de países",
             media_lifeExp = "Esperanza de vida",
             media_gdpPercap = "Renta per cápita",
             pob_millones = "Población (millones)") %>%
4  fmt_number(columns = c(media_lifeExp, media_gdpPercap,
                         pob_millones),
             decimals = 1, sep_mark = ".", dec_mark = ",") %>%
5  tab_source_note("Fuente: gapminder") %>%
6  opt_stylize(style = 1, color = "green")
1
gt(): la tabla básica
2
tab_header(): el título (y el subtítulo)
3
cols_label(): los nombres que se ven en las columnas
4
fmt_number(): el formato de los números
5
tab_source_note(): la fuente de los datos
6
opt_stylize(): un estilo. O colores con data_color() y tab_style()
Los continentes en 2007
Continente Nº de países Esperanza de vida Renta per cápita Población (millones)
Africa 52 54,8 3.089,0 929,5
Americas 25 73,6 11.003,0 898,9
Asia 33 70,7 12.473,0 3.812,0
Europe 30 77,6 25.054,5 586,1
Oceania 2 80,7 29.810,2 24,5
Fuente: gapminder

Para exportarla, gtsave(): a Word con .docx; como imagen con .png. Y a Excel, copiando y pegando desde el .html o llevando los datos con rio::export()