class: center, middle, inverse, title-slide .title[ # Clase 04 ] .subtitle[ ## Data Wrangling ] .author[ ### Sebastián Muñoz ] .date[ ### 2025-04-04 ] --- ## En esta clase ### 1. Repaso ### 2. Data Wrangling #### 2.1 Limpieza de datos #### 2.2 Transformación de variables #### 2.3 Exportar ### 3. Gráficos con ggplot --- class: inverse, center, middle # 1. Repaso --- # De persona novata a experta  --- # De persona novata a experta  --- background-size: contain background-repeat: no-repeat background-position: center center background-image: url("img/quipu0.png") --- ### Flujo de trabajo  --- ### Orden de script  --- ## Tipos de datos  --- ## Listas  --- #Importación de bases de datos A la hora de importar una base de datos nos podemos llegar a enfrentar a distintos tipos de archivos. En R contamos con **distintos paquetes y funciones** según el **tipo de extensión** del archivo: <table class="table table-striped table-hover" style="margin-left: auto; margin-right: auto;"> <thead> <tr> <th style="text-align:left;"> Tipo de archivo </th> <th style="text-align:left;"> Paquete </th> <th style="text-align:left;"> Extension </th> <th style="text-align:left;"> Funciones </th> </tr> </thead> <tbody> <tr> <td style="text-align:left;"> Texto Plano </td> <td style="text-align:left;"> readr </td> <td style="text-align:left;"> .csv </td> <td style="text-align:left;"> read_csv() </td> </tr> <tr> <td style="text-align:left;"> Texto Plano </td> <td style="text-align:left;"> readr </td> <td style="text-align:left;"> .txt </td> <td style="text-align:left;"> read_txt() </td> </tr> <tr> <td style="text-align:left;"> Texto Plano </td> <td style="text-align:left;"> readr </td> <td style="text-align:left;"> .tsv </td> <td style="text-align:left;"> read_tsv() </td> </tr> <tr> <td style="text-align:left;"> Extension de R </td> <td style="text-align:left;"> RBase </td> <td style="text-align:left;"> .RDS </td> <td style="text-align:left;"> readRDS() </td> </tr> <tr> <td style="text-align:left;"> Extension de R </td> <td style="text-align:left;"> RBase </td> <td style="text-align:left;"> .RDATA </td> <td style="text-align:left;"> open() </td> </tr> <tr> <td style="text-align:left;"> Otros Softwares </td> <td style="text-align:left;"> haven </td> <td style="text-align:left;"> .dta </td> <td style="text-align:left;"> read_dta() </td> </tr> <tr> <td style="text-align:left;"> Otros Softwares </td> <td style="text-align:left;"> haven </td> <td style="text-align:left;"> .sav </td> <td style="text-align:left;"> read_spss() </td> </tr> <tr> <td style="text-align:left;"> Excel </td> <td style="text-align:left;"> openxlsx </td> <td style="text-align:left;"> .xlsx </td> <td style="text-align:left;"> read.xlsx() </td> </tr> <tr> <td style="text-align:left;"> Excel </td> <td style="text-align:left;"> readxl </td> <td style="text-align:left;"> .xls </td> <td style="text-align:left;"> read_excel() </td> </tr> </tbody> </table> --- #Importación de bases de datos El primer y más importante parámetro de las funciones para importar datos suele llamarse **`file`**. Allí debemos especificar la ruta hasta el archivo, incluyendo la extensión del mismo. Si tenemos abierto un proyecto, el punto de partida para la ruta a especificar será la carpeta del proyecto. Si queremos ir hacia atrás en las carpetas agregamos **`../`** ```r base.vacunas<- read_csv( file = "../Fuentes/Covid19VacunasAgrupadas.csv") base.covid <- readRDS(file = "../Fuentes/base_covid_sample.RDS") ``` **IMPORTANTE**: Siempre que lean bases de datos asignarlas a un nuevo objeto. De lo contrario, las va a mostrar completas en consola y no va a guardarlas en el ambiente de trabajo (enviroment) --- #Exportación de resultados Por lo general, cada paquete que presenta funciones para importar bases de dato, tiene como complemento una función para exportar (guardar en el disco de nuestra PC) un objeto con la misma extensión. Ejemplos: - el paquete **openxlsx** tiene una función denominada **`write.xlsx()`** que nos permite exportar un dataframe creando un archivo **.xslx** - En RBase la función **`saveRDS()`** nos permite exportar archivos de extensión **.RDS** (son menos pesados para trabajarlos luego desde R) En general estas funciones tienen un primer parametro para especificar el objeto a exportar, y un segundo para especificar la ruta y el nombre de archivo a crear () ```r write.xlsx(x = objeto_resultados,file = "Resultados/cuadro1.xlsx") saveRDS(object = objeto_resultados,file = "Resultados/base_nueva.RDS") ``` --- background-size: contain background-repeat: no-repeat background-position: center center background-image: url("img/quipu.png") --- ## Definición de Términos ### Quipú - Artefacto inca de cuerdas y nudos - Función: registro de información económica, demográfica, histórica - Operadores: quipucamayocs ### Base de Datos - Sistema digital para almacenar y manipular información - Estructura: tablas con filas y columnas - Acceso mediante lenguajes de programación --- ## Analogías Funcionales ### Almacenamiento de Información - **Quipú:** Posición y color de hilos, tipos de nudos - **Base de Datos:** Registros digitales en estructuras predefinidas ### Sistematización y Orden - **Quipú:** Orden físico y visual - **Base de Datos:** Orden lógico definido por esquemas digitales --- ## Importancia Cultural y Tecnológica .pull-left[ ### Contexto Cultural - **Quipú:** Reflejo de la cosmovisión inca, sin sistema de escritura - **Base de Datos:** Reflejo de avances tecnológicos y manejo de información en la sociedad moderna ### Especialización del Conocimiento - **Quipú:** Quipucamayocs, especialistas en su manejo - **Base de Datos:** Programadores y analístas de datos] .pull-right[ ] --- background-image: url("img/quipueg.jpg") background-size: cover --- class: inverse, center, middle # 2. Data Wrangling --- background-image: url("img/limpieza.png") background-size: cover --- background-image: url("img/herramientas.png") background-size: cover --- class: center, middle # 2.1 Limpieza de datos ## Janitor  --- ## Limpiar nombres de variables En general los nombres de las variables de bases de datos (en bruto) tienen la forma ```r library(openxlsx) datos <- read.xlsx(xlsxFile = "base/Encuesta Estudiantes Antropología 2023 (respuestas).xlsx", startRow = 2) #extraigo el nombre de todas las variables y las observo names (datos) ``` ``` ## [1] "Marca.temporal" ## [2] "p02..Edad.del(a).entrevistado/" ## [3] "p03..Género.del/a.entrevistado/a" ## [4] "p04..Año.en.que.se.encuentra.de.la.carrera.(1°,.2°,.3°,.4°,.5°,.)." ## [5] "p05..Comuna.actual.de.residencia" ## [6] "p06..Comuna.de.residencia.de.su.familia.nuclear.(padres,.hermanos/as.u.otros/as.cuidadores).o.en.la.que.vivió.la.mayor.parte.de.infancia.y.adolescencia." ## [7] "p07..Último.tipo.de.establecimiento.educativo.en.que.realizó.su.enseñanza.media" ## [8] "p08..Puntaje.final.obtenido.en.la.prueba.de.selección.universitaria.(ponderado.según.carrera.elegida)" ## [9] "p09..¿Cuál.de.estas.situaciones.describe.mejor.su.actividad.principal.durante.el.último.mes?" ## [10] "p10..Indique.el.máximo.nivel.educativo.alcanzado.por.su.MADRE" ## [11] "p11..¿Actualmente.su.MADRE.trabaja?" ## [12] "p12..¿Cuál.es.la.ocupación.u.oficio.actual.de.su.MADRE?.Describa.las.principales.tareas.y.funciones.en.el.puesto.de.trabajo.actual.de.su.madre" ## [13] "p13..Indique.el.máximo.nivel.educativo.alcanzado.por.su.PADRE" ## [14] "p14..¿Actualmente.su.PADRE.trabaja?" ## [15] "p15..¿Cuál.es.la.ocupación.u.oficio.actual.de.su.PADRE?.Describa.las.principales.tareas.y.funciones.en.el.puesto.de.trabajo.actual.de.su.padre" ## [16] "p17..¿Quién.es.el.principal.sostenedor/a.de.su.hogar.ACTUAL?.(quien.aporta.más.al.presupuesto.mensual)" ## [17] "p18..En.la.sociedad,.comúnmente,.existen.distintos.grupos.o.clases.sociales..Las.personas.de.clase.social.alta.son.las.que.tienen.los.ingresos.más.altos,.el.mayor.nivel.de.educación.y.los.trabajos.más.valorados..Las.personas.de.clase.social.baja.son.las.que.tienen.los.ingresos.más.bajos,.el.menor.nivel.de.educación.y.los.trabajos.menos.valorados..Entre.estas.clases.existen.otras.intermedias:.Según.su.opinión,.a.cuál.de.los.siguientes.grupos.o.clases.sociales.pertenece.usted:" ## [18] "p19..Actualmente.en.su.casa.¿Tienen.Computador.(ya.sea.notebook.o.de.escritorio).?" ## [19] "p20..Actualmente.USTED.¿tiene.Computador.para.uso.personal.(ya.sea.notebook.o.de.escritorio)?" ## [20] "p21..Actualmente.USTED.¿Tiene.smartphone.personal?" ## [21] "p22..¿Con.qué.frecuencia.escucha.música?" ## [22] "p23..¿Qué.tipo.de.música.es.la.que.MÁS.prefiere.escuchar?.[Aun.cuándo.escuche.más.de.un.estilo,.elija.el.que.MÁS.escuche]" ## [23] "p24..Si.eligió.otra,.¿Cuál?" ## [24] "p25.¿Cuál.es.la.segunda.música.que.más.prefiere.escuchar?" ## [25] "p26..Si.eligió.otra,.¿Cuál?" ## [26] "p27..¿Con.qué.dispositivo.suele.escuchar.más.música?" ## [27] "p28.¿Cuál.es.principal.sitio,.programa.o.aplicación.para.bajar.o.escuchar.música?" ## [28] "p29..si.respondió.otro,.¿Cuál?" ## [29] "p30..¿Cuál.es.la.red.social.en.que.pasa.más.tiempo?" ## [30] "p31..si.respondió.otra,.¿Cuál?" ## [31] "p32..Y.¿Cuál.es.la.segunda.red.social.en.que.pasa.más.tiempo?" ## [32] "p33..si.respondió.otra,.¿Cuál?" ``` --- ## Limpiar nombres de variables 1 ```r # Janitor #install.packages("janitor") library(janitor) datos <- janitor::clean_names(datos)# transformo todo a minúscula, quito tildes, saco signos, borro espacios ``` --- ## Limpiar nombres de variables ```r library(openxlsx) datos <- read.xlsx(xlsxFile = "base/Encuesta Estudiantes Antropología 2023 (respuestas).xlsx", startRow = 2) datos <- janitor::clean_names(datos) names (datos) ``` ``` ## [1] "marca_temporal" ## [2] "p02_edad_del_a_entrevistado" ## [3] "p03_genero_del_a_entrevistado_a" ## [4] "p04_ano_en_que_se_encuentra_de_la_carrera_1_2_3_4_5" ## [5] "p05_comuna_actual_de_residencia" ## [6] "p06_comuna_de_residencia_de_su_familia_nuclear_padres_hermanos_as_u_otros_as_cuidadores_o_en_la_que_vivio_la_mayor_parte_de_infancia_y_adolescencia" ## [7] "p07_ultimo_tipo_de_establecimiento_educativo_en_que_realizo_su_ensenanza_media" ## [8] "p08_puntaje_final_obtenido_en_la_prueba_de_seleccion_universitaria_ponderado_segun_carrera_elegida" ## [9] "p09_cual_de_estas_situaciones_describe_mejor_su_actividad_principal_durante_el_ultimo_mes" ## [10] "p10_indique_el_maximo_nivel_educativo_alcanzado_por_su_madre" ## [11] "p11_actualmente_su_madre_trabaja" ## [12] "p12_cual_es_la_ocupacion_u_oficio_actual_de_su_madre_describa_las_principales_tareas_y_funciones_en_el_puesto_de_trabajo_actual_de_su_madre" ## [13] "p13_indique_el_maximo_nivel_educativo_alcanzado_por_su_padre" ## [14] "p14_actualmente_su_padre_trabaja" ## [15] "p15_cual_es_la_ocupacion_u_oficio_actual_de_su_padre_describa_las_principales_tareas_y_funciones_en_el_puesto_de_trabajo_actual_de_su_padre" ## [16] "p17_quien_es_el_principal_sostenedor_a_de_su_hogar_actual_quien_aporta_mas_al_presupuesto_mensual" ## [17] "p18_en_la_sociedad_comunmente_existen_distintos_grupos_o_clases_sociales_las_personas_de_clase_social_alta_son_las_que_tienen_los_ingresos_mas_altos_el_mayor_nivel_de_educacion_y_los_trabajos_mas_valorados_las_personas_de_clase_social_baja_son_las_que_tienen_los_ingresos_mas_bajos_el_menor_nivel_de_educacion_y_los_trabajos_menos_valorados_entre_estas_clases_existen_otras_intermedias_segun_su_opinion_a_cual_de_los_siguientes_grupos_o_clases_sociales_pertenece_usted" ## [18] "p19_actualmente_en_su_casa_tienen_computador_ya_sea_notebook_o_de_escritorio" ## [19] "p20_actualmente_usted_tiene_computador_para_uso_personal_ya_sea_notebook_o_de_escritorio" ## [20] "p21_actualmente_usted_tiene_smartphone_personal" ## [21] "p22_con_que_frecuencia_escucha_musica" ## [22] "p23_que_tipo_de_musica_es_la_que_mas_prefiere_escuchar_aun_cuando_escuche_mas_de_un_estilo_elija_el_que_mas_escuche" ## [23] "p24_si_eligio_otra_cual" ## [24] "p25_cual_es_la_segunda_musica_que_mas_prefiere_escuchar" ## [25] "p26_si_eligio_otra_cual" ## [26] "p27_con_que_dispositivo_suele_escuchar_mas_musica" ## [27] "p28_cual_es_principal_sitio_programa_o_aplicacion_para_bajar_o_escuchar_musica" ## [28] "p29_si_respondio_otro_cual" ## [29] "p30_cual_es_la_red_social_en_que_pasa_mas_tiempo" ## [30] "p31_si_respondio_otra_cual" ## [31] "p32_y_cual_es_la_segunda_red_social_en_que_pasa_mas_tiempo" ## [32] "p33_si_respondio_otra_cual" ``` --- background-size: contain background-repeat: no-repeat background-position: center center background-image: url("img/limpieza2.png") --- ## Reducir nombres de variables 2 ### Existen nombres de variables muy largos, los quiero acortar. ```r names(datos) <- substring(names(datos), 1, 5) ``` El operador de asignación <- asigna el vector resultante de substring(names(datos), 1, 5) de vuelta a names(datos), reemplazando los nombres originales por los truncados. --- ## Limpiar nombres de variables ### Asignar nuevos nombres 4. Renombro algunas variables en específico Posibilidad de renombrar uno por uno las variables de interés. ```r libro_códigos <- read.xlsx(xlsxFile = "base/Encuesta Estudiantes Antropología 2023 (respuestas).xlsx", startRow = 2) names(libro_códigos) datos <- datos %>% dplyr::rename( # primero nuevo nombre y luego nombre antiguo edad = p02, genero = p03, annio = p04, comuna_actual = p05, comuna_pre= p06, tipo_colegio = p07, puntaje = p08, estudio_trabajo = p09, educacion_madre = p10, trabaja_madre =p11, empleo_madre =p12, educacion_padre =p13, trabaja_padre =p14, empleo_padre = p15, psdhogar = p17, clase_social_subjetiva = p18) ``` --- ## Limpiar nombres de variables Finalmente observo los nombres de mis nuevas variables ```r names(datos) ``` [1] "mar" "edad" "genero" [4] "annio" "comuna_actual" "comuna_pre" [7] "tipo_colegio" "puntaje" "estudio_trabajo" --- class: center, middle # 2.2 Transformación de contenido de casos --- ## Transformaciones/limpieza en variables numéricas Limpieza inicial de variables numéricas ```r table(datos$edad) # vemos el ingreso de una variable que dice "años" class (datos$edad) # Se considera "character" ``` > table(datos$edad) # vemos que hay un caso que dice "años" 19 20 21 22 23 24 años 30 1 8 4 3 3 1 1 > class (datos$edad) # Se considera "character" [1] "character" Lee la variable como `character` porque existe una observación que dice años --- ## Transformaciones/limpieza en variables numéricas Limpieza inicial de variables numéricas Eliminamos todo lo que no sea número de la variable numérica ```r datos$edad <- as.numeric(gsub("[^0-9]+", "", datos$edad)) # elimino todo lo que no es número ``` ## Explicación: * **[^0-9]** busca cualquier secuencia de caracteres que no sean dígitos (0-9) + los reemplaza con una cadena vacía "". + elimina cualquier carácter que no sea numérico de la columna "edad" + as.numeric: transforma en numérico. --- background-size: contain background-repeat: no-repeat background-position: center center background-image: url("img/asnumeric.png") --- ## Transformaciones/limpieza en variables numéricas Limpieza inicial de variables numéricas Finalmente se comprueba si la transformación resulta correctamente ```r class (datos$edad) # compruebo si es numérico table(datos$edad) # observo como quedó variable ``` .pull-left[ * class (datos$edad) # compruebo si es numérico * table(datos$edad) # observo como quedó variable ] .pull-right[ | Edad | Frecuencia | |-------------- | -------------- | | 19 | 1 | | 20 | 8 | | 21 | 4 | | 22 | 3 | | 23 | 3 | | 24 | 1 | | 30 | 1 | ] --- # Recodificación de variables Recodificación de tipo de medición de variable: paso de `numérica` a `ordinal` Existen 2 funciones que usamos de manera combinada, `mutate` y `case_when` ```r datos <- datos %>% mutate (edadr= case_when (edad %in% c(18:20) ~ "18 a 20", edad %in% c(21:23) ~ "21 a 23", edad >= 24 ~ "24 o más")) ``` + **mutate**: función para modificar/crear variables + **edadr**: variable nueva + **case_when**: argumumento al interior de mutate para decir, cuando se da "x" transformalo en "y" + **edad**: variable vieja + **~**: indica la modificación --- # Recordemos los operadores lógicos .pull-left[ | Operador | Descripción | Ejemplo | |----------|-------------------------|--------------------------------------| | == | Igual a | `edad == 5` | | != | No es igual a | `sexo != "F"` | | < | Menor que | `edad < 18` | | > | Mayor que | `edad > 18` | | <= | Menor o igual que | `edad <= 18` | | >= | Mayor o igual que | `edad >= 65` | | & | Y lógico (AND) | `sexo != "M" & edad <= 18` | ] .pull-left[ + **&**: AND: Cuando se cumplen ambas condiciones + **|**: OR: Cuando se cumple una u otra condición + **%in%**: Incluye. Lo que está a la izquierda está incluido en lo q está a la derecha ] --- # Transformación de variables Recodificación de tipo de medición de variable: paso de `numérica` a `ordinal`. Comparamos: ```r table(datos$edad) table(datos$edadr) ``` .pull-left[ > table(datos$edad) | Edad | Frecuencia | |-------------- | -------------- | | 19 | 1 | | 20 | 8 | | 21 | 4 | | 22 | 3 | | 23 | 3 | | 24 | 1 | | 30 | 1 | ] .pull-right[ > table(datos$edadr) | Edad recodificada | Frecuencia | |----------------- | -------------- | | 18 a 20 | 9 | | 21 a 23 | 10 | | 24 o más | 2 | + entonces: **¿Qué es recodificar?** ] --- background-size: contain background-repeat: no-repeat background-position: center center background-image: url("img/recode.png") --- ## Transformaciones/limpieza en variables cualitativas En las variables categóricas de pregunta abierta cada uno responde como quiere, por lo tanto exite el problema de homogeneizar las respuestas a estas variables para poder analizar posteriormente ```r table(datos$genero) table(datos$annio) table(datos$comuna_actual) #que cosa rara observa? table(datos$comuna_pre) #que cosa rara observa? ``` * ¿Cómo homogeneizo los valores escritos? + Algunos tienen mayúsculas y minusculas en diversas letras + Algunos usan tildes y otros no + Uno escribe `Santiago` y otro `Santiago centro` --- ## Transformaciones/limpieza en variables cualitativas Homogeinizo categorías de respuesta, sin tildes, en minúsculas y cambio espacios por guión bajo (_) ```r #saco caracteres típicos del español (ñ), elimino comas y espacios y pongo todo en minuscula datos <- datos %>% mutate(comuna_actual = stringi::stri_trans_general(comuna_actual, "Latin-ASCII"), comuna_actual = tolower (comuna_actual), comuna_actual = gsub(" ", "_", comuna_actual)) #Observo table(datos$comuna_actual) ``` + **mutate**: modifica o crea una variable + **comuna_actual**: variable nueva + **stri_trans_general(comuna_actual, "Latin-ASCII")**: borra tildes y ñ + **tolower (comuna_actual)**: transforma todo en minúscula + **comuna_actual = gsub(" ", "_", comuna_actual)**: cambia espacios a _ --- ## Transformaciones/limpieza en variables cualitativas Recodificar con `recode` permite recodificar de manera personalizada las categorías de la variable ```r #recodifico datos <- datos %>% mutate(comuna_actual = recode(comuna_actual, "puente_alto_" = "puente_alto", "santiago_centro" = "santiago", "san_felipe,_v_region" = "san felipe", "paine_" = "paine")) table(datos$comuna_actual) ``` + **mutate**: modifica o crea una variable + **comuna_actual**: variable nueva + **recode**: función para recodificar + **comuna_actual**: variable vieja (se pisan) + **la coma**: va separando las distintas recodificaciones + **valores viejos** = valores nuevos --- background-size: contain background-repeat: no-repeat background-position: center center background-image: url("img/Data_Wrangling.png") --- # Finalmente guardo mi base ```r dir.create(path = "output") write.xlsx(x = datos,file = "output/Encuesta_Antropología_Limpia") ``` + **dir.create**: crea un directorio nuevo + **write.xlsx**: crea una base de datos con las modificaciones realizadas --- background-size: contain background-repeat: no-repeat background-position: center center background-image: url("img/datos.png") ---  --- class: inverse, center, middle # Vamos a la sintaxis...