class: center, middle, inverse, title-slide <style type="text/css"> .remark-slide table{ border: none } .remark-slide-table { } tr:first-child { border-top: none; } tr:last-child { border-bottom: none; } </style> <style type="text/css"> /* THIS IS A CSS CHUNK - THIS IS A COMMENT */ /* Size of font in code echo. E.g. 10px or 50% */ .remark-code { font-size: 70%; } /* Size of font in text */ .medium-text { font-size: 75%; } /* Size of font in tables */ .small-table table { font-size: 6px; } .medium-table table { font-size: 8px; } .medium-large-table table { font-size: 10px; } .medium-large-table2 table { font-size: 11px; } .small-code .remark-code{ font-size: 40% } </style> # Introducción a R para </br> Epidemiología Aplicada ### Caso práctico de ébola y limpieza de datos [contact@appliedepi.org](mailto:contact@appliedepi.org) --- # Objetivos y calendario - Crear un nuevo proyecto de RStudio para el caso práctico de ébola - Leer o importar los datos de una subcarpeta del proyecto utilizando `import()` y `here()` - Familiarizarte con funciones de limpieza de datos {dplyr} - Empezar a escribir un comando de limpieza utilizando el operador 'pipe' `%>%` </br> <div class="tabwid"><style>.cl-ec1f483a{}.cl-ec1b67b0{font-family:'Helvetica';font-size:11pt;font-weight:normal;font-style:normal;text-decoration:none;color:rgba(0, 0, 0, 1.00);background-color:transparent;}.cl-ec1cf4a4{margin:0;text-align:left;border-bottom: 0 solid rgba(0, 0, 0, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);padding-bottom:5pt;padding-top:5pt;padding-left:5pt;padding-right:5pt;line-height: 1;background-color:transparent;}.cl-ec1d06ba{width:1.033in;background-color:transparent;vertical-align: middle;border-bottom: 1.5pt solid rgba(102, 102, 102, 1.00);border-top: 1.5pt solid rgba(102, 102, 102, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-ec1d06d8{width:2.825in;background-color:transparent;vertical-align: middle;border-bottom: 1.5pt solid rgba(102, 102, 102, 1.00);border-top: 1.5pt solid rgba(102, 102, 102, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-ec1d06e2{width:1.033in;background-color:transparent;vertical-align: middle;border-bottom: 0 solid rgba(0, 0, 0, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-ec1d0700{width:2.825in;background-color:transparent;vertical-align: middle;border-bottom: 0 solid rgba(0, 0, 0, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-ec1d070a{width:1.033in;background-color:transparent;vertical-align: middle;border-bottom: 0 solid rgba(0, 0, 0, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-ec1d0714{width:2.825in;background-color:transparent;vertical-align: middle;border-bottom: 0 solid rgba(0, 0, 0, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-ec1d071e{width:1.033in;background-color:transparent;vertical-align: middle;border-bottom: 1.5pt solid rgba(102, 102, 102, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-ec1d0728{width:2.825in;background-color:transparent;vertical-align: middle;border-bottom: 1.5pt solid rgba(102, 102, 102, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-ec1d0732{width:1.033in;background-color:transparent;vertical-align: middle;border-bottom: 0 solid rgba(255, 255, 255, 0.00);border-top: 0 solid rgba(255, 255, 255, 0.00);border-left: 0 solid rgba(255, 255, 255, 0.00);border-right: 0 solid rgba(255, 255, 255, 0.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-ec1d073c{width:2.825in;background-color:transparent;vertical-align: middle;border-bottom: 0 solid rgba(255, 255, 255, 0.00);border-top: 0 solid rgba(255, 255, 255, 0.00);border-left: 0 solid rgba(255, 255, 255, 0.00);border-right: 0 solid rgba(255, 255, 255, 0.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}</style><table data-quarto-disable-processing='true' class='cl-ec1f483a'><thead><tr style="overflow-wrap:break-word;"><th class="cl-ec1d06ba"><p class="cl-ec1cf4a4"><span class="cl-ec1b67b0">Time</span></p></th><th class="cl-ec1d06d8"><p class="cl-ec1cf4a4"><span class="cl-ec1b67b0">Topic</span></p></th></tr></thead><tbody><tr style="overflow-wrap:break-word;"><td class="cl-ec1d06e2"><p class="cl-ec1cf4a4"><span class="cl-ec1b67b0">10 minutos</span></p></td><td class="cl-ec1d0700"><p class="cl-ec1cf4a4"><span class="cl-ec1b67b0">Introducir el caso de estudio de ébola</span></p></td></tr><tr style="overflow-wrap:break-word;"><td class="cl-ec1d070a"><p class="cl-ec1cf4a4"><span class="cl-ec1b67b0">20 minutos</span></p></td><td class="cl-ec1d0714"><p class="cl-ec1cf4a4"><span class="cl-ec1b67b0">Funciones para limpieza de datos</span></p></td></tr><tr style="overflow-wrap:break-word;"><td class="cl-ec1d070a"><p class="cl-ec1cf4a4"><span class="cl-ec1b67b0">10 minutos</span></p></td><td class="cl-ec1d0714"><p class="cl-ec1cf4a4"><span class="cl-ec1b67b0">Demo de limpieza de datos</span></p></td></tr><tr style="overflow-wrap:break-word;"><td class="cl-ec1d070a"><p class="cl-ec1cf4a4"><span class="cl-ec1b67b0">2 horas</span></p></td><td class="cl-ec1d0714"><p class="cl-ec1cf4a4"><span class="cl-ec1b67b0">Ejercicio</span></p></td></tr><tr style="overflow-wrap:break-word;"><td class="cl-ec1d071e"><p class="cl-ec1cf4a4"><span class="cl-ec1b67b0">20 minutos</span></p></td><td class="cl-ec1d0728"><p class="cl-ec1cf4a4"><span class="cl-ec1b67b0">Devolución</span></p></td></tr></tbody><tfoot><tr style="overflow-wrap:break-word;"><td colspan="2"class="cl-ec1d0732"><p class="cl-ec1cf4a4"><span class="cl-ec1b67b0">Toma las pausas que necesites durante el ejercicio</span></p></td></tr></tfoot></table></div> ??? Fíjate en las pausas de estiramiento. --- # Orden del día - **Proyectos RStudio** - un hogar para los datos y scripts de un análisis concreto -- - Ejecutar comandos en **un script de R** usando comentarios -- - Crear **objetos** con el operador de asignación **`<-`** -- - Utilizar **funciones** como `max()`, `min()` y `paste()` -- - Importar un conjunto de datos con **`import()`** -- - Revisar un conjunto de datos con `skim()` y `summary()` -- - Comprobar la **clase** de las columnas `class()` --- class: inverse, center, middle # El caso de estudio: el brote de ébola Los módulos 2 a 9 utilizarán datos de un brote simulado de ébola en Sierra Leona. --- # Un nuevo proyecto de RStudio .pull-left[ El ejercicio te guiará para crear un nuevo **proyecto de RStudio** en la carpeta "intro\_curso/**ebola**/". <img src="../../images/functions_packages/project_briefcase.png" width="85%" /> ] .pull-right[ 📁 intro\_curso - 📁 modulo1 - 📂 covid - **📁 ebola** - **ebola.Rproj** - 📂 datos - 📁 resultados - 📂 scripts ] --- # Un nuevo Script de R .pull-left[ Escribirás un nuevo script de R llamado "ebola\_analisis.R" para guardar tus comandos. El script se guardará en la subcarpeta "ebola/**scripts**/" <img src="../../images/data_cleaning/ebola_setup.png" width="100%" height="200%" /> ] .pull-right[ 📁 intro\_curso - 📂 modulo1 - 📁 covid - 📁 **ebola** - **ebola.Rproj** - 📁 datos - 📁 resultados - 📂 **scripts** - **analisis\_ebola.R** ] --- # Cargar paquetes ¿Cuál será tu primer comando en el nuevo script de R? ¿Qué función utilizará? -- Utiliza **`pacman::p_load()`** para **cargar los paquetes** necesarios para el análisis ``` r pacman::p_load( rio, # para importar datos here, # para rutas relativas para localizar arhivos skimr, # para revisar los datos janitor, # para limpieza de datos epikit, # para crear categorías de edad tidyverse # para manejo de datos y visualización ) ``` --- # Importar desde una subcarpeta El listado de casos de ébola se guarda en la subcarpeta "**datos**/**brutos**/": 📁 **ebola** - ebola.Rproj - 📂 **datos** - 📂 limpios - 📁 **brutos** - **surveillance\_linelist\_20141201.csv** - 📂 scripts - 📂 resultados `import()` espera un *ruta de archivo*: la ubicación o "dirección" de los datos ¿Funcionará este comando para importar el listado de casos de ébola? ``` r import("listado_vigilancia_20141201.csv") ``` -- **No**, tienes que especificar en qué *subcarpeta* del proyecto se guardan los datos. --- # Rutas de los archivos **Evita** la ruta de archivo "absoluta" por ser frágil *(sólo funciona en un ordenador)* ``` r import("C:/Users/Me/Docs/intro_course/ebola/datos/brutos/listado_vigilancia_20141201.csv") ``` -- **En un proyecto de RStudio** la ruta puede empezar en la carpeta raíz del proyecto ``` r import("datos/brutos/listado_vigilancia_20141201.csv") # funciona casi en cualquier ordenador ``` -- **Utiliza `here()` para crear la ruta del archivo** sin barras `here("datos", "brutos", "listado_vigilancia_bruto.csv")` -- **El paso final** es colocar la ruta del archivo del comando `here()` *dentro* de `import()` ``` r vig_bruta <- import(here("datos", "brutos", "listado_vigilancia_20141201.csv")) ``` -- *El operador de asignación `<-` guarda el conjunto de datos como un objeto con el nombre `vig_bruta`.* ??? Los enseñamos aquí() porque elimina la necesidad de manejar barras inclinadas, y es realmente útil cuando llegas a los informes automatizados. --- class: medium-large-table # Los datos
.nota[Aquí sólo se muestran 25 filas] ??? La tabla muestra sólo las 25 primeras filas, para que se cargue más rápido. --- class: inverse, center, middle # Demostración en vivo ## Nuevo proyecto de RStudio y script de R <img src="../../images/functions_packages/piano_man.jpg" width="50%" /> --- class: inverse, center, middle ## Limpieza de datos en R <img src="../../images/data_cleaning/data_cleaning.png" width="75%" /> --- # Datos limpios, datos desordenados Ahora tus datos están importados. ¿Qué suele implicar la "limpieza" de un conjunto de datos? .pull-left[ <img src="../../images/data_cleaning/tidy_broom.png" width="75%" /> ] -- .pull-right[ - Preparar el análisis y la visualización - Normalizar los nombres de las columnas - Indexar filas y columnas - Homogeneizar escritura - Crear variables categóricas y calculadas - Unir con otros datos - Eliminar duplicados... ] .nota[] ??? Pregunta a los participantes qué medidas toman para limpiar los conjuntos de datos --- # El paquete {dplyr} .pull-left[ <img src="../../images/data_cleaning/dplyr_hex.png" width="75%" /> ] .pull-right[ - El paquete más sencillo y versátil para la limpieza de datos - Este paquete se instala como parte de un universo de paquetes de R, {tidyverse} - {tidyverse} ha transformado R en los últimos 10 años ] .nota["dplyr" es la abreviatura de "datos plier" (pinza de datos): la pinza en el logo de arriba] ??? Tidyverse ha hecho que la codificación en R sea mucho más fácil de usar, intuitiva y accesible para los codificadores principiantes --- # Base de datos de práctica Vamos a utilizar una mini base de datos, **`vig_bruta`**, para practicar algunas funciones básicas de R. |id_caso | edad|sexo |lab_conferma |inicio fecha | peso (kg)| |:-------|----:|:----|:------------|:------------|---------:| |694928 | 23|h |FALSE |11/9/2014 | 70| |86340d | 0|m |TRUE |10/30/2014 | 18| |92d002 | 16|h |TRUE |8/16/2014 | 59| |544bd1 | 10|m |TRUE |8/29/2014 | 39| |544bd1 | 10|m |TRUE |8/29/2014 | 39| |544bd1 | 10|m |FALSE |8/29/2014 | 39| --- # Funciones para hoy | Función | Utilidad | | ------- | -------------------------------------- | | `filter()` | filtrar **filas** | | `select()` | seleccionar **columnas** | | `clean_names()` | estandarizar los nombres de las columnas | | `rename()` | renombrar columnas manualmente | | `mutate()` | crear y transformar columnas | | `mdy()`, `dmy()`, `ymd()` | indicar a R cómo entender las fechas | --- class: medium-large-table2 # Filtrar filas: `filter()` .pull-left[ ``` r filter(vig_bruta) ``` 1er argumento: una base de datos ] .pull-right[ |id_caso | edad|sexo |lab_conferma |inicio fecha | peso (kg)| |:-------|----:|:----|:------------|:------------|---------:| |694928 | 23|h |FALSE |11/9/2014 | 70| |86340d | 0|m |TRUE |10/30/2014 | 18| |92d002 | 16|h |TRUE |8/16/2014 | 59| |544bd1 | 10|m |TRUE |8/29/2014 | 39| |544bd1 | 10|m |TRUE |8/29/2014 | 39| |544bd1 | 10|m |FALSE |8/29/2014 | 39| ] --- class: medium-large-table2 # Filtrar filas: `filter()` .pull-left[ ``` r filter(vig_bruta, edad < 18) ``` 2º+ argumentos: pruebas lógicas para *mantener* las filas deseadas ] .pull-right[ |id_caso | edad|sexo |lab_conferma |inicio fecha | peso (kg)| |:-------|----:|:----|:------------|:------------|---------:| |86340d | 0|m |TRUE |10/30/2014 | 18| |92d002 | 16|h |TRUE |8/16/2014 | 59| |544bd1 | 10|m |TRUE |8/29/2014 | 39| |544bd1 | 10|m |TRUE |8/29/2014 | 39| |544bd1 | 10|m |FALSE |8/29/2014 | 39| ] --- class: medium-large-table2 # Filtrar filas: `filter()` .pull-left[ ``` r filter(vig_bruta, edad < 18, sexo == "f") ``` 2º+ argumentos: pruebas lógicas para *mantener* las filas deseadas ] .pull-right[ |id_caso | edad|sexo |lab_conferma |inicio fecha | peso (kg)| |:-------|----:|:----|:------------|:------------|---------:| |86340d | 0|m |TRUE |10/30/2014 | 18| |544bd1 | 10|m |TRUE |8/29/2014 | 39| |544bd1 | 10|m |TRUE |8/29/2014 | 39| |544bd1 | 10|m |FALSE |8/29/2014 | 39| ] .footnote[Observa el uso de doble igual `==` para comprobar la igualdad]. --- class: medium-large-table2 # Filtrar filas: `filter()` .pull-left[ ``` r filter(vig_bruta, edad < 18 & (sexo == "m" | lab_conferma == TRUE) ) ``` *Las nuevas líneas y las sangrías no afectan al código* La lógica puede volverse compleja utilizando: - `&` (Y) - `|` (O) - Paréntesis ] .pull-right[ |id_caso | edad|sexo |lab_conferma |inicio fecha | peso (kg)| |:-------|----:|:----|:------------|:------------|---------:| |86340d | 0|m |TRUE |10/30/2014 | 18| |92d002 | 16|h |TRUE |8/16/2014 | 59| |544bd1 | 10|m |TRUE |8/29/2014 | 39| |544bd1 | 10|m |TRUE |8/29/2014 | 39| ] --- class: medium-large-table2 # Seleccionar columnas: `select()` .pull-left[ ``` r select(vig_bruta, ___) ``` `select()` también espera una base de datos como primer argumento ] .pull-right[ |id_caso | edad|sexo |lab_conferma |inicio fecha | peso (kg)| |:-------|----:|:----|:------------|:------------|---------:| |694928 | 23|h |FALSE |11/9/2014 | 70| |86340d | 0|m |TRUE |10/30/2014 | 18| |92d002 | 16|h |TRUE |8/16/2014 | 59| |544bd1 | 10|m |TRUE |8/29/2014 | 39| |544bd1 | 10|m |TRUE |8/29/2014 | 39| |544bd1 | 10|m |FALSE |8/29/2014 | 39| ] --- class: medium-large-table2 # Seleccionar columnas: `select()` .pull-left[ ``` r select(vig_bruta, id_caso, edad) ``` Puedes proporcionar a `select()` los nombres de columnas a *mantener* ] .pull-right[ |id_caso | edad| |:-------|----:| |694928 | 23| |86340d | 0| |92d002 | 16| |544bd1 | 10| |544bd1 | 10| |544bd1 | 10| ] --- class: medium-large-table2 # Seleccionar columnas: `select()` .pull-left[ ``` r select(vig_bruta, id_caso, edad, sexo) ``` Puedes proporcionar a `select()` los nombres de columnas a *mantener* ] .pull-right[ |id_caso | edad|sexo | |:-------|----:|:----| |694928 | 23|h | |86340d | 0|m | |92d002 | 16|h | |544bd1 | 10|m | |544bd1 | 10|m | |544bd1 | 10|m | ] --- class: medium-large-table2 # Seleccionar columnas: `select()` .pull-left[ ``` r select(vig_bruta, -id_caso, -lab_conferma) ``` O puedes designar qué columnas *eliminar* con -. ] .pull-right[ | edad|sexo |inicio fecha | peso (kg)| |----:|:----|:------------|---------:| | 23|h |11/9/2014 | 70| | 0|m |10/30/2014 | 18| | 16|h |8/16/2014 | 59| | 10|m |8/29/2014 | 39| | 10|m |8/29/2014 | 39| | 10|m |8/29/2014 | 39| ] --- # ¿`filter()` *y* `select()`? ¡Sí! Utiliza el **%>%** para "pasar" datos de una función a otra. .pull-left[ Es como decir las palabras **"y entonces"**. Una *secuencia* de limpieza típica contiene una serie de pasos enlazados - Cambiar el nombre de las columnas - Filtrar filas - Seleccionar columnas - Desduplicar - Limpiar valores... ] .pull-right[ <img src="../../images/data_cleaning/cleaning.png" width="75%" /> ] --- class: medium-large-table2 # Datos en la "tubería" (secuencia) Anteriormente, el 1er argumento era la base de datos `filter(`**vig\_raw**`, edad < 18)` -- Usando tuberías, esto se escribe ahora como **vig\_raw** `%>% filter(edad < 18)` -- Puedes conectar los datos a través de *múltiples* funciones `vig_bruta` |id_caso | edad|sexo |lab_conferma |inicio fecha | peso (kg)| |:-------|----:|:----|:------------|:------------|---------:| |694928 | 23|h |FALSE |11/9/2014 | 70| |86340d | 0|m |TRUE |10/30/2014 | 18| |92d002 | 16|h |TRUE |8/16/2014 | 59| |544bd1 | 10|m |TRUE |8/29/2014 | 39| |544bd1 | 10|m |TRUE |8/29/2014 | 39| |544bd1 | 10|m |FALSE |8/29/2014 | 39| --- class: medium-large-table2 # Datos en la "tubería" (secuencia) Anteriormente, el 1er argumento era la base de datos `filter(`**vig\_raw**`, edad < 18)` Usando tuberías, esto se escribe ahora como **vig\_raw** `%>% filter(edad < 18)` Puedes conectar los datos de `vig_bruta` a través de *múltiples* funciones `vig_bruta` **%>%** `filter(edad < 18)` |id_caso | edad|sexo |lab_conferma |inicio fecha | peso (kg)| |:-------|----:|:----|:------------|:------------|---------:| |86340d | 0|m |TRUE |10/30/2014 | 18| |92d002 | 16|h |TRUE |8/16/2014 | 59| |544bd1 | 10|m |TRUE |8/29/2014 | 39| |544bd1 | 10|m |TRUE |8/29/2014 | 39| |544bd1 | 10|m |FALSE |8/29/2014 | 39| --- class: medium-large-table2 # Datos en la "tubería" (secuencia) Anteriormente, el 1er argumento era la base de datos `filter(`**vig\_raw**`, edad < 18)` Usando tuberías, esto se escribe ahora como **vig\_raw** `%>% filter(edad < 18)` Puedes conectar los datos de `vig_bruta` a través de *múltiples* funciones `vig_bruta` **%>%** `filter(edad < 18)` **%>%** `select(id_caso, edad, sexo)` |id_caso | edad|sexo | |:-------|----:|:----| |86340d | 0|m | |92d002 | 16|h | |544bd1 | 10|m | |544bd1 | 10|m | |544bd1 | 10|m | --- # Estilo de codificación vertical Un estilo de codificación *vertical* con *sangrías* no afecta al código, ¡pero lo hace más legible! ``` r vig_bruta ``` |id_caso | edad|sexo |lab_conferma |inicio fecha | peso (kg)| |:-------|----:|:----|:------------|:------------|---------:| |694928 | 23|h |FALSE |11/9/2014 | 70| |86340d | 0|m |TRUE |10/30/2014 | 18| |92d002 | 16|h |TRUE |8/16/2014 | 59| |544bd1 | 10|m |TRUE |8/29/2014 | 39| |544bd1 | 10|m |TRUE |8/29/2014 | 39| |544bd1 | 10|m |FALSE |8/29/2014 | 39| --- # Estilo de codificación vertical Un estilo de codificación *vertical* con *sangrías* no afecta al código, ¡pero lo hace más legible! ``` r vig_bruta %>% select(id_caso, edad, sexo, lab_conferma) # seleccionar columnas ``` |id_caso | edad|sexo |lab_conferma | |:-------|----:|:----|:------------| |694928 | 23|h |FALSE | |86340d | 0|m |TRUE | |92d002 | 16|h |TRUE | |544bd1 | 10|m |TRUE | |544bd1 | 10|m |TRUE | |544bd1 | 10|m |FALSE | --- # Estilo de codificación vertical El **`%>%`** pasa el conjunto de datos al siguiente paso ``` r vig_bruta %>% select(id_caso, edad, sexo, lab_conferma) %>% # seleccionar columnas distinct() # des-duplicar ``` |id_caso | edad|sexo |lab_conferma | |:-------|----:|:----|:------------| |694928 | 23|h |FALSE | |86340d | 0|m |TRUE | |92d002 | 16|h |TRUE | |544bd1 | 10|m |TRUE | |544bd1 | 10|m |FALSE | --- # Estilo de codificación vertical El **`%>%`** pasa la base de datos al siguiente paso ``` r vig_bruta %>% select(id_caso, edad, sexo, lab_conferma) %>% # seleccionar columnas distinct() %>% # des-duplicar filter(edad < 18, lab_conferma == TRUE) # sólo los casos confirmados de niños pequeños ``` |id_caso | edad|sexo |lab_conferma | |:-------|----:|:----|:------------| |86340d | 0|m |TRUE | |92d002 | 16|h |TRUE | |544bd1 | 10|m |TRUE | --- # Estilo de codificación vertical El **`%>%`** pasa la base de datos al siguiente paso ``` r vig_bruta %>% select(id_caso, edad, sexo, lab_conferma) %>% # seleccionar columnas distinct() %>% # des-duplicar filter(edad < 18, lab_conferma == TRUE) %>% # casos confirmados sólo en niños pequeños mutate(bebe = ifelse(edad < 1, "bebe", "not bebe")) # crear una columna ``` |id_caso | edad|sexo |lab_conferma |bebe | |:-------|----:|:----|:------------|:--------| |86340d | 0|m |TRUE |bebe | |92d002 | 16|h |TRUE |not bebe | |544bd1 | 10|m |TRUE |not bebe | --- # Estilo de codificación vertical ¿Hay un operador 'pipe' al final de este flujo de trabajo? ``` r vig_bruta %>% select(id_caso, edad, sexo, lab_conferma) %>% # seleccionar columnas distinct() %>% # des-duplicar filter(edad < 18, lab_conferma == TRUE) %>% # casos confirmados sólo en niños pequeños mutate(bebe = ifelse(edad < 1, "bebe", "not bebe")) # crear una columna ``` |id_caso | edad|sexo |lab_conferma |bebe | |:-------|----:|:----|:------------|:--------| |86340d | 0|m |TRUE |bebe | |92d002 | 16|h |TRUE |not bebe | |544bd1 | 10|m |TRUE |not bebe | -- Las tuberías conectan todas estas funciones en un único comando enlazado. ¿Cómo ejecutarías este comando en RStudio? --- # Nombres de las columnas Podemos observar los cambios en los nombres de las columnas imprimiéndolos con `names()` ``` r # Imprimir los nombres de las columnas actuales names(vig_bruta) ``` ``` ## [1] "id_caso" "edad" "sexo" "lab_conferma" ## [5] "inicio fecha" "peso (kg)" ``` --- # Nombres de las columnas De forma equivalente, `vig_bruta` puede pasarse a `names()` utilizando un **pipe**: ``` r vig_bruta %>% # comienza con los datos crudos names() # imprime los nombres actuales de las columnas ``` ``` ## [1] "id_caso" "edad" "sexo" "lab_conferma" ## [5] "inicio fecha" "peso (kg)" ``` -- Aplica `clean_names()` a `vig_bruta` agregándolo en la secuencia. Así se estandarizan los nombres de las columnas: en minúsculas, sin espacios ni caracteres especiales. ``` r vig_bruta %>% # comienza con los datos crudos * clean_names() %>% # estandariza los nombres de las columnas names() # imprime los nombres actuales de las columnas ``` ``` ## [1] "id_caso" "edad" "sexo" "lab_conferma" ## [5] "inicio_fecha" "peso_kg" ``` *Ver cambios en las dos últimas columnas* --- # Nombres de las columnas De forma equivalente, `vig_bruta` puede pasarse a `names()` utilizando un **pipe**: ``` r vig_bruta %>% # comienza con los datos crudos names() # imprime los nombres actuales de las columnas ``` ``` ## [1] "id_caso" "edad" "sexo" "lab_conferma" ## [5] "inicio fecha" "peso (kg)" ``` Ahora, incorpora los nombres **limpios** a `rename()` para editarlos manualmente. Ten en cuenta que `rename()` conecta a los nombres **limpios** (`inicio_fecha`). ``` r vig_bruta %>% # comienza con los datos crudos * clean_names() %>% # estandariza los nombres de las columnas * rename( # edita manualmente * edad_anios = edad, # NUEVO = VIEJO * fecha_inicio = inicio_fecha) %>% names() # imprime los nombres actuales de las columnas ``` --- # Imprimir vs. guardar Haz clic en las pestañas para ver la diferencia. .panelset[ .panel[.panel-name[Printing] Los cambios en `vig_bruta` **no** fueron guardados. Sólo *imprimimos las modificaciones*. ``` r # modifica e imprime los nombres de las columnas *vig_bruta %>% # comienza con los datos crudos clean_names() %>% # estandariza los nombres de las columnas rename( # edita manualmente edad_anios = edad, # NUEVO = VIEJO fecha_inicio = inicio_fecha) %>% * names() # imprime los nombres actuales de las columnas ``` ¡**`vig_bruta`** todavía tiene los *nombres originales de las columnas*! ``` r names(vig_bruta) ``` ``` ## [1] "id_caso" "edad" "sexo" "lab_conferma" ## [5] "inicio fecha" "peso (kg)" ``` ] .panel[.panel-name[Saving] Utiliza el operador **`<-`** para guardar los cambios en un nuevo objeto **`vig_limpia`**. Aunque no se imprime nada, el nuevo objeto estará en el Entorno de RStudio. ``` r # crea una nueva base de datos *vig_limpia <- vig_bruta %>% clean_names() %>% rename( edad_anios = edad, fecha_inicio = inicio_fecha) ``` ¡**`vig_limpia`** tiene ahora los *nombres de las columnas limpios*! ``` r names(vig_limpia) ``` ``` ## [1] "id_caso" "edad_anios" "sexo" "lab_conferma" ## [5] "fecha_inicio" "peso_kg" ``` ] ] --- class: medium-large-table2 # Crear columnas: `mutate()` La sintaxis es ``` r base_de_datos %>% mutate(NUEVO_NOMBRE = UNA_FUNCIÓN(argumentos)) ``` .pull-left[ ``` r vig_bruta %>% mutate(grupo_etario = ifelse( test = edad >= 18, yes = "adulto", no = "menor")) ``` `ifelse()` comprueba lógicamente cada fila y escribe en la nueva columna `grupo_etario`: - "adulto" si es VERDADERO - "menor" si es FALSA ] .pull-right[ |id_caso | edad|sexo |lab_conferma |inicio fecha | peso (kg)|grupo_etario | |:-------|----:|:----|:------------|:------------|---------:|:------------| |694928 | 23|h |FALSE |11/9/2014 | 70|adulto | |86340d | 0|m |TRUE |10/30/2014 | 18|menor | |92d002 | 16|h |TRUE |8/16/2014 | 59|menor | |544bd1 | 10|m |TRUE |8/29/2014 | 39|menor | |544bd1 | 10|m |TRUE |8/29/2014 | 39|menor | |544bd1 | 10|m |FALSE |8/29/2014 | 39|menor | ] --- class: medium-large-table2 # Editar columnas con `mutate()` La sintaxis es similar: ``` r base_de_datos %>% mutate(MISMO_NOMBRE_DE_COLUMNA = UNA_FUNCIÓN(argumentos)) ``` .pull-left[ ``` r vig_bruta %>% mutate(sexo = recode(sexo, "h" = "hombre", "m" = "mujer")) ``` La columna `sexo` se sobrescribe. La función `recode()` comienza con el original de `sexo` y aplica los cambios: - "h" a "hombre" - "m" a "mujer" ] .pull-right[ |id_caso | edad|sexo |lab_conferma |inicio fecha | peso (kg)| |:-------|----:|:------|:------------|:------------|---------:| |694928 | 23|hombre |FALSE |11/9/2014 | 70| |86340d | 0|mujer |TRUE |10/30/2014 | 18| |92d002 | 16|hombre |TRUE |8/16/2014 | 59| |544bd1 | 10|mujer |TRUE |8/29/2014 | 39| |544bd1 | 10|mujer |TRUE |8/29/2014 | 39| |544bd1 | 10|mujer |FALSE |8/29/2014 | 39| ] --- # Usando `mutate()` con fechas Las columnas de fecha han de ser de `class()` "date" (fecha), no "character" (nominal) Para cambiar la clase, debes *indicar* a R cómo entender las fechas en bruto. .pull-left[ Las fechas tienen muchos formatos: ¿"03/09/2024" es el 9 de marzo o el 3 de septiembre? ] .pull-right[ <img src="../../images/data_cleaning/Dates_500x500.png" width="100%" /> ] .footnote[Más detalles en este [capítulo del Manual de Epi](https://epirhandbook.com/en/working-with-dates.html)] --- # Convertir a clase fecha En la función `mutate()`, usa {lubridate} para alinear los *formatos de fechas*. - `ymd()` si los valores brutos son AAAA-MM-DD - `dmy()` si los valores brutos son DD-MM-AAAA - `mdy()` si los valores brutos son MM-DD-AAAA -- .pull-left[ ``` r vig_limpia %>% select(id_caso, fecha_inicio) %>% tibble() ``` ``` ## # A tibble: 6 × 2 ## id_caso fecha_inicio ## <chr> <chr> ## 1 694928 11/9/2014 ## 2 86340d 10/30/2014 ## 3 92d002 8/16/2014 ## 4 544bd1 8/29/2014 ## 5 544bd1 8/29/2014 ## 6 544bd1 8/29/2014 ``` ] -- .pull-right[ ``` r vig_limpia %>% * mutate(fecha_inicio = mdy(fecha_inicio)) %>% select(id_caso, fecha_inicio) %>% tibble() ``` ``` ## # A tibble: 6 × 2 ## id_caso fecha_inicio ## <chr> <date> ## 1 694928 2014-11-09 ## 2 86340d 2014-10-30 ## 3 92d002 2014-08-16 ## 4 544bd1 2014-08-29 ## 5 544bd1 2014-08-29 ## 6 544bd1 2014-08-29 ``` ] .footnote[`tibble()` muestra la clase de cada columna encima de sus valores] --- class: inverse, center, middle ## Ejercicio Ve al sitio web del curso Abre el ejercicio del Módulo 2 e inicia sesión Sigue las instrucciones para crear un nuevo proyecto de RStudio y empieza a programar Avisa a un/a instructor/a si no estás seguro de lo que tienes que hacer <img src="../../images/breakout/COVID dominoes.png" width="100%" />