library(tidyverse)
2 Primeros pasos con tidyverse
2.1 Presentación
2.2 Comprendiendo nuestra data
La primera etapa del Análisis Exploratorio de Datos (EDA) en Machine Learning se centra en los pasos básicos con tidyverse, ya que este ecosistema de herramientas facilita la importación, organización y transformación de la información. En este punto, resulta esencial familiarizarnos con la estructura de los datos, reconocer las variables disponibles y aplicar operaciones que nos permitan manipular y preparar la base de forma eficiente. Este proceso no solo brinda una comprensión profunda de la data, sino que también sienta los cimientos para un análisis riguroso y para el éxito de las fases posteriores de modelamiento.
Te sugiero ver este video introductorio sobre el Tidyverse:
Abrimos la librería tidyverse:
dplyr
es un paquete del Tidyverse que sirve para manipular tablas y transformarlas. Tiene una amplia gama de verbos con los cuales podemos realizar las tareas más recurrentes de la manipulación de datos.
2.2.1 Importación de archivos
Podríamos abrir este archivo con la función read_xlsx()
:
library(readxl)
<-read_xlsx("data/CPI.xlsx") data
Visualizamos la data y solicitamos que nos diga la clase:
data
# A tibble: 1,086 × 5
country year iso3 region cpi_score
<chr> <dbl> <chr> <chr> <dbl>
1 Afghanistan 2022 AFG AP 24
2 Albania 2022 ALB ECA 36
3 United Arab Emirates 2022 ARE MENA 67
4 Angola 2022 AGO SSA 33
5 Argentina 2022 ARG AME 38
6 Armenia 2022 ARM ECA 46
7 Australia 2022 AUS AP 75
8 Austria 2022 AUT WE/EU 71
9 Azerbaijan 2022 AZE ECA 23
10 Bahamas 2022 BHS AME 64
# ℹ 1,076 more rows
class(data)
[1] "tbl_df" "tbl" "data.frame"
Un tibble es una versión moderna del dataframe en R, parte del tidyverse, diseñado para facilitar el trabajo con datos tabulares.
Exploración del dataset y configuración de variables
Vemos la estructura rápidamente:
str(data)
tibble [1,086 × 5] (S3: tbl_df/tbl/data.frame)
$ country : chr [1:1086] "Afghanistan" "Albania" "United Arab Emirates" "Angola" ...
$ year : num [1:1086] 2022 2022 2022 2022 2022 ...
$ iso3 : chr [1:1086] "AFG" "ALB" "ARE" "AGO" ...
$ region : chr [1:1086] "AP" "ECA" "MENA" "SSA" ...
$ cpi_score: num [1:1086] 24 36 67 33 38 46 75 71 23 64 ...
Al ejecutar names() sobre un conjunto de datos, se nos devuelve un vector con los nombres de todas las columnas en el orden en que aparecen.
names(data)
[1] "country" "year" "iso3" "region" "cpi_score"
Antes de proseguir con el análisis exploratorio de datos, es fundamental que comprendas claramente qué representan las filas y las columnas en tus datos.
Corroboramos que el score del AML esté adecuadamente configurado.
class(data$cpi_score)
[1] "numeric"
De acuerdo, podemos proseguir.
Examinemos la base original. Vamos a editar la tabla con diversos verbos de dplyr
.
2.2.2 Select()
La función select() es utilizada para seleccionar o excluir columnas de un data frame o tibble en R. Va más allá de simplemente escoger columnas por nombre, ya que permite una amplia gama de criterios y operaciones.
Funcionamiento básico:
Entrada: Un data frame o tibble y un conjunto de nombres de columnas o criterios para seleccionar columnas.
Salida: Un objeto de la misma clase que el de entrada (data frame o tibble) que contiene solo las columnas seleccionadas.
Vamos a seleccionar sólo ciertas columnas:
<-data |>
data1select(country, year, region, cpi_score)
data1
# A tibble: 1,086 × 4
country year region cpi_score
<chr> <dbl> <chr> <dbl>
1 Afghanistan 2022 AP 24
2 Albania 2022 ECA 36
3 United Arab Emirates 2022 MENA 67
4 Angola 2022 SSA 33
5 Argentina 2022 AME 38
6 Armenia 2022 ECA 46
7 Australia 2022 AP 75
8 Austria 2022 WE/EU 71
9 Azerbaijan 2022 ECA 23
10 Bahamas 2022 AME 64
# ℹ 1,076 more rows
Tener en cuenta que puedes:
Seleccionar por nombre
Seleccionar por el número de la columna
(Des)seleccionar colocando un “-” antes del nombre/número de columna.
Seleccionar un rango colocando por ejemplo 2:4 lo que significa “desde la columna 2 hasta la columna 4).
Puedes combinar todas las anteriores y tener más de un criterio a la vez separándolo por coma.
2.2.3 Filter()
La función filter() se utiliza para filtrar filas de un data frame o tibble en R en función de condiciones específicas, permitiendo crear un subconjunto de datos.
Al crear subconjuntos nuestros datos de forma precisa, podemos focalizar nuestro análisis, mejorar la eficiencia computacional y obtener resultados más claros y relevantes.
Características principales:
Condiciones múltiples: Puedes usar múltiples condiciones para filtrar tus datos. Estas se combinan utilizando operadores lógicos como & (y), | (o) y ! (no).
Uso de operadores de comparación: Los operadores estándar como ==, >, <, >=, <=, y != se utilizan para establecer condiciones.
Funciones auxiliares: dplyr proporciona funciones como between(), que pueden ser útiles para establecer condiciones. Por ejemplo, between(x, 1, 10) es equivalente a x >= 1 & x <= 10.
En este caso vamos a seleccionar aquellos países cuya medición es del año 2022.
<-data1 %>%
data2filter(year==2022)
data2
# A tibble: 181 × 4
country year region cpi_score
<chr> <dbl> <chr> <dbl>
1 Afghanistan 2022 AP 24
2 Albania 2022 ECA 36
3 United Arab Emirates 2022 MENA 67
4 Angola 2022 SSA 33
5 Argentina 2022 AME 38
6 Armenia 2022 ECA 46
7 Australia 2022 AP 75
8 Austria 2022 WE/EU 71
9 Azerbaijan 2022 ECA 23
10 Bahamas 2022 AME 64
# ℹ 171 more rows
2.2.4 Arrange()
Se utiliza para ordenar (o reordenar) un data frame o tibble según una o más columnas.
Funcionamiento básico:
Ordenación simple: Si proporcionas una columna a arrange(), ordenará el data frame en función de esa columna en orden ascendente por defecto.
Ordenación descendente: Si deseas ordenar en dirección descendente, puedes usar la función desc(). Por ejemplo: df |> arrange(desc(edad)) ordenará el data frame por la columna “edad” en orden descendente.
Ordenación múltiple: Puedes proporcionar múltiples columnas para ordenar, y arrange() las usará en el orden proporcionado para determinar el ordenamiento. Por ejemplo, si deseas ordenar primero por “grupo” y luego por “edad” dentro de cada grupo, usarías: df |> arrange(grupo, edad).
<-data2 |>
data3arrange(desc(cpi_score))
data3
# A tibble: 181 × 4
country year region cpi_score
<chr> <dbl> <chr> <dbl>
1 Denmark 2022 WE/EU 90
2 Finland 2022 WE/EU 87
3 New Zealand 2022 AP 87
4 Norway 2022 WE/EU 84
5 Singapore 2022 AP 83
6 Sweden 2022 WE/EU 83
7 Switzerland 2022 WE/EU 82
8 Netherlands 2022 WE/EU 80
9 Germany 2022 WE/EU 79
10 Ireland 2022 WE/EU 77
# ℹ 171 more rows
2.2.5 Mutate()
La función mutate() está diseñada para crear o modificar columnas dentro de un data frame o tibble en R. Mientras que el data frame original se mantiene inalterado, mutate() devuelve una copia con las columnas especificadas añadidas o alteradas.
En este caso vamos a crear una variable cambiando la escala del score del CPI.
En la medida original 0 representaba alta corrupción y 100 escasa corrupción. Ahora, si realizamos la operación “100 - cpi_score”, los valores cercanos a 0 tendrán poca corrupción y los cercanos a 100 alta corrupción, siendo más intuitivo.
Esta transformación puede ser útil para ajustar la interpretación de los datos a contextos donde es más intuitivo trabajar con escalas donde un número mayor indica mayor intensidad de un fenómeno (Corrupción, en este caso), dependiendo del análisis que se desea realizar.
<-data3 |>
data4mutate(cpi_score2=100-cpi_score)
data4
# A tibble: 181 × 5
country year region cpi_score cpi_score2
<chr> <dbl> <chr> <dbl> <dbl>
1 Denmark 2022 WE/EU 90 10
2 Finland 2022 WE/EU 87 13
3 New Zealand 2022 AP 87 13
4 Norway 2022 WE/EU 84 16
5 Singapore 2022 AP 83 17
6 Sweden 2022 WE/EU 83 17
7 Switzerland 2022 WE/EU 82 18
8 Netherlands 2022 WE/EU 80 20
9 Germany 2022 WE/EU 79 21
10 Ireland 2022 WE/EU 77 23
# ℹ 171 more rows
2.2.6 Summarise()
Se utiliza para crear resúmenes estadísticos de un data frame o tibble.
Dentro de los resúmenes puedes disponer de por ejemplo:
Medidas de tendencia central: Estas funciones describen un valor central o típico dentro de un conjunto de datos.
- Media: mean(x)
- Mediana: median(x)
Cómo calcularíamos la media de forma directa (tradicional)?
summary(data4$cpi_score2)
Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
10.00 45.00 60.50 57.02 70.25 88.00 1
¿Qué significa NA´s? ¿Por qué se produce esto en una data como la de Corruption Perception Index?
Cómo lo calculamos con tidyverse?
|>
data4 summarise(mean(cpi_score2, na.rm = T))
# A tibble: 1 × 1
`mean(cpi_score2, na.rm = T)`
<dbl>
1 57.0
Cuando aplicamos un summarise lo que nos devuelve es un valor o conjunto de valores. Por otro lado, el argumento na.rm = TRUE se utiliza para especificar que los valores perdidos (NA) deben ser ignorados en el cálculo. De esta forma, le indicamos a la función que proceda con la operación excluyendo dichos valores ausentes.
2.2.7 Utilizando pipe: |>
Probablemente hayas observado que hemos creado un conjunto de datos para cada verbo utilizado, lo cual en situaciones reales resultaría excesivamente repetitivo. Haciendo una analogía con la escritura de un libro, sería como si estuviéramos limitados a usar únicamente oraciones, lo cual haría el proceso tedioso.
El operador |> (pipe) en R, introducido en la versión 4.1, permite realizar operaciones en cadena, facilitando la secuencia de funciones y transformaciones en un flujo más legible y ordenado.
Es evidente que, mediante el uso del operador pipe, podemos encadenar verbos de manera fluida y evitar la creación innecesaria de objetos, ya que este operador permite que el resultado a la izquierda se convierta automáticamente en el argumento de la función a la derecha.
|>
data select(country, year, region, cpi_score) |>
filter(year==2022) |>
arrange(desc(cpi_score)) |>
mutate(cpi_score2=100-cpi_score) |>
summarise(mean(cpi_score2, na.rm=T))
# A tibble: 1 × 1
`mean(cpi_score2, na.rm = T)`
<dbl>
1 57.0
¿Qué sucede si a esta cadena de pipes le doy un nombre? ¿Cuál sería el objeto creado?
<-data |>
data_finalselect(country, year, region, cpi_score) |>
filter(year==2022) |>
arrange(desc(cpi_score)) |>
mutate(cpi_score2=100-cpi_score)
2.2.8 Agrupando con group_by()
Se utiliza para dividir un conjunto de datos en grupos según valores de una o más variables (normalmente de tipo categórica). Una vez que los datos están agrupados, es posible realizar operaciones específicas dentro de cada grupo.
|>
data group_by(year) |>
summarise(Media=mean(cpi_score, na.rm = T))
# A tibble: 6 × 2
year Media
<dbl> <dbl>
1 2017 43.1
2 2018 43.1
3 2019 43.2
4 2020 43.3
5 2021 43.3
6 2022 43.0
2.2.9 Contar con count()
Facilita el conteo de observaciones dentro de categorías específicas de una o más variables en un dataframe. Esta función agrupa el conjunto de datos por las variables especificadas y luego calcula el número de observaciones dentro de cada categoría, retornando un nuevo dataframe con las categorías y sus respectivos conteos. Es una herramienta esencial para obtener resúmenes rápidos y frecuencias de variables categóricas en datos estructurados.
|>
data_final count(region) |>
arrange(desc(n))
# A tibble: 6 × 2
region n
<chr> <int>
1 SSA 49
2 AME 32
3 AP 32
4 WE/EU 31
5 ECA 19
6 MENA 18
En la última línea de código, indicamos a R que ordene los datos de acuerdo a la variable ‘n’, la cual fue definida en la línea de código precedente. Es importante recordar que la ejecución de acciones o funciones en R se realiza de manera secuencial y acumulativa.
2.2.10 Renombrar con rename()
Permite cambiar los nombres de las columnas de un dataframe. Para ello, se especifica el nuevo nombre deseado y el nombre actual de la columna. Esta función es útil cuando se necesita ajustar o estandarizar los nombres de las columnas en un conjunto de datos, facilitando así análisis posteriores y asegurando la claridad y consistencia en la manipulación de los datos.
Primero debes escribir el nuevo nombre y luego el nombre original de la variable.
|>
data_final rename(zona=region) # Renombro la columna "region" (nombre original) como "zona" (nombre nuevo)
# A tibble: 181 × 5
country year zona cpi_score cpi_score2
<chr> <dbl> <chr> <dbl> <dbl>
1 Denmark 2022 WE/EU 90 10
2 Finland 2022 WE/EU 87 13
3 New Zealand 2022 AP 87 13
4 Norway 2022 WE/EU 84 16
5 Singapore 2022 AP 83 17
6 Sweden 2022 WE/EU 83 17
7 Switzerland 2022 WE/EU 82 18
8 Netherlands 2022 WE/EU 80 20
9 Germany 2022 WE/EU 79 21
10 Ireland 2022 WE/EU 77 23
# ℹ 171 more rows
2.2.11 Recodificar con case_when()
La función case_when() del paquete tidyverse en R sirve para recodificar datos y crear nuevas variables o modificar variables existentes basándose en múltiples condiciones.
Permite evaluar varias condiciones utilizando una sintaxis similar a una instrucción “if-else”. Esta función es particularmente útil cuando necesitamos recodificar una variable en varias categorías o cuando tenemos múltiples condiciones a evaluar.
Se coloca primero la condición (fórmula) seguido del símbolo ~ (alt+126) y la etiqueta.
Al final se coloca TRUE, lo que indica todos aquellos casos que no cumplen con las condiciones anteriores.
summary(data_final$cpi_score2)
Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
10.00 45.00 60.50 57.02 70.25 88.00 1
<-data_final |>
data_finaldrop_na(cpi_score2)
summary(data_final$cpi_score2)
Min. 1st Qu. Median Mean 3rd Qu. Max.
10.00 45.00 60.50 57.02 70.25 88.00
Podemos realizar:
<-data_final |>
data_finalmutate(corrupcion=case_when(cpi_score2<30~"Bajo",
<60~"Medio",
cpi_score2<=100~"Alto")) cpi_score2
Le asignamos la configuración adecuada:
$corrupcion<-factor(data_final$corrupcion,
data_finallevels = c("Bajo", "Medio", "Alto"),
ordered = TRUE)
Finalmente, ya contamos una nueva nueva variable ordinal creada a partir de una variable numérica:
str(data_final$corrupcion)
Ord.factor w/ 3 levels "Bajo"<"Medio"<..: 1 1 1 1 1 1 1 1 1 1 ...