R Para Ciencia de Datos: Cómo hacer ciencia de datos con R en español

¿Por qué traducir este libro?

‘R for Data Science’ es un libro práctico utilizado por muchos para aprender los fundamentos del lenguaje R. Sin embargo, muchos hispanohablantes tienen dificultades para utilizar este libro como recurso debido a la barrera del idioma inglés.

Me gusta mucho haber trabajado con mi amiga y colega Riva Quiroga, quien me invitó a trabajar con ella, Edgar Ruiz y otros, para abordar esta brecha de accesibilidad y han creado ‘R Para Ciencia de Datos’. Como ella mencionó durante su charla en rstudio::conf 2020, destaca que iniciativas como ésta no son sólo software, sino herramientas para hacer más fuerte a la comunidad.

En el caso de Chile, un curso de inglés de nivel elemental cuesta alrededor de 500 USD/mes, mientras que el salario mínimo es de 350 USD/mes y el medio es de alrededor de 550 USD/mes, según los últimos informes del Instituto Nacional de Estadísticas (INE Chile). En lugar de hacer recaer el peso del aprendizaje del inglés en el alumno, como líderes de la comunidad y educadores podemos actuar para reducir las barreras idiomáticas con soluciones sociales y tecnológicas.

Además, creamos el paquete de R ‘datos’ para traducir automáticamente datasets del inglés al español utilizando herramientas computacionales ya existentes en el ecosistema de R. Juntos, el libro ‘R Para Ciencia de Datos’ y el paquete ‘datos’ permiten a los hispanohablantes gastar su energía no en entender el inglés sino en aprender ciencia de datos en R.

¿Qué lección aprendí después de completar este proceso?

Me alegró mucho trabajar con personas de diferentes países y darme cuenta de que teníamos que aplicar diferentes convenciones para poder escribir en español neutro (¿existe?) y conseguir traducir todos los capítulos del libro.

Mi papel en esto fue traducir los capítulos 2, 3, 12, 13, 28, volver a dibujar y traducir los diagramas para el libro completo y ser el “guardián” del repositorio.

La lección principal es: ¡Respeta la diversidad! La diversidad, como siempre insisto, es algo más que un conjunto de tuits bellamente escritos. El resto consiste en crear la “caja de arena” adecuada para evitar que la gente borre ramas o empuje a la rama principal de traducción sin un PR revisado por pares, y darles cada vez más libertad a medida que aprenden a utilizar las diferentes funcionalidades de GitHub (¡algo que no es trivial aprender!).

¿Puedo medir mi contribución al proyecto?

Sí, aquí hay un análisis de los 112 PRs fusionados durante el proyecto. Este análisis no incluye las contribuciones de Edgar Ruiz porque él contribuyó a la traducción de conjuntos de datos y no a la traducción de capítulos directamente.

Para el análisis empecé por los paquetes necesarios para leer el historial de GitHub.

library(gh)
library(purrr)
library(glue)
library(readr)
library(dplyr)
library(lubridate)
library(stringr)
library(ggplot2)

Luego definí qué repositorio leer y una función para obtener la información relevante para un análisis elemental.

user <- "cienciadedatos"
repo <- "r4ds"
limit <- 500

get_prs <- function() {
  res  <- gh(
    "/repos/{user}/{repo}/pulls?state=all",
    user = user, repo = repo, page = page, per_page = limit,
    .token = Sys.getenv("GITHUB_TOKEN"), .limit = limit
  )

  author <- res %>%
    map_chr(~ .x$user$login)

  created <- res %>%
    map_chr(~ .x$created_at)

  state <- res %>%
    map_chr(~ .x$state)

  return(
    tibble(
      author = author,
      created = created,
      state = state
    )
  )
}

Capturé los datos una vez, y luego los leí muchas veces hasta que pulí mis gráficos.

prs_rds <- "~/github/r4ds-es-analysis/prs.rds"

if (!file.exists(prs_rds)) {
  prs <- get_prs()
  saveRDS(prs, prs_rds)
} else {
  prs <- readRDS(prs_rds)
}

Por último, hice los gráficos utilizando los colores de Pokemon. Encontré muchos empates para el 3er, 4to y 5to puesto en el ranking de contribuciones.

cols <- c("#78c850", "#f08030", "#6890f0", "#a8b820", "#a8a878",
          "#a040a0", "#f8d030", "#e0c068", "#ee99ac", "#c03028",
          "#f85888", "#b8a038", "#705898", "#98d8d8", "#7038f8")

prs2 <- prs %>%
  filter(state == "closed") %>%
  mutate(
    created = as_datetime(created),
    month = paste(year(created), 
                   str_pad(month(created), 2, "left", "0"),
                   sep = "-")
  )

prs2 %>%
  group_by(month) %>%
  count() %>%
  ungroup() %>%
  mutate(y = cumsum(n)) %>%
  ggplot() +
  geom_col(aes(x = month, y = y)) +
  labs(x = "Mes", y = "Cant. de PRs",
       title = "PRs fusionadas por mes") +
  theme_minimal(base_size = 10, base_family = "Source Sans Pro") +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1))

prs2_top <- prs2 %>%
  group_by(author) %>%
  count(sort = T) %>%
  ungroup() %>%
  mutate(rank = dense_rank(desc(n))) %>%
  arrange(rank)

prs2 %>%
  inner_join(
    prs2_top %>% filter(rank <= 5)
  ) %>%
  group_by(month, author) %>%
  count() %>%
  group_by(author) %>%
  mutate(y = cumsum(n)) %>%
  ggplot() +
  geom_col(aes(x = month, y = y, fill = author)) +
  scale_fill_manual(values = cols) +
  labs(x = "Mes", y = "Cant. de PRs",
       title = "PRs fusionadas por mes para los contribuyentes top 5") +
  theme_minimal(base_size = 10, base_family = "Source Sans Pro") +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1))

prs2 %>%
  inner_join(
    prs2_top %>% filter(rank > 5)
  ) %>%
  group_by(month, author) %>%
  count() %>%
  group_by(author) %>%
  mutate(y = cumsum(n)) %>%
  ggplot() +
  geom_col(aes(x = month, y = y, fill = author)) +
  scale_fill_manual(values = cols) +
  labs(x = "Mes", y = "Cant. de PRs",
       title = "PRs fusionadas por mes para los contribuyentes no top 5") +
  theme_minimal(base_size = 10, base_family = "Source Sans Pro")

¡Me alegro de ocupar el segundo puesto en la clasificación de las contribuciones!

¿Cómo puedo utilizar la traducción al español para traducirla a otro idioma?

La infraestructura de ‘R4DS en español’ motivó la creación de R4DS en portugués. En la organización GitHub Ciencia de Datos, tenemos los siguientes recursos disponibles:

  • R4DS en español: Traducción del libro. Vea la rama ‘traduccion’, ‘main’ se mantiene intacta para facilitar la sincronización con la versión original.
  • Datos: Traducción de los datasets en español.
  • Dados: Traducción de los datasets en portugués.

El repositorio R4DS-ES también contiene un redibujado de todos los diagramas en formato SVG para ser editados con Inkscape independientemente del sistema operativo que se utilice. Los diagramas se proporcionan tanto en inglés como en español. El libro en sí es un proyecto estándar de “bookdown” en R.

El paquete ‘datos’ hace uso de las especificaciones YAML para traducir automáticamente datasets originalmente disponibles en otros paquetes de R. Los datos traducidos pueden utilizarse junto con el libro R4DS o de forma independiente como fuente de datos prácticos en español. La especificación YAML para cada conjunto de datos que proporciona el nombre del conjunto de datos, cómo se desea traducir las variables, y la descripción para la documentación. Este proceso no sólo consigue traducir el dataset, sino también la página de ayuda para el dataset, que es muy útil para las personas que están aprendiendo. ‘Datos’ traduce los conjuntos de datos sobre la marcha, gracias a delayedAssign() de R base, por lo que los datasets no están en el paquete, ya que sólo contiene archivos YAML con especificaciones de traducción y funciones que traducen los datasets llamados desde otros paquetes.

Como ejemplo, inspeccionemos las primeras filas de la tabla de aerolíneas de ‘nycflights13’. Este datasets tiene dos columnas ‘carrier’ y ‘name’, que proporcionan una abreviatura de dos letras y el nombre completo de la aerolínea.

head(nycflights13::airlines)

## # A tibble: 6 x 2
##   carrier name                    
##   <chr>   <chr>                   
## 1 9E      Endeavor Air Inc.       
## 2 AA      American Airlines Inc.  
## 3 AS      Alaska Airlines Inc.    
## 4 B6      JetBlue Airways         
## 5 DL      Delta Air Lines Inc.    
## 6 EV      ExpressJet Airlines Inc.

Esta es la especificación de la tabla de aerolíneas de ‘nycflights13’. Aquí, proporcionamos tanto una traducción (trans:) como una descripción (desc:) en español, así como información adicional útil.

df:
  source: nycflights13::airlines
  name: aerolineas
variables:
  carrier:
    trans: aerolinea
    desc: "abreviaci\u00f3n de dos caracteres del nombre de la
     aerol\u00EDnea"
  name:
    trans: nombre
    desc: "nombre completo de la aerol\u00EDnea"
help:
  name: aerolineas
  alias: aerolineas
  title: "Nombres de aerol\u00EDneas"
  description: "Nombres de aerol\u00EDneas y su respectivo c\u00f3digo
   carrier de dos d\u00EDgitos."
  usage: aerolineas
  format: Un data.frame con 16 filas y 2 columnas