class: center, middle, titular background-size: contain <img style="border-radius: 50%;" src="img/logofundapi.jpg" width="250px"/> # Capítulo 2: Estructuras y Tipos de Datos ## **CAPACITACIÓN** #### LINDA CABRERA ORELLANA #### Mayo, 2024 --- # Contenido del Capítulo 2 - Estructuras de datos * Vectores * Data.frames (Tibbles) * Funciones básicas - Tipos de datos * Numéricos * Cadena de caracteres * Factores * Fechas y Horas --- class: middle, center, inverse
# Estructuras de Datos --- ## Estructuras de datos - Objetos Las estructuras de datos más usadas son: Vector, Matriz, Data.frame o Tibble, Listas, Series de tiempo, Data.table <img style="border-radius: 50%;" src="img/estructuras.png" width="1050px"/> --- ## Vectores .pull-left[ El tipo de dato fundamental en R es el vector. Un vector es una secuencia de elementos de datos todos del mismo tipo. Creamos un vector de dimensión 1: ```r x <- 4 is.vector(x) #¿es vector? ## [1] TRUE ``` Hay varias formas de crear vectores, pero una de las más comunes es el operador de concatenación `c()`. A continuación creamos un vector de 4 elementos de tipo numérico: ```r y <- c(11, 13, 15, 20) ``` ] .pull-right[ Con la función `is.vector()` identificamos que el objeto corresponde a un vector: ```r is.vector(y) ## [1] TRUE y # imprimir el contenido del objeto ## [1] 11 13 15 20 ``` También podemos crear un vector de tipo caracter de 4 elementos: ```r z <- c("1", "5", "11", "14") z ## [1] "1" "5" "11" "14" is.vector(z) ## [1] TRUE ``` ] --- ## Vectores .pull-left[ También podemos realizar operaciones entre vectores de la misma dimensión: ```r w <- c(2, 5, 6, 8) w ## [1] 2 5 6 8 y + 2*w - 3 ## [1] 12 20 24 33 ``` Para conocer la longitud de un vector usamos `length()`. ```r length(y) ## [1] 4 ``` ] .pull-right[ Podemos llamar elementos específicos de un vector usando la **indexación**. Por ejemplo: * `x[]` es una forma de llamar a un elemento específico de un vector. * `x[3]` es el tercer elemento. * `x[-3]` es un vector con todo menos el tercer elemento. Vamos a intentar indexar los vectores que tenemos: ```r # extraigo el segundo elemento del vector w w[2] ## [1] 5 # imprimo el vector w, excepto su tercer elemento w[-3] ## [1] 2 5 8 ``` ] --- ## Data.frames .pull-left[ Un data frame es un conjunto de vectores que deben cumplir las siguientes propiedades: - Las componentes son **vectores** - Cada vector puede ser de un **tipo de dato** distinto - Cada columna es una **variable** - Las columnas tienen la misma **longitud** Las _filas_ se denominan **observaciones** y las _columnas_ se denominan **variables**. ] .pull-right[ .center[ <img src="img/dataframe.png" width="700px"> Artwork by @allison_horst ] ] --- ## Data.frames .pull-left[ ### Crear un data.frame `data.frame()` crea data.frames a partir de la unión de vectores creados previamente. ```r nombres <- c("Marcela Cox", "Luis Vargas", "David Mieles") edades <- c(24,32,27) seguro <- factor(c("IESS", "BMI", "IESS")) pacientes <- data.frame(nombres, edades, seguro) pacientes ## nombres edades seguro ## 1 Marcela Cox 24 IESS ## 2 Luis Vargas 32 BMI ## 3 David Mieles 27 IESS ``` Ver objeto creado en el panel `Environment`. ] .pull-right[ ### Cambiar nombre de columnas * Desde la creación del data.frame: ```r pacientes2 <- data.frame(N1=nombres, N2=edades, seguro) pacientes2 ## N1 N2 seguro ## 1 Marcela Cox 24 IESS ## 2 Luis Vargas 32 BMI ## 3 David Mieles 27 IESS ``` * En un data.frame existente con `names()`: ```r names(pacientes2) <- c("Name", "Age", "Insurance") pacientes2 ## Name Age Insurance ## 1 Marcela Cox 24 IESS ## 2 Luis Vargas 32 BMI ## 3 David Mieles 27 IESS ``` ] --- ## Data.frames .pull-left[ ### Seleccionar elementos Al igual que los vectores podemos seleccionar elementos de un data.frame con la ayuda de corchetes `[]`. Al usar una coma, puede indicar qué seleccionar de las filas y las columnas respectivamente. Por ejemplo, supongamos que queremos extraer la edad de David Mieles: .center[ <img src="img/dataframe2.png" width="750px"> ] ] .pull-right[ La edad de David Mieles se ubica en la fila 3 y la columna 2: ```r pacientes[3,2] ## [1] 27 ``` ### Otros usos - `nombre_dataframe[1,2]` selecciona el valor en la primera fila y la segunda columna en `nombre_dataframe`. - `nombre_dataframe[1:3,2:4]` selecciona las filas 1, 2, 3 y las columnas 2, 3, 4 en `nombre_dataframe`. - A veces desea seleccionar todos los elementos de una fila o columna. Por ejemplo, `nombre_dataframe[1, ]` selecciona todos los elementos de la primera fila. ] --- ## Data.frames .pull-left[ ### Seleccionar columnas También podemos consultar a R por los valores de una columna entera de nuestro data set con el símbolo `$`. ```r pacientes$nombres ## [1] "Marcela Cox" "Luis Vargas" "David Mieles" ``` Y aplicar una función a esa columna: ```r mean(pacientes$edades) ## [1] 27.66667 ``` ] .pull-right[ ### Ordenando elementos En el análisis de datos, puede ordenar sus datos de acuerdo con una determinada variable en el conjunto de datos. `order()` es una función que le da la posición clasificada de cada elemento cuando se aplica a una variable, como un vector, por ejemplo: ```r ## podemos ordenar los elementos de vectores order(pacientes$edades) ## [1] 1 3 2 ## podemos ordenar los elementos de la columna de un data.frame pacientes[order(edades),] ## nombres edades seguro ## 1 Marcela Cox 24 IESS ## 3 David Mieles 27 IESS ## 2 Luis Vargas 32 BMI ``` ] --- ## Funciones básicas para explorar data.frames .pull-left[ * **`str():`** muestra de forma compacta la estructura interna de un objeto R. * **`colnames():`** muestra el nombre de las variables de un data.frame. * **`head():`** muestra las 10 primeras obervaciones del conjunto de datos. * **`tail():`** muestra las 4 últimas observaciones del conjunto de datos. ] .pull-right[ * **`summary():`** produce resúmenes de resultados de varias variables. Los resultados dependen de la clase de datos. * **`sum():`** devuelve la suma de todos los valores presentes en sus argumentos. * **`min():`** devuelve el valor mínimo de un vector numérico. * **`max():`** devuelve el valor máximo de un vector numérico. ] --- 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> --- ## 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 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" ``` <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] "2024-05-13" now() ## [1] "2024-05-13 20:48:28 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" ``` ] --- class: middle, center, inverse <br> <br> # Estructuras y Tipos de Datos ## **CAPÍTULO 2** <br> <br> .center[ ### [@lindateachtech
](https://www.linkedin.com/in/lindateachtech/) ### [@lindateachtech
](https://twitter.com/lindateachtech) ]