Novedades en {tidyr} 2023

R-Ladies Chile

Sara Acevedo

Hola!

saryace | Saryace | saryace.github.io

  • Sara Acevedo
  • Doctora Cs. Ingeniería UC, Magíster UC-Davis
  • Usuaria de R hace años 👩‍💻

Taller de tidyr

En esta taller:

  • Repasaremos las principales herramientas de tidyr
  • Revisaremos las funciones más usadas
  • Revisar los principales cambios

Código y materiales

Las presentaciones contienen código real (se puede copiar y pegar directamente). El repositorio contendrá el material y contenido de cada clase

1 + 1 # copia y pega en la consola
[1] 2

El repositorio lo puedes encontrar acá:

Repositorio en github

Funciones para ordenar datos tidyr::

  • Objetivo: datos tidy rectangulares
  • Cada variable forma su propia columna
  • Cada observación forma una fila
  • Y cada celda es un único valor

Funciones para ordenar datos tidyr::

tidy data Más info en R4DS tidy data

Operaciones de tidyr

Las funciones de tidyr se dividen en cinco categorías principales:

  • “Pivotar”, que convierte entre formatos anchos y largos.
  • “Rectangling”, que convierte las listas anidadas en tibbles.
  • “anidación” que convierte los datos donde cada grupo se convierte en una única fila que contiene un marco de datos anidado
  • Dividir y combinar columnas de caracteres
  • “missing implicitos”

Como usar el paquete

library(tidyverse)
library(tidyr)
#| eval: false
help(mean) # ver documentación

Cosas nuevas de la versión 1.3

  • Una nueva familia de funciones separate_*() sustituye a separate() y extract() e incorpora útiles funciones de debug

  • unnest_wider() y unnest_longer() son mejorados

  • pivot_longer() obtiene un nuevo argumento cols_vary.

  • nest(.by) proporciona una nueva (y esperemos que definitiva) forma de crear conjuntos de datos anidados.

Mejoras a separate_*()

Crea columnas Crea filas
Separa por delim separate_wider_delim() separate_longer_delim()
Separa por posición separate_wider_position() separate_longer_position()
Separa por regex separate_wider_regex()

Separate clásico

library(tidyverse)
info_nombres <- tibble(nombres = c("maria-jose", "ema-paz", "sofia-ester"))

info_nombres %>% 
  separate(nombres, into = c("primer_nombre", "segundo_nombre"), sep = "-")
# A tibble: 3 × 2
  primer_nombre segundo_nombre
  <chr>         <chr>         
1 maria         jose          
2 ema           paz           
3 sofia         ester         

separate_*_delim()

info_nombres %>% 
  separate_wider_delim(nombres, names = c("primer_nombre", "segundo_nombre"), delim = "-")
# A tibble: 3 × 2
  primer_nombre segundo_nombre
  <chr>         <chr>         
1 maria         jose          
2 ema           paz           
3 sofia         ester         
info_nombres %>% 
  separate_longer_delim(nombres, delim = "-")
# A tibble: 6 × 1
  nombres
  <chr>  
1 maria  
2 jose   
3 ema    
4 paz    
5 sofia  
6 ester  

separate_*_position()

info_deptos <- tibble(deptos = c("P3D2", "P4D6", "P4D1"))

info_deptos %>% 
  separate_wider_position(deptos, widths = c(piso = 2, numero = 2))
# A tibble: 3 × 2
  piso  numero
  <chr> <chr> 
1 P3    D2    
2 P4    D6    
3 P4    D1    
info_deptos %>% 
  separate_longer_position(deptos, width = 2)
# A tibble: 6 × 1
  deptos
  <chr> 
1 P3    
2 D2    
3 P4    
4 D6    
5 P4    
6 D1    

separate_wider_regex()

info_deptos %>%
separate_wider_regex(deptos, ...)

Ver vídeo de expresiones regulares de RladiesChile

Mejoras unnest_*(): primero veamos nest()

info_mascota <- tribble(
  ~mascota,  ~estado,  ~info,
  "gato", "sano",list(nombre = "isi", edad = 2, vacunas = c("a")),
  "gato", "enfermo", list(nombre = "oso", edad = 10, vacunas = c("a","b")),
  "perro","sano",list(nombre = "cuchi", edad = 6, vacunas = c("c"))
)

info_mascota
# A tibble: 3 × 3
  mascota estado  info            
  <chr>   <chr>   <list>          
1 gato    sano    <named list [3]>
2 gato    enfermo <named list [3]>
3 perro   sano    <named list [3]>

Mejoras unnest_*(): primero veamos nest()

info_mascota %>% 
  unnest()
# A tibble: 9 × 3
  mascota estado  info        
  <chr>   <chr>   <named list>
1 gato    sano    <chr [1]>   
2 gato    sano    <dbl [1]>   
3 gato    sano    <chr [1]>   
4 gato    enfermo <chr [1]>   
5 gato    enfermo <dbl [1]>   
6 gato    enfermo <chr [2]>   
7 perro   sano    <chr [1]>   
8 perro   sano    <dbl [1]>   
9 perro   sano    <chr [1]>   

Mejoras unnest_*()

info_mascota %>% 
 unnest_wider(info, names_sep = "_")
# A tibble: 3 × 5
  mascota estado  info_nombre info_edad info_vacunas
  <chr>   <chr>   <chr>           <dbl> <list>      
1 gato    sano    isi                 2 <chr [1]>   
2 gato    enfermo oso                10 <chr [2]>   
3 perro   sano    cuchi               6 <chr [1]>   

Mejoras unnest_*()

info_mascota %>% 
 unnest_longer(info)
# A tibble: 9 × 4
  mascota estado  info         info_id
  <chr>   <chr>   <named list> <chr>  
1 gato    sano    <chr [1]>    nombre 
2 gato    sano    <dbl [1]>    edad   
3 gato    sano    <chr [1]>    vacunas
4 gato    enfermo <chr [1]>    nombre 
5 gato    enfermo <dbl [1]>    edad   
6 gato    enfermo <chr [2]>    vacunas
7 perro   sano    <chr [1]>    nombre 
8 perro   sano    <dbl [1]>    edad   
9 perro   sano    <chr [1]>    vacunas

Pivotear

  • Con el formato long podemos graficar y hacer operaciones por grupos
  • Con el formato wide comparamos columnas
  • tidyexplain

pivot_longer()

mis_gatos <- tibble(nombre = c("cuchito", "minino", 
                                     "bigotito"),
                    color = c("negro", "blanco",
                                "atigrado"),
                    "personalidad" = c("arisco","amoroso", "amoroso"))
mis_gatos
# A tibble: 3 × 3
  nombre   color    personalidad
  <chr>    <chr>    <chr>       
1 cuchito  negro    arisco      
2 minino   blanco   amoroso     
3 bigotito atigrado amoroso     

pivot_longer()

mis_gatos %>% 
  pivot_longer(everything(),
               names_to = "caracteristicas_gato",
               values_to = "caracteristica") 
# A tibble: 9 × 2
  caracteristicas_gato caracteristica
  <chr>                <chr>         
1 nombre               cuchito       
2 color                negro         
3 personalidad         arisco        
4 nombre               minino        
5 color                blanco        
6 personalidad         amoroso       
7 nombre               bigotito      
8 color                atigrado      
9 personalidad         amoroso       

Mejora pivot_longer()

mis_gatos %>% 
  pivot_longer(everything(),
               names_to = "caracteristicas_gato",
               values_to = "caracteristica",
               cols_vary = "slowest") 
# A tibble: 9 × 2
  caracteristicas_gato caracteristica
  <chr>                <chr>         
1 nombre               cuchito       
2 nombre               minino        
3 nombre               bigotito      
4 color                negro         
5 color                blanco        
6 color                atigrado      
7 personalidad         arisco        
8 personalidad         amoroso       
9 personalidad         amoroso       

nest()

info_mascota
# A tibble: 3 × 3
  mascota estado  info            
  <chr>   <chr>   <list>          
1 gato    sano    <named list [3]>
2 gato    enfermo <named list [3]>
3 perro   sano    <named list [3]>
info_mascota %>% 
  nest()
# A tibble: 1 × 1
  data            
  <list>          
1 <tibble [3 × 3]>

nest()

info_mascota
# A tibble: 3 × 3
  mascota estado  info            
  <chr>   <chr>   <list>          
1 gato    sano    <named list [3]>
2 gato    enfermo <named list [3]>
3 perro   sano    <named list [3]>
info_mascota %>% 
  group_by(mascota) %>% 
  nest()
# A tibble: 2 × 2
# Groups:   mascota [2]
  mascota data            
  <chr>   <list>          
1 gato    <tibble [2 × 2]>
2 perro   <tibble [1 × 2]>

Mejora nest: nest(.by)

info_mascota %>% 
  nest(.by = mascota)
# A tibble: 2 × 2
  mascota data            
  <chr>   <list>          
1 gato    <tibble [2 × 2]>
2 perro   <tibble [1 × 2]>
info_mascota %>% 
  nest(.by = estado)
# A tibble: 2 × 2
  estado  data            
  <chr>   <list>          
1 sano    <tibble [2 × 2]>
2 enfermo <tibble [1 × 2]>

Mucha información nueva por hoy 🧠 🔥