Escribiendo con R y Quarto
  • Info
  • Materiales
  • Blog
  • Pedro J. Pérez

Índice

  • 1 Intro
  • 2 Datos
  • 3 Tablas básicas
    • Con gt
    • Con DT
    • Con reactable
  • 4 Tuneando

Editar esta página

Informar de un problema

Generando tablas con R

tablas

Se pueden hacer tablas muy chulas con R. Por ejemplo mira aquí

Autor

Pedro J. Pérez

Fecha de Publicación

3 de febrero de 2023

Fecha de modificación

12 de junio de 2023

1 Intro

Durante el curso vimos que se podían insertar tablas en nuestros documentos QMD de dos formas:

  • usando Markdown

  • usando R (o otro lenguaje de programación)

Solo vimos un ejemplo muy sencillo, concretamente este pero dije que se podían hacer tablas muy chulas con R. Vamos a profundizar en ello.

2 Datos

Para ello vamos a usar datos de inflación de la OCDE. Vamos a descargar los datos:

Código
library(tidyverse)

#- Datos de inflación de la OCDE 
ruta_inflation <- "https://raw.githubusercontent.com/perezp44/archivos.download.2023/main/DP_LIVE_22032023113248591.csv"
inflation_orig <- readr::read_csv(ruta_inflation)
inflation_dicc <- pjpv.curso.R.2022::pjp_dicc(inflation_orig)

#- seleccionamos CPI mensual
inflation <- inflation_orig %>% 
  dplyr::filter(FREQUENCY == "M" & MEASURE == "AGRWTH") %>% 
  select(place = LOCATION, date = TIME, cpi = Value, tipo = SUBJECT) 

#- nos quedamos solo con el último dato: 2023-02 (y arreglamos)
inflation <- inflation %>% dplyr::filter(date == "2023-02") %>% 
  tidyr::pivot_wider(names_from = tipo, values_from = cpi) %>% 
  dplyr::arrange(desc(TOT))

3 Tablas básicas

Una vez tenemos los datos que queremos mostrar en una tabla, es muy fácil usar varios paquetes para mostrarlos en una tabla. Para saber un poco más sobre tablas en Quarto, puedes ir aquí

Con gt

Código
gt::gt(inflation %>% slice(1:10))
place date ENRG FOOD TOT TOT_FOODENRG
ARG 2023-02 NA 102.62940 102.50080 NA
TUR 2023-02 42.23681 69.33482 55.17983 51.902860
HUN 2023-02 39.45069 45.80613 25.40000 16.207950
LVA 2023-02 46.42958 25.33258 20.26292 10.511360
LTU 2023-02 29.20563 30.18281 18.73836 12.170210
EST 2023-02 30.27698 25.20833 17.54967 12.125680
CZE 2023-02 33.82126 23.91482 16.71949 11.444360
COL 2023-02 18.02995 24.13994 13.27902 10.150170
CHL 2023-02 13.22474 21.43148 11.94660 9.090909
AUT 2023-02 26.51685 16.15970 10.88180 8.612440

Con DT

Código
DT::datatable(inflation)

Con reactable

Código
reactable::reactable(inflation)

4 Tuneando

Código
library(gt)
tt <- gt::gt(inflation %>% slice(1:10))

tt %>% tab_header(title = md("**Tasa de inflación**"),
                      subtitle = md("TOT: total; FOOD: alimentos; ENRG: energía")) %>% 
    tab_source_note(md("Fuente: datos de [OCDE](https://raw.githubusercontent.com/perezp44/archivos.download.2023/main/DP_LIVE_22032023113248591.csv)")) 
Tasa de inflación
TOT: total; FOOD: alimentos; ENRG: energía
place date ENRG FOOD TOT TOT_FOODENRG
ARG 2023-02 NA 102.62940 102.50080 NA
TUR 2023-02 42.23681 69.33482 55.17983 51.902860
HUN 2023-02 39.45069 45.80613 25.40000 16.207950
LVA 2023-02 46.42958 25.33258 20.26292 10.511360
LTU 2023-02 29.20563 30.18281 18.73836 12.170210
EST 2023-02 30.27698 25.20833 17.54967 12.125680
CZE 2023-02 33.82126 23.91482 16.71949 11.444360
COL 2023-02 18.02995 24.13994 13.27902 10.150170
CHL 2023-02 13.22474 21.43148 11.94660 9.090909
AUT 2023-02 26.51685 16.15970 10.88180 8.612440
Fuente: datos de OCDE

Pongamos banderitas y alguna cosas más

Código
#- data munging
inflation <- inflation_orig %>%
  dplyr::filter(FREQUENCY == "M") %>% 
  dplyr::filter(MEASURE == "AGRWTH") %>% 
  dplyr::mutate(fecha = lubridate::ym(TIME)) %>% 
  select(pais = LOCATION, fecha, inflacion = Value, tipo_inf = SUBJECT)

#- incorporar region para filtrar grupos de países
zz <- countrycode::codelist %>% select(iso.name.en, region, region23, wb, fips, ioc, imf, iso2c, iso3c, ecb, eurostat, continent, eu28, un, un.region.name)

inflation <- left_join(inflation, zz, by = join_by(pais == iso3c) ) 

#- solo Europa (q no sea Europa del Este) --------------------------------------
df <- inflation %>% 
  dplyr::filter(un.region.name %in% c("Europe")) %>% 
  dplyr::filter(!(region23 %in% c("Eastern Europe"))) 

my_title <- "Tasas de inflación interanual en Europa (febrero 2023)"
my_subtitle <- "Países europeos y <span style='color:#3569a4'> España </span> "

#- paso a ancho ----------------------------------------------------------------
df <- df %>% 
  select(pais, iso.name.en, fecha, inflacion, tipo_inf) %>% 
  pivot_wider(names_from = tipo_inf, values_from = inflacion)

#- banderas --------------------------------------------------------------------
df <- df %>% #- fips
  mutate(iso2 = countrycode::countrycode(sourcevar = pais, origin = "iso3c", destination = "iso2c", warn = FALSE)) %>% 
  mutate(iso2 = tolower(iso2)) %>% 
  mutate(flag_URL = glue::glue('https://hatscripts.github.io/circle-flags/flags/{iso2}.svg')) 
  
#- selecciono fecha ------------------------------------------------------------
my_fecha <-  max(inflation$fecha)
my_fecha <-  "2023-02-01"

df <- df %>% dplyr::filter(fecha == my_fecha) 

#- ordeno de + a - la inf. total -----------------------------------------------
df <- df %>% select(1,2, flag_URL, 3, 6, everything()) %>% arrange(desc(TOT), ENRG) %>% select(-iso2)

df <- df %>% mutate(FOOD = FOOD/max(FOOD))

Me he quedado solo con los países de Europa

Código
#- con DT: https://rstudio.github.io/DT/
df_DT <- df %>% select(-flag_URL)
DT::datatable(df_DT, filter = 'top', extensions = "Scroller")
Código
#- con reactable: https://glin.github.io/reactable/index.html
library(reactable)
reactable::reactable(df_DT, pagination = FALSE, height = 850, 
                     filterable = TRUE, searchable = TRUE, highlight = TRUE, 
                     columns = list( variable = colDef(
     # sticky = "left",
      # Add a right border style to visually distinguish the sticky column
      style = list(borderRight = "1px solid #eee"),
      headerStyle = list(borderRight = "1px solid #eee")
    )),
  defaultColDef = colDef(minWidth = 50)
)
Código
tt_6 <- df %>%  
  gt(rowname_col = "pais") %>% 
  tab_header(title = my_title, subtitle = md(my_subtitle))  %>% 
  tab_source_note(md("Fuente: datos proveniente de la [OCDE](http://www.oecd.org/)")) %>%
  gtExtras::gt_theme_nytimes() %>%
  gtExtras::gt_img_rows(flag_URL, height = 25) %>% 
  gtExtras::gt_merge_stack(col2 = iso.name.en, col1 = pais) %>% 
  tab_footnote(footnote = "Tasa de inflación eliminando el efecto de la energía y los alimentos", 
               location = cells_column_labels(columns = TOT_FOODENRG)) %>% 
  cols_label(TOT = md("**Total**"), ENRG = "Energética", FOOD = "Alimentos", TOT_FOODENRG = "Total sin ..." )  %>% 
  cols_align(align = "center") %>% 
  cols_align(align = "left", columns = fecha) %>% 
  cols_width(columns = TOT ~ px(120)) %>% 
  fmt_percent(columns = c(TOT, ENRG, FOOD, TOT_FOODENRG), scale_values = FALSE) %>% 
  tab_style(style = cell_text(color = "#f97d64"),
            locations = cells_body(columns = TOT,
            rows = TOT >= mean(TOT))) %>% 
  tab_style(style = cell_text(color = "#f97d64"),
            locations = cells_body(columns = FOOD,
            rows = FOOD >= mean(FOOD))) %>% 
   tab_style(style = cell_text(color = "#f97d64"),
            locations = cells_body(columns = ENRG,
            rows = ENRG >= mean(ENRG))) %>% 
   tab_style(style = cell_text(color = "#3569a4"),
            locations = cells_body(rows = pais == "ESP")) %>% 
   data_color(columns = c(TOT_FOODENRG),
              colors = scales::col_numeric(palette = "Reds", domain = NULL)) 
  
tt_6  
Tasas de inflación interanual en Europa (febrero 2023)
Países europeos y España
flag_URL fecha Total Energética Alimentos Total sin ...1
LVA
Latvia
2023-02-01 20.26% 46.43% 0.84% 10.51%
LTU
Lithuania
2023-02-01 18.74% 29.21% 1.00% 12.17%
EST
Estonia
2023-02-01 17.55% 30.28% 0.84% 12.13%
AUT
Austria
2023-02-01 10.88% 26.52% 0.54% 8.61%
ISL
Iceland
2023-02-01 10.20% 14.58% 0.40% 9.47%
SVN
Slovenia
2023-02-01 9.28% 6.14% 0.61% 7.67%
ITA
Italy
2023-02-01 9.15% 28.20% 0.44% 4.79%
FIN
Finland
2023-02-01 8.80% 16.83% 0.54% 6.60%
DEU
Germany
2023-02-01 8.68% 19.98% 0.69% 5.86%
IRL
Ireland
2023-02-01 8.46% 29.30% 0.43% 5.56%
PRT
Portugal
2023-02-01 8.25% 1.94% 0.71% 7.21%
NLD
Netherlands (the)
2023-02-01 7.96% −1.07% 0.59% NA
DNK
Denmark
2023-02-01 7.60% 13.97% 0.49% 5.80%
BEL
Belgium
2023-02-01 6.62% −7.93% 0.56% 6.90%
NOR
Norway
2023-02-01 6.30% 12.44% 0.29% 5.60%
FRA
France
2023-02-01 6.28% 13.95% 0.52% 3.57%
GRC
Greece
2023-02-01 6.13% −5.22% 0.49% 6.34%
ESP
Spain
2023-02-01 6.03% −8.87% 0.55% 5.19%
LUX
Luxembourg
2023-02-01 4.31% −1.98% 0.43% 3.63%
CHE
Switzerland
2023-02-01 3.37% 16.65% 0.21% 2.03%
SWE
Sweden
2023-02-01 NA 11.97% 0.69% 10.50%
Fuente: datos proveniente de la OCDE
1 Tasa de inflación eliminando el efecto de la energía y los alimentos


Algún día lo retomaré!!

Reutilizar

https://creativecommons.org/licenses/by/4.0/deed.es
© 2023 Pedro J. Pérez
Hecho con Quarto