class: center, middle .linea-superior[] .linea-inferior[] <img src="imagenes/logo_portada2.png" width="200" /> ## INE Educa: Clases abiertas de R ## R y herramientas de reproducibilidad ## Proyecto Ciencia de Datos ### Julio 2023 --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Bienvenidas y bienvenidos .center[ <img src="imagenes/wordcloud_welcome.jpg" width="550"/> ] --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Estructura del taller ##Contenidos de la clase <br/> -- - I - Motivación -- - II - Introducción -- - III - Rudimentos -- - IV - Introducción a `renv` -- - V - Mis proyectos con `renv` -- - VI - Colaborando con `renv` -- - VII - Comentarios y referencias <br> <br> --- class: inverse, center, middle # I. Motivación --- background-image: url(https://the-turing-way.netlify.app/_images/reproducibility.jpg) background-size: contain --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Motivación <br/> .center[<img src="https://i.giphy.com/media/l0NgQIwNvU9AUuaY0/200w.webp" width=500/>] --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Comentario preliminar .center[ <img src="imagenes/diana.png" width="250" /> ### Público objetivo: orientado a usuarios y usuarias intermedios de R ] -- **Objetivo del taller:** - Presentar herramientas para mejorar la reproducibilidad de nuestros flujos de trabajo .center[**Nota:** mirada desde la **producción de estadísticas oficiales**] .center[**Advertencia:** `renv` podría tener problemas de ejecución en .pur[entornos empresariales]] --- class: inverse, center, middle # II. Introducción --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # ¿Qué es la reproducibilidad? -- <br/> <br/> <br/> <br/> <br/> <br/> .center[.medium-par[Un resultado es .pur[reproducible] cuando los .pur[**mismos pasos**] de análisis realizados en el .pur[**mismo conjunto de datos**] producen consistentemente la .pur[**misma respuesta**]]] --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Reproducibilidad .panelset[ .panel[.panel-name[Su espectro] <br/> <br/> <br/> <img src =https://www.researchgate.net/profile/Arthur_Piazzi/publication/325910795/figure/fig2/AS:640119719620611@1529627842920/Reproducibility-Spectrum.png width="800"/> .center[👁️: compartir los datos no es algo trivial] ] .panel[.panel-name[¿Sus dimensiones?] .center[<img src ="imagenes/repro-repli.JPG" width="600"/>] ] ] --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Importancia de la reproducibilidad -- <br/> Que .pur[otra persona] (o .pur[mi yo del futuro]) pueda ejecutar mi rutina nuevamente de forma exitosa. -- <br/> <br/> .center[.big-par[**¿Qué puede salir mal?** ⚰️]] -- <br/> .center[ <img src= "https://media1.giphy.com/media/jM6JLt7xHkZxaeHwhG/200w.webp?cid=ecf05e478x4ytanztrx22si2y7ibrgekn371tgscimf4bemf&rid=200w.webp" width="400"/> ] --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # 10 years reproducibility challenge -- .pull-left[ <img src="imagenes/ten-years1.JPG" width="600"/> <br/> <img src="imagenes/ten-years3.JPG" width="300"/> ] -- .pull-rigth[ <br/> <br/> <img src="imagenes/ten-years2.png" width="300"/> ] --- class: inverse, center, middle # III. Rudimentos --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # El principio: Consola de R -- <br/> .medium-par[Utilidades:] -- Me permite explorar objetos rápidamente con código residual -- .medium-par[**Desventajas:**] - Es más complejo desplazarse por distintas líneas de código -- - No está hecha para almacenar rutinas -- .medium-par[¿Puedo recuperar el código escrito en consola?] -- - La verdad es que sí... a través del log de la sesión ("History"), pero es engorroso. -- .medium-par[.pur[Primer upgrade]: **script**] -- El **script** me permite almacenar extensas rutinas de código --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Veamos un ejemplo -- **Pueden descargar los datos entrando** 👉 [aquí](https://github.com/clases-r-topicos/reproducibilidad/raw/master/data/casen_2020_small.dta) <img src="reproducibilidad_files/figure-html/unnamed-chunk-1-1.png" style="display: block; margin: auto;" /> --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Veamos un ejemplo ```r library(dplyr) library(ggplot2) library(haven) # tabla de casen 2020 con selección de variables *casen2020 = read_dta("C:/Users/Adm-Ignacio/Documents/Proyectos/clases-abiertas-r/reproducibilidad/data/casen_2020_small.dta") # construcción de variabe de resumen de pobreza casen2020 = casen2020 %>% mutate(pobreza2 = case_when(pobreza == 1 ~ 1, pobreza == 2 ~ 1, pobreza == 3 ~ 0, is.na(pobreza) ~ 0)) %>% select(region, pobreza2, expr) # Preparar datos para visualización tabla = casen2020 %>% group_by(region) %>% summarise(pob_tot = sum(expr), pobres = sum(pobreza2 * expr), por_pob = round((pobres / pob_tot) * 100,1)) %>% select(-pob_tot, -pobres) # Plot de personas pobres según región ggplot(data = tabla, aes(x = as.factor(region), y = por_pob)) + geom_bar(stat = "identity", fill = "orange") + geom_text(aes(label= por_pob, vjust=0)) + geom_hline(aes(yintercept = mean(por_pob))) + labs(title="Porcentaje de personas pobres por región en Casen 2020", x ="Región numérica", y = "Porcentaje") + theme(plot.title = element_text(hjust = 0.5)) ``` .center[.medium-par[¿Qué .pur[obstáculos] a la reproducibilidad podemos observar?]] --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Primeros obstáculos -- <br/> .pull-left[ <img src = "https://media0.giphy.com/media/3o6MbhOHfhpOhctaWk/200.webp?cid=ecf05e47brnypsfat6raaiaje2v7saby2wiyahj8cq84eqzr&ep=v1_gifs_search&rid=200.webp&ct=g" width="350" />] -- .pull-right[ - Estoy usando una **ruta absoluta** a los datos - rutas absolutas - Son propias de mi computador - Son engorrosas de escribir - rutas relativas - 👌 ] -- .center[.medium-par[.pur[Segundo upgrade:] **Proyectos de R**]] -- .center[.medium-par[¿Cómo creamos un proyecto?]] --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Ventajas de los proyectos -- <br/> - **Organización y gestión:** - Organización de archivos y recursos relacionados - Estructura clara y fácil acceso a los recursos del proyecto -- - **Reproducibilidad y control:** - Facilita la reproducibilidad de los resultados -- - **Ambiente de trabajo:** - Creación de un entorno aislado para cada proyecto -- - **Colaboración:** - Facilidad para compartir y trabajar en equipo - rutas relativas -> mayor portabilidad y flexibilidad --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Mención especial 👩🎓 / .pur[Upgrade 2.1] .panelset[ .panel[.panel-name[¿Qué es?] .pull-left[ <br/> <br/> <img src= "imagenes/rmarkdown-logo.png" width=200/> ] .pull-rigth[ - RMarkdown es una versión de Markdown - Es un .pur[lenguaje de marcado ligero] - Permite incorporar código y resultados en un mismo ambiente (`knitr`) - Es posible usar `\(LaTex\)` dentro de RMarkdown - Se puede automatizar la generación de documentos en html y pdf - Muy útil para la reproducibilidad en el .pur[ámbito científico] ] .panel[.panel-name[¿Qué contiene?] .center[<img src = "imagenes/captura-rmarkdown.JPG" width=650/>] ] .panel[.panel-name[¿Cómo se ve?] .center[<img src = "imagenes/compilado_rmarkdown.JPG" width=650/>] ] .panel[.panel-name[Algunos ejemplos] **Documentos:** [Cálculo de medidas de precisión para medianas de ingreso y gasto de la VIII EPF](https://www.ine.gob.cl/docs/default-source/documentos-de-trabajo/c%C3%A1lculo-de-medidas-de-precisi%C3%B3n-para-medianas-de-ingreso-y-gasto-de-la-v.pdf?sfvrsn=e5b6a7b3_2) [Métodos de Imputación VIII EPF: Gastos diarios e ingresos de la actividad laboral y jubilaciones](https://www.ine.gob.cl/docs/default-source/documentos-de-trabajo/190320-documento-imputacion-viii-epf.pdf?sfvrsn=668a66c0_2) **Boletines IPC e IPP:** .center[ .pull-left[ <img src= "imagenes/ipc.JPG" width=200/> ] .pull-rigth[ <img src= "imagenes/ipp.JPG" width=200/>] ] ] ] ] --- class: inverse, center, middle # IV. Introducción a `renv` --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Resumen de upgrades -- <br/> .medium-par[.pur[Primer upgrade:] **script**] -- .medium-par[.pur[Segundo upgrade:] **proyectos**] -- .pur[Upgrade 2.1:] **`rmarkdown`** -- .medium-par[.pur[Tercer upgrade:] **`renv`**] --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Ejemplo práctico -- **Descarga los siguientes datos** 👉 [aquí](https://github.com/clases-r-topicos/reproducibilidad/raw/master/data/tabla_ejemplo.xlsx) -- Y copia el siguiente código en R: ```r library(dplyr) library(ggplot2) library(haven) library(readxl) # cargar datos df = read_excel("data/tabla_ejemplo.xlsx") # crear tabla de resumen tabla = df %>% group_by(sexo) %>% summarise(time = mean(tiempo)) # plot de tiempo según sexo ggplot(data= tabla, aes(x = sexo, y = time)) + geom_bar(stat = "identity", fill = "blue") + geom_text(aes(label= time, vjust=0)) + labs(title="Tiempo promedio según sexo", x ="Sexo", y = "Tiempo promedio") + theme(plot.title = element_text(hjust = 0.5)) ``` ```r # packageVersion("readxl") ``` --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Ejemplo práctico -- <br/> Me aparece el siguiente **error**: -- <img src = "imagenes/error-readxl.JPG" width=800/> -- Podemos preguntar a R la versión que tengo de `readxl` con `packageVersion("readxl")` -- <img src = "imagenes/version-readxl.JPG" width=800/> -- La versión más actual disponible de `readxl` es la 1.4.3 --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # ¿Qué es `renv`? -- <br/> .center[<img src ="https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExNzVsMnoyaGpmeThieWw0YTB6c3d3YWVlbHdqZXR5ZzIwaTlicWtpbyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/ctWSqhTv0LXd6/giphy.gif" width=300/>] -- Es un .pur[gestor de dependencias] locales de `R` -- Es el sucesor del paquete `packrat` -- Busca ofrecer la posibilidad de .pur[guardar] y .pur[restaurar] el estado de la **configuración** de un proyecto en un momento determinado. --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Crear un entorno con renv -- Primero que todo ```r install.packages("renv") ``` -- Luego hay dos opciones: -- .pull-left[ - Al crear un proyecto le indicamos que queremos usar renv vía cuadro de diálogo <img src="imagenes/crear-renv.JPG" width="300" /> ] -- .pull-right[ - Si queremos iniciar un renv por consola o en un proyecto ya existente ```r renv::init() ``` ] -- .center[Esto creará la .pur[infraestructura] de renv en el proyecto] --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Crear un entorno con renv .panelset[ .panel[.panel-name[¿Qué vemos?] <br/> .center[<img src="imagenes/renv-init.png" width=400/>] ] .panel[.panel-name[¿Qué hemos creado?] <br/> .pur[.Rprofile:] es un archivo que ejecuta RStudio cada vez que se carga una sesión. Este archivo llama a `renv/activate.R` file .pur[renv/.gitignore:] le dice a Git que **ignore**, entre otros, la carpeta de la biblioteca, ya que contiene dependencias que pueden ser de gran tamaño .pur[renv/activate.R:] archivo que activa el entorno local .pur[renv/library/*:] carpeta que contiene las dependencias del proyecto .pur[renv.lock:] archivo que describe el **estado de la librería de proyecto** en un momento determinado ] ] --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Biblioteca privada -- <br/> Cuando le pregunto a `R` donde están las librerías fuera de `renv` veo algo así: -- ```r .libPaths() ``` <img src = "imagenes/libpaths.JPG" width = 800/> -- Cuando estoy dentro de un ambiente virtual, estoy parado en otro lugar: (**Nota:** las rutas que verás probablemente serán direfentes a estas) -- ```r .libPaths() ``` ``` ## [1] "C:/Users/Adm-Ignacio/Documents/Proyectos/clases-abiertas-r/reproducibilidad/renv/library/R-4.3/x86_64-w64-mingw32" ## [2] "C:/Users/Adm-Ignacio/AppData/Local/R/cache/R/renv/sandbox/R-4.3/x86_64-w64-mingw32/e9e85620" ``` -- 👀 Esta clase está hecha en un proyecto de `R` y tiene su propio ambiente virtual --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Flujo de trabajo con `renv` -- <br/> <br/> `renv::init()`: inicia un nuevo ambiente local de proyecto con una librería de R privada -- `renv::snapshot()`: guarda una "foto" del estado de la librería de proyecto en el `lock.file` -- `renv::restore()`: restaura el estado de un proyecto desde un `renv.lock` -- Cuando estoy en un proyecto con un `renv` ya creado: ```r renv::activate() # para activar renv::deactivate() # para desactivar ``` --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # ¿Cómo funciona `renv`? .panelset[ .panel[.panel-name[Inicio] `renv::init()` crea la infraestructura de un ambiente virtual. Si el proyecto ya existía, .pur[rastrea] y .pur[registra] todas las dependencias en uso Si la dependencia ya existe en la carpeta de usuario, la tomará desde ahí y no de CRAN Si prefieres partir de una librería privada vacía y tú poblarla: ```r renv::init(bare = TRUE) ``` 👀 Lo que gatilla el guardado es que en algún script del proyecto haya un `library(paquete)`. Eso le indica a `renv` que se trata de una .pur[dependencia] del ambiente. ] .panel[.panel-name[General] <br/> .center[<img src ="imagenes/esquema-renv.JPG" width=600/>] ] .panel[.panel-name[Cache] `renv` utiliza un cache de paquetes global compartido por todos los proyectos De este modo las llamadas a `renv::restore()` y `renv::install()` serán más rápidas Esto permite ahorrar .pur[espacio en memoria] al evitar la **duplicidad** .medium-par[enlaces simbólicos o puntos de unión] ] ] --- class: inverse, center, middle # V. Mis proyectos con `renv` --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Mis proyectos con `renv` -- .medium-par[Ejemplo práctico] ```r library(dplyr) library(ggplot2) library(haven) # tabla de casen 2020 con selección de variables casen2020 = read_dta("data/casen_2020_small.dta") # construcción de variabe de resumen de pobreza casen2020 = casen2020 %>% mutate(pobreza2 = case_when(pobreza == 1 ~ 1, pobreza == 2 ~ 1, pobreza == 3 ~ 0, is.na(pobreza) ~ 0)) %>% select(region, pobreza2, expr) # Preparar datos para visualización tabla = casen2020 %>% group_by(region) %>% summarise(pob_tot = sum(expr), pobres = sum(pobreza2 * expr), por_pob = round((pobres / pob_tot) * 100,1)) %>% select(-pob_tot, -pobres) # Plot de personas pobres según región ggplot(data = tabla, aes(x = as.factor(region), y = por_pob)) + geom_bar(stat = "identity", fill = "orange") + geom_text(aes(label= por_pob, vjust=0)) + geom_hline(aes(yintercept = mean(por_pob))) + labs(title="Porcentaje de personas pobres por región en Casen 2020", x ="Región numérica", y = "Porcentaje") + theme(plot.title = element_text(hjust = 0.5)) ``` --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Mis proyectos con `renv` -- .medium-par[Ejemplo práctico] -- .center[<img src ="https://media4.giphy.com/media/9S706ievhjXVfG9s9Q/200w.webp?cid=ecf05e478scjupy2qkpn26qs1t87n973fiesdjl7ff2daxx6&ep=v1_gifs_search&rid=200w.webp&ct=g" width=450/>] --- class: inverse, center, middle # VI. Colaborando con `renv` --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Colaborando con `renv` -- <br/> .medium-par[Ejemplo práctico] -- Clona el siguiente repositorio: https://github.com/ignacioagloni/ejemplo-renv-git.git -- .center[<img src ="https://media0.giphy.com/media/l36kU80xPf0ojG0Erg/200w.webp?cid=ecf05e4797shbz9ansita0qvuy9l050drrpqlusnjl0huz78&ep=v1_gifs_search&rid=200w.webp&ct=g" width=600/>] --- class: inverse, center, middle # VII. Comentarios y referencias --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Qué NO soluciona `renv` <br/> -- .medium-par[`renv` no es la .pur[panacea] de la reproducibilidad, es una herramienta más.] -- `renv` NO ayuda con la versión de `R`, porque se ejecuta dentro de `R` -- `pandoc` vive fuera del paquete `rmarkdown` -- Si un paquete ya no está disponible para descarga, `renv` no lo puede restaurar. -- Para obtener una "imagen" estable se requiere considerar también .pur[sistema operativo] y .pur[aplicaciones del sistema] --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # También existe `Docker` .pull-left[ <img src="imagenes/docker-logo.png" width=300 /> ] .pull-right[ Plataforma de **código abierto** Ejecución de aplicaciones en **contenedores** **Encapsulan** una aplicación y todas ssu dependencias **Mismo comportamiento en diferentes entornos**: maquinas locales, servidores físicos, en nube, etc. ] .center[ .pur[Portabilidad y consistencia Eficiencia en recursos Despliegue rápido Escalabilidad Aislamiento y seguridad] ] --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Resumen y un poco más: -- No sé si estoy aplicando la misma rutina 👉 .medium-par[.pur[script]] -- No sé si estoy usando los mismos datos 👉 .medium-par[.pur[script]] -- Rutas a archivos que son incorrectas 👉 .medium-par[.pur[proyectos]] -- Aleatoriedad no reproducible 👉 .medium-par[.pur[set.seed()]], entre otros -- Comentarios escuetos en el código 👉 .medium-par[.pur[🧐 (estilo de código)]] -- Variables no localizadas (no creadas en la rutina) 👉 .medium-par[.pur[RMarkdown]] -- Diferentes versiones de los paquetes 👉 .medium-par[🌱] -- Diferente versión de *software* o sistema operativo 👉 .medium-par[🐳] --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Caja de herramientas -- <br/> .center[<img src= "imagenes/logos-repro.JPG" width=800/>] --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Reflexión final: -- <br/> ## Ponderar cada caso -- .pull-center[ <img src="imagenes/its-fine.JPG" width=700 /> ] --- background-image: url("imagenes/fondo2.PNG") background-size: contain; background-position: 100% 0% # Referencias .medium-par[Nada de esto sería posible sin:] - [Florencia D'Andrea - meetup de R-Ladies Buenos Aire](https://rladiesba.netlify.app/project/charlar8/) - [Ciencia Social Abierta - Prof. Juan Carlos Castillo](https://cienciasocialabierta.netlify.app/) - [Introducción a renv package](https://rstudio.github.io/renv/articles/renv.html) - [Guía para la reproducibilidad en investigación - The Turing Project](https://the-turing-way.netlify.app/welcome.html) - [Xaringan: Presentation Ninja, de Yihui Xie](https://github.com/yihui/xaringan). Para generar esta presentación con la plantilla ninja ⚔ - [Advanced R, de Hadley Wickham](http://adv-r.had.co.nz/Introduction.html) - [Healy, Kieran. 2018. The Plain Person’s Guide to Plain Text Social Science](https://plain-text.co/) .medium-par[R for Data Science tiene una traducción al español realizada por la comunidad hispana de R:] - [R para ciencia de datos, de Hadley Wickham](https://es.r4ds.hadley.nz/) --- class: center, middle .linea-superior[] .linea-inferior[] <img src="imagenes/logo_portada2.png" width="200" /> ## INE Educa: Clases abiertas de R ## R y herramientas de reproducibilidad ## Proyecto Ciencia de Datos ### Julio 2023