class: center, middle, titular background-size: contain <img style="border-radius: 50%;" src="img/masapp.jpg" width="250px"/> # Capítulo 2: Tipos de Datos en R ## **CAPACITACIÓN** #### LINDA CABRERA ORELLANA #### Mayo, 2023 --- .pull-left[ # Contenido del Capítulo 2 - Tipos de datos * Numéricos * Cadena de caracteres * Factores * Fechas y Horas - Práctica 3 ] .pull-right[ # Paquetes a utilizar *
`library(tidyverse)` *
`library(readr)` *
`library(lubridate)` ] --- class: middle, center, inverse
# Tipos de Datos --- <div class="figure" style="text-align: center"> <img src="img/tiposdatos.png" alt="Figura 2. Tipos de datos en R" width="100%" /> <p class="caption">Figura 2. Tipos de datos en R</p> </div> --- ## Sin corregir los tipos de datos <img src="img/tipo_incorrectoA.png" width="100%" style="display: block; margin: auto;" /> --- ## Corrigiendo los tipos de datos <img src="img/tipo_correctoA.png" width="100%" style="display: block; margin: auto;" /> --- ## Datos Numéricos .pull-left[ Para determinar el tipo de dato de un data set aplicamos la función `class()`. ```r # clase de un vector de 1 elemento class(5) ## [1] "numeric" # clase de la columna edades del dataset pacientes class(pacientes$edades) ## [1] "numeric" ``` Ahora, el vector `\(z\)` de tipo caracter lo convertiremos en tipo numérico. ```r z ## [1] "1" "5" "11" "14" class(z) ## [1] "character" ``` ] .pull-right[ ### Con `as.numeric()`. ```r # cambio de clase caracter a numérico con as.numeric() class(as.numeric(z)) ## [1] "numeric" ``` ### Con `parse_number()`. ```r library(readr) # cambio de clase caracter a numérico con parse_number() class(parse_number(z)) ## [1] "numeric" ``` ] --- ## Datos Numéricos .pull-left[ **`parse_number()`** es muy útil para resolver problemas de decimales, caracteres que acompañan a números y caracteres de agrupación. En R, por default, el decimal es el punto. A continuación, tiene dos argumentos que le pueden servir de ayuda: - `grouping_mark` para especificar el signo de agrupación; - `decimal_mark` para especificar el decimal a cambiar. ```r parse_number("6'789,56", locale = locale(grouping_mark = "'", decimal_mark = ",")) ## [1] 6789.56 ``` ] .pull-right[ También sirve para extraer números insertos en texto. ```r parse_number("$100") ## [1] 100 parse_number("20%") ## [1] 20 parse_number("It cost $123.45") ## [1] 123.45 parse_number("$123.456.789", locale = locale(grouping_mark = ".")) ## [1] 123456789 ``` ] --- <!-- ## Cadena de Caracteres .pull-left[ `readr` asume que tus datos están codificados en UTF-8. `charToRaw():` realiza una representación subyacente de una cadena de texto. ```r charToRaw("Linda") ## [1] 4c 69 6e 64 61 ``` ¿Qué sucede cuando tus datos producidos no entienden UTF-8? ```r library(readr) x1 <- "El Ni\xf1o was particularly bad this year" ``` ] .pull-right[ Para corregir el problema necesitas especificar la codificación en **`parse_character()`**: ```r parse_character(x1, locale = locale(encoding = "Latin1")) ## [1] "El Niño was particularly bad this year" ``` ¿Cómo encontrar la codificación correcta? Con `guess_encoding()` ```r guess_encoding(charToRaw(x1)) ## # A tibble: 2 × 2 ## encoding confidence ## <chr> <dbl> ## 1 ISO-8859-1 0.46 ## 2 ISO-8859-9 0.23 ``` ] .footnote[ [Tablas de codificación de caracteres](http://www.atc.uniovi.es/tablas.php)] ## Cadena de Caracteres .pull-left[ .center[ <img src="img/stringr.png" width="200px"> ] `stringr` proporciona un conjunto cohesivo de funciones diseñadas para trabajar de forma más fácil con cadenas de caracteres. ```r library(stringr) ``` ] .pull-right[ ```r frase <- "Esta es una cadena de caracteres" class(frase) ## [1] "character" ``` `str_length()` indica el número de caracteres de una cadena. ```r str_length(frase) ## [1] 32 ``` `str_c()` combina dos o más cadenas: ```r str_c(frase, " y esto también") ## [1] "Esta es una cadena de caracteres y esto también" ``` ] --> ## Cadena de Caracteres .pull-left[ Para convertir datos a tipo caracter usamos la función `as.character()`: ```r pacientes ## nombres edades seguro ## 1 Marcela Cox 24 IESS ## 2 Luis Vargas 32 BMI ## 3 David Mieles 27 IESS class(pacientes$seguro) ## [1] "factor" ## convertir de factor a tipo caracter pacientes$seguro <- as.character(pacientes$seguro) class(pacientes$seguro) ## [1] "character" ``` ] .pull-right[ Convertimos un dato tipo fecha a tipo caracter: ```r ## consultamos la función now() y su clase lubridate::now() ## [1] "2023-05-14 23:47:56 CEST" class(lubridate::now()) ## [1] "POSIXct" "POSIXt" ## convertimos a tipo caracter as.character(lubridate::now()) ## [1] "2023-05-14 23:47:56" class(as.character(lubridate::now())) ## [1] "character" ``` ] <br> <br> .footnote[ [stringr.tidyverse.org](https://stringr.tidyverse.org/) || [tidyverse/reprex](https://github.com/tidyverse/reprex)] --- ## Factores <!-- .pull-left[ .center[ <img src="img/forcats.png" width="200px"> ] `forcats` proporciona un conjunto de herramientas que resuelven problemas comunes con factores. ```r library(forcats) ``` ] --> .pull-left[ Imaginemos que tenemos la siguiente variable que registra meses: ```r fc1 <- c("Dic", "Abr", "Ene", "Mar") class(fc1) ## [1] "character" ``` Si trabajamos esta variable en tipo caracter, tendremos 2 problemas: 1. Errores de tipeo, 2. No se ordena de una forma útil. Estos problemas se solucionan trabajando con factores. ] .pull-right[ Para crear un factor con **`factor()`** debes: 1. Definir una lista de niveles válidos. ```r niveles_meses <- c("Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic") ``` 2. Ahorar puedes crear un factor. ```r y1 <- factor(fc1, levels = niveles_meses) class(y1) ## [1] "factor" # para acceder a los niveles del factor levels(y1) ## [1] "Ene" "Feb" "Mar" "Abr" "May" "Jun" "Jul" "Ago" "Sep" "Oct" "Nov" "Dic" ``` ] <br> .footnote[ [forcats.tidyverse.org](https://forcats.tidyverse.org/) || [Wrangling categorical data in R](https://peerj.com/preprints/3163/) || [stringsAsFactors = <sigh>](https://notstatschat.tumblr.com/post/124987394001/stringsasfactors-sigh) ] --- ## Fechas y Horas .pull-left[ **`parse_datetime()`** asume una fecha-hora ISO8601, estándar internacional en el que los componentes de una fecha están organizados de mayor a menor: año, mes, día, hora, minuto, segundo. ```r # Dato de fecha-hora fecha1 <- "2010-10-01T2010" parse_datetime(fecha1) ## [1] "2010-10-01 20:10:00 UTC" # Si se omite la hora, será determinada como medianoche. fecha2 <- "20101010" parse_datetime(fecha2) ## [1] "2010-10-10 UTC" ``` ] .pull-right[ **`parse_date()`** asume aaaa-mm-dd o aaaa/mm/dd. ```r fecha3 <- "2010-10-01" parse_date(fecha3) ## [1] "2010-10-01" ``` **`parse_time()`** espera la hh:mm:ss, los segundos y el especificador am/pm son opcionales. ```r library(hms) parse_time("01:10 am") ## 01:10:00 parse_time("20:10:01") ## 20:10:01 ``` ] <br> <br> .footnote[ [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) || [hms.tidyverse.org](https://hms.tidyverse.org/)] --- ## Fechas y Horas .pull-left[ .center[ <img src="img/lubridate.png" width="200px"> ] `lubridate` hace que sea más fácil hacer las cosas que hace R con fecha y hora y hace posible hacer las cosas que R base no hace. ```r library(lubridate) ``` ] .pull-right[ Hay tres tipos de datos de fechas/horas que se refieren a un instante en el tiempo: * Una fecha o `date`. * Una hora o `time` dentro de un día. * Una fecha-hora o date-time `dttm` (llamado también `POSIXct`). Para obtener la fecha o fecha-hora actual utiliza `today()` o `now()`: ```r today() ## [1] "2023-05-14" now() ## [1] "2023-05-14 23:47:57 CEST" ``` ] <br> .footnote[ [lubridate.tidyverse.org](https://lubridate.tidyverse.org/) || [hms.tidyverse.org](https://hms.tidyverse.org/) ] --- ## Fechas y Horas .pull-left[ Hay tres modos en los que puedes crear una fecha/hora: * Desde una cadena de caracteres (o string, en inglés). * Desde componentes de fecha-hora individuales. * Desde un objeto fecha-hora existente. ### Desde cadenas de caracteres ```r ymd("2017-01-31") ## [1] "2017-01-31" ymd("20170131") ## [1] "2017-01-31" ``` ] .pull-right[ ```r mdy("01-31-2017") ## [1] "2017-01-31" mdy("01312017") ## [1] "2017-01-31" dmy("31-01-2017") ## [1] "2017-01-31" dmy("31012017") ## [1] "2017-01-31" mdy_hm("01/31/2017 08:01") ## [1] "2017-01-31 08:01:00 UTC" ymd_hms("2017-01-31 20:11:59") ## [1] "2017-01-31 20:11:59 UTC" ``` ] --- ## Fechas y Horas .pull-left[ ### Desde componentes individuales Crearé un data.frame donde las fechas y las horas están repartidos en diferentes columnas. ```r ejemplo <- data.frame(anio= c(1994, 1992, 1987), dia= c(21, 02, 15), mes= c(02, 04, 05), hora= c(20, 14, 09), minuto= c(45, 30, 15)) ejemplo ## anio dia mes hora minuto ## 1 1994 21 2 20 45 ## 2 1992 2 4 14 30 ## 3 1987 15 5 9 15 ``` ] .pull-right[ `make_date()` para crear fecha. ```r # forma fecha que contiene dia, mes y anio make_date(ejemplo$anio, ejemplo$mes, ejemplo$dia) ## [1] "1994-02-21" "1992-04-02" "1987-05-15" ``` `make_datetime()` para crear fecha-hora. ```r # forma fecha-hora make_datetime(ejemplo$anio, ejemplo$mes, ejemplo$dia, ejemplo$hora, ejemplo$minuto) ## [1] "1994-02-21 20:45:00 UTC" "1992-04-02 14:30:00 UTC" ## [3] "1987-05-15 09:15:00 UTC" ``` ### Desde otros tipos ```r as_datetime(today()) as_date(now()) ``` ] --- background-color: var(--azul-claro) class: middle, center, inverse
## PRÁCTICA 3 --- #
Práctica: ¡10 minutos! 1. Modificar el tipo de dato de las variables _"VENTAS_NETAS_TARIFA_12", "VENTAS_NETAS_TARIFA_0", "EXPORTACIONES", "COMPRAS_ENTAS_TARIFA_12", "COMPRAS_NETAS_TARIFA_0", "IMPORTACIONES", "COMPRAS_RISE", "TOTAL_COMPRAS", "TOTAL_VENTAS"_. 2. Convertir los meses en un vector tipo factor y modificar los niveles al nombre abreviado de cada mes. --- class: middle, center, inverse <br> <br> # Tipos de Datos en R ## **CAPÍTULO 2** <br> <br> .center[ ### [@MasappEC
](https://www.facebook.com/MasappEC/) ### [@Masappdata
](https://twitter.com/Masappdata) ]