---
title: "Clase 2"
output: 
  html_document:
    toc: TRUE
    toc_float: TRUE
author: "Germán Rosati y Laia Domenech Burin"
date: "`r format(Sys.time(), '%d %B, %Y')`"
theme: Boadilla
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo=FALSE)
```

```{r message=FALSE, warning=FALSE, include=FALSE, paged.print=FALSE}
knitr::opts_chunk$set(echo=TRUE, message=FALSE, warning=FALSE, tidy=TRUE)
```

## El mundo tidyverse

- La clase pasada cerramos la parte práctica instalando el paquete **Tidyverse**. Sin embargo, al hacerlo no estaban instalando solo un paquete, sino una colección de paquetes de R que están diseñados para el análisis de datos. 
- La lógica de tener estos paquetes juntos es que todos ellos comparten la misma filosofía, gramática, y estructuras de datos. 

- Los principales paquetes que están en este mundo son
  + `magrittr`: que introduce la **pipe** (%>%)
  + `dplyr`: orientado a la maniplulación de bases de datos
  + `tidyr`: para la limpieza de datos
  + `readr`: para la lectura de bases de datos
  + `purr`: provee herramientas para trabajar con funciones sobre vectores
  + `stringr`: orientado a facilitar el trabajo con datos de texto
  + `forcats`: orientado a facilitar el trabajo con factores
        
### ¿Por qué tidyverse? 

- Está diseñado para ser leído y usado de manera simple por seres humanos. La gramática es intuitiva y la mayoría de sus funcionalidades son fáciles de usar. 
- Sus funciones no están pensadas para una tarea específica, sino para todo un flujo de trabajo: desde la importación de datos hasta la comunicación de resultados. 
- Su comunidad está basada en los principios de código abierto y colaborativo. Los mismos diseñadores de los paquetes tienen [muchísimas fuentes](https://www.tidyverse.org/learn/) para aprender a usarlos, y disponen del código abierto de cada paquete en GitHub. 

Para empezar a trabajar con el paquete, tenemos que introducirlo en la sesión con la función `library()`: 

```{r, echo=TRUE, warning=TRUE}
library(tidyverse)
library(readr)
library(eph)
```

## Pipes: la gramática básica de tidyverse

Más arriba mencionamos que el paquete `magrittr` introduce la pipe y la señalamos como este símbolo `%>%`. La pipe es una **forma de escribir** del mundo tidyverse, que indica que vamos a realizar de terminada operación sobre el objeto que está a la izquierda. Sirve para indicar una secuencia de acciones. 

Para desarrollar los ejemplos de esta clase, vamos a trabajar con datos de la Encuesta Permanente de Hogares. Para ello, usaremos el paquete `eph`. Por ahora, lo único que vamos a usar de él es la función `get_microdata()`, que nos devuelve la base de microdatos de individuos o hogares para el trimestre seleccionado:
```{r}
df <- get_microdata(year=2023, trimester=3, type='individual')

df <- organize_labels(df=df, type='individual') # Vamos a etiquetar la base

df$NRO_HOGAR <- as.character(df$NRO_HOGAR)

table(df$CAT_OCUP)
```

---

#### Ejercicio rápido
¿Qué les parece que hace esta línea?
`df$NRO_HOGAR <- as.character(df$NRO_HOGAR)`

---

Ahora, con una pipe...
```{r}
df$CAT_OCUP %>%
        table()
```

Las funciones pueden concatenarse, y esta es la principal gracia del uso de las pipes. 

```{r}
df$CAT_OCUP%>%
        table()%>%
        prop.table()%>%
        round(., 2)
```

---

### Ejercicio rápido ***
¿Cómo obtendrían la tabla anterior sin usar `%>%`? O sea en R-base...
```{r}
###
```

---


## dplyr

Vimos que este paquete de tidyverse está orientado al manejo de bases de datos. Tiene 5 funciones básicas que resuelven el 90% de nuestros problemas a la hora de limpiar y procesas bases: 

1. `select()`: que selecciona y descarta variables
2. `filter()`: selecciona y descarta según filas
3. `arrange()`: reordena las filas
4. `mutate()`: crea o edita variables
5. `rename()`: renombra variables
6. `summarise()`: colapsa los valores a un solo resumen

Todas pueden ser usadas en conjunto con `group_by()` que cambia el objeto de cada función: en lugar de operar sobre todo el dataset, lo hace al interior de cada grupo definido.

### `select()`

- Esta función únicamente requiere poner el nombre de las columnas que elegimos.
  +Para seleccionar un intervalo de columnas, uso el `:`

```{r}
select_prueba_1 <- df %>% select(CODUSU, CH03:CH09)

head(select_prueba_1)
```

- Podemos hacer una selección por **posición de la columna**: 

```{r}
select_prueba_2 <- df %>% select(3:6)

head(select_prueba_2)
```

- Se puede hacer una anti-selección (o sea, elegir todas las columnas menos algunas especificadas)
```{r}
select_prueba_3 <- df %>% select(-c(ANO4:TRIMESTRE))

head(select_prueba_3)
```

- También, se pueden seleccionar columnas según criterios con funciones auxiliares:
  + `starts_with` : selecciona columnas que empiecen con el string que pasemos.
  + `ends_with` : selecciona columnas que terminen con el string que le pasemos. 
  + `contains` : selecciona columnas que contengan la palabra que indicamos. 
  
```{r}
select_prueba_4 <- df %>% select(starts_with("CH"))

head(select_prueba_4)

select_prueba_5 <- df %>% select(contains("CAT"))

head(select_prueba_5)
```
### `rename()`

- Esta función solo requiere indicar `NOMBRE_NUEVO = NOMBRE_VIEJO`

```{r}
df <- df %>% rename(sexo = CH04)

table(df$sexo)
```
- También se puede usar la versión `rename_with()` para cambiarle el nombre a una selección de columnas: 

```{r}
df %>% rename_with(tolower, starts_with("CH"))
```
### `arrange()`

- La función toma un data frame y un conjunto de nombres de columnas (o expresiones más complicadas) para ordenar según ellas. 

```{r}
df %>% arrange(CH06) %>% select(CH06)
```
- Usa `desc()` para reordenar por una columna en orden descendente:

```{r}
df %>% arrange(desc(CH06)) %>% select(CH06)
```

### `filter()`

- Esta función tiene el siguiente esquema: `filter(CONDICIÓN)`
- La clase 1 vimos los distintos operadores (lógicos, arimétricos, relacionales) que podemos usar para escribir estos formatos condicionales. 

Supongamos que queremos quedarnos con los registros de mujeres:
```{r}
base_filtrada_1 <- df %>% filter(sexo == 2)

table(base_filtrada_1$sexo)
```

Por ejemplo, supongamos que queremos obtener los registros aquellas personas mayores de 25:

```{r}
base_filtrada_2 <- df %>% filter(CH06> 25)

table(base_filtrada_2$CH06)
```

Los condicionales también pueden combinarse. Podríamos traer todas las mujeres mayores de 25:

```{r}
base_filtrada_3 <- df %>% filter(sexo == 2 | CH06 > 25)

dim(base_filtrada_3)
```

Ahora bien, ¿cómo hacemos si queremos los registros solo las mujeres desocupadas e inactivas? 

```{r}
base_filtrada_4 <- df  %>% filter(ESTADO %in% c(2, 3) & sexo == 2)

table(base_filtrada_4$ESTADO, base_filtrada_4$sexo)
```

`%in%` es una forma de indicar que vamos a buscar los valores del vector en la columna que indicamos. Sería lo mismo que hacer: 

```{r}
base_filtrada_4 <- df  %>% filter((ESTADO == 2 & sexo == 2) | (ESTADO == 3 & sexo == 2))
```

Pero de manera simplificada. 

El filtrado también puede aplicarse sobre columnas para quedarnos sólo con las filas que tienen valores -es decir, borrar los NA. 

Vamos a borrar los casos que tienen NA en el ultimo año de cursada aprobado. Probemos que pasa si usamos el operador `==`
```{r}
base_filtrada_4 <- df  %>% filter(CH14 != NA) %>% select(CH14)

nrow(base_filtrada_4)
```

¡Nos borró todas las variables! Pero esto no está bien, ya que vimos que esta columna tenía varios valores. ¿Qué sucedió? 

Resulta que los NA son bastante tramposos en R. Casi cualquier operación con uno de ellos va a devolver otro NA, y es por esto que no debemos trabajar con operadores a la hora de filtrarlos, sino que debemos usar la función `is.na()`
```{r}
base_filtrada_5 <- df  %>% filter(!is.na(CH14)) %>% select(CH14)

nrow(base_filtrada_5)
```

### `mutate()`

- Esta función nos permite crear y modificar columnas.
- Suele ser útil crear columnas como funciones de columnas ya existentes
- Su sintaxis es `mutate(nombre_de_la_columna = valores_de_la_columna)`  

Por ejemplo, podemos crear una columna simple con el nombre de la base:
```{r}
mutate_1 <- df %>% mutate(columna_ejemplo = "EPH 2do trim 2020") 
head(mutate_1)
```
- También podemos "editar" una columna ya existente. Por ejemplo, podemos pasar a `string` la columna de sexo para que aparezca la etiqueta en lugar de números:

```{r}
mutate_2 <- df %>% mutate(sexo = as.character(sexo))
mutate_2 %>% select(sexo)
```
- Podemos combinar `mutate` y `across()` para editar varias variables al mismo tiempo:
  + dentro de la función `mutate()` pasamos una segunda función `across()` donde indicamos el conjunto de columnas que queremos modificar
  + para aplicar una función hay que introducirla con el símbolo `~`
  + usamos el punto `.x` para referirnos a la selección de variables anterior
```{r}
df <- df %>% mutate(across(c(CH03, sexo, CH07:CAT_INAC), ~as.character(.x)))

df %>% select(CH03:CAT_INAC)
```


### `group_by` + `summarize()`

* `group_by` cambia la unidad de análsis del dataset a grupos. Así, al llamar a cualqyuer verbo de `dplyr` se aplica "por grupo",
* combinándolo con `summarize()`, nos permite hacer una tabla con una medida resumen de las variables que querramos. 

Por ejemplo, podemos hacer el conteo de frecuencias del último año aprobado de escolaridad:
```{r}
df %>%
        group_by(CH14)%>%
        summarize(n=n())
```
La media de edades según sexo: 
```{r}
df %>%
        group_by(sexo)%>%
        summarize(mean_edad=round(mean(CH06,na.rm=TRUE)))
```

### `pivot_longer` y `pivot_wider` 
- `pivot_longer` "alarga" los datos convirtiendo columnas a filas. Tiene los siguientes parámetros:
        + `cols`: elijo las columnas que quiero pasar a filas
        + `names_to`: indico el nombre de la columna que va a contener las variables elegidas
        + `values_to`: indico el nombre de la columna que va a contener los valores de las variables

```{r}
medidas_resumen <- df %>%
  group_by(sexo) %>% 
  summarise(media_edad = mean(CH06, na.rm = TRUE),
            sd_edad = sd(CH06, na.rm = TRUE)) %>% 
  select(sexo, 
         media_edad, sd_edad) 

pivot_longer_resumen <- medidas_resumen%>% 
  pivot_longer(cols = c(media_edad, sd_edad), 
               names_to = "variable", 
               values_to = "valor")
```

- `pivot_wider` es la operación inversa. Crea variables a partir de filas, y "alarga" la base de datos. 
  +`id_cols`: la columna de ID, que no queremos que pierda su formato
  +`names_from`: indico en qué columna están los nombres de las variables
  + `values_from`: indico en qué columna están los valores de las variables

```{r}
pivot_longer_resumen %>% 
        pivot_wider(id_cols= sexo, 
                    names_from=variable,
                    values_from = valor)
```

### `join()`

- Esta función sirve para unir un dataframe x con un dataframe y a partir de un identificador común. Existen distintos tipos de join:
  + `inner_join():` incluye todas las filas que estén en x e y.
  + `left_join():` incluye todas las filas que estén en x.
  + `right_join():` incluye todas las filas que estén en y.
  + `full_join():` incluye todas las filas que estén en x o y.
  
Supongamos que queremos "joinear" la base que tenemos con las variables de resumen del hogar (cantidad de personas en el hogar `IX_TOT`, las personas menores de 10 años `IX_MEN10` y las personas de 10 o más años de edad, `IX_MAYEQ10`). Todas estas variables están en la tabla de hogares. La columna **CODSU** nos da un identificador único de cada registro. De manera que podemos hacer un seguimiento de los individuos en el hogar a través de esa columna:
```{r}
df_2 <- get_microdata(year=2023, trimester=3, type='hogar') %>%
        organize_labels(type='hogar') %>%
        mutate(NRO_HOGAR = as.character(NRO_HOGAR))

df_2 <- df_2 %>%
    select(CODUSU, NRO_HOGAR, IX_TOT:IX_MAYEQ10) # Selecciono únicamente las variables de ID y las variables de resumen del hogar 

df_merged <- df %>% left_join(df_2, by = c("CODUSU", "NRO_HOGAR"))
```

Ahora podemos chequear el resultado revisando los nombres de columnas que se agregaron a la tabla.

```{r}
colnames(df_merged)
```


## Ejercicios 

1. ¿Cómo podrían calcular (sin hacer el join) las variables que trajimos de la tabla de hogar? 
  - cantidad de personas en el hogar `IX_TOT` 
  - cantidad de personas menores de 10 años `IX_MEN10` 
  - cantidad de personas de 10 o más años de edad, `IX_MAYEQ10`

2. Hagan un join de la variable Ingreso Total Familiar (`ITF`) de la tabla de hogar y chequeen los resultados con la misma variable que ya existe en la tabla de individuos.


