Proceso del Tidyverse
La manipulación de datos es parte del proceso de Data Wrangling. En
esta sección veremos algunos paquetes que nos servirán para manipular
los datos antes del análisis exploratorio de datos, entre ellos,
dplyr (una de las herramientas más importantes en el data
wrangling), magrittr, lubridate,
stringr y forcats.
El paquete magrittr ofrece un conjunto de operadores que
hacen que su código sea más legible al:
Estructurar secuencias de operaciones de datos de izquierda a derecha (a diferencia de desde adentro hacia afuera).
Minimizando la necesidad de variables locales y definiciones de funciones, y
Facilitando la adición de pasos en cualquier lugar de la secuencia de operaciones.
Puedes encontrar más información del paquete magrittr en
magrittr.tidyverse.org
Puede utilizar el atajo de teclado Ctrl+Shift+M para
generar el operador %>%. Ejemplo: Genere una vista en el
editor de scripts de las primeras 5 observaciones de las columnas de
Transacción y Tiempo_Servicio_seg de la Data banco.
library(magrittr)
##
## Attaching package: 'magrittr'
## The following object is masked from 'package:purrr':
##
## set_names
## The following object is masked from 'package:tidyr':
##
## extract
banco %>% select(Transaccion, Tiempo_Servicio_seg) %>% head(5)
## # A tibble: 5 × 2
## Transaccion Tiempo_Servicio_seg
## <chr> <dbl>
## 1 Cobro/Pago (Cta externa) 311
## 2 Cobro/Pago (Cta externa) 156
## 3 Cobro/Pago (Cta externa) 248
## 4 Cobro/Pago (Cta externa) 99
## 5 Cobro/Pago (Cta externa) 123
str(banco)
dplyrEl paquete dplyr proporciona un vocabulario intuitivo
para ejecutar tareas de gestión y análisis de datos.
La visualización de datos es una herramienta importante para la
generación de conocimiento; sin embargo, es raro que obtengas los datos
exactamente en la forma en que los necesitas, por lo que previamente
tendrás que crear algunas variables nuevas o resúmenes, o tal vez solo
quieras cambiar el nombre de las variables o reordenar las observaciones
para facilitar el trabajo con los datos, o agrupar las observaciones y
todo esto es lo que te ayuda a hacer dplyr.
Puedes encontrar más información del paquete dplyr en dplyr.tidyverse.org
El paquete proporciona un conjunto de verbos (funciones) para
describir y realizar tareas comunes de preparación de datos.
Específicamente, la gramática dplyr le permite hablar y
realizar fácilmente tareas como las siguientes:
select() -> Seleccionar características específicas
(columnas) de interés de un conjunto de datos.filter() -> Filtrar los datos irrelevantes y
mantenga solo las observaciones (filas) de interés.mutate() -> Mutar un conjunto de datos agregando más
características (columnas).arrange() -> Organizar las observaciones (filas) en
un orden particularsummarise() -> Resumir los datos en términos de
agregados como la media, la mediana o el máximo.group_by() -> Todos esta funciones se pueden usar
junto con group_by(), que cambia el alcance de cada función de operar en
todo el conjunto de datos a operar en él grupo por grupo.Estas seis funciones proporcionan los verbos para un lenguaje de manipulación de datos.
Recuerda que para visualizar los datos en el editor de scripts en
RStudio es mejor utilizar view().
select()select() permite seleccionar rápidamente un subconjunto
útil utilizando operaciones basadas en los nombres de las variables.
Para seleccionar las columnas por nombre:
banco %>% select(Transaccion, Tiempo_Servicio_seg)
## # A tibble: 24,299 × 2
## Transaccion Tiempo_Servicio_seg
## <chr> <dbl>
## 1 Cobro/Pago (Cta externa) 311
## 2 Cobro/Pago (Cta externa) 156
## 3 Cobro/Pago (Cta externa) 248
## 4 Cobro/Pago (Cta externa) 99
## 5 Cobro/Pago (Cta externa) 123
## 6 Cobro/Pago (Cta externa) 172
## 7 Cobro/Pago (Cta externa) 140
## 8 Cobro/Pago (Cta externa) 247
## 9 Cobro/Pago (Cta externa) 183
## 10 Cobro/Pago (Cta externa) 91
## # … with 24,289 more rows
Para seleccionar todas las columnas entre Transacción y Monto:
banco %>% select(Transaccion:Monto)
## # A tibble: 24,299 × 4
## Transaccion Tiempo_Servicio_seg Satisfaccion Monto
## <chr> <dbl> <fct> <dbl>
## 1 Cobro/Pago (Cta externa) 311 Muy Bueno 2889.
## 2 Cobro/Pago (Cta externa) 156 Malo 1671.
## 3 Cobro/Pago (Cta externa) 248 Regular NA
## 4 Cobro/Pago (Cta externa) 99 Regular 1765.
## 5 Cobro/Pago (Cta externa) 123 Muy Bueno 1836.
## 6 Cobro/Pago (Cta externa) 172 Bueno 2165.
## 7 Cobro/Pago (Cta externa) 140 Regular 1305.
## 8 Cobro/Pago (Cta externa) 247 Bueno 4080.
## 9 Cobro/Pago (Cta externa) 183 Muy Bueno 2541.
## 10 Cobro/Pago (Cta externa) 91 Muy Bueno 2219.
## # … with 24,289 more rows
Para seleccionar todas las columnas excepto aquellas entre Transacción y Monto:
banco %>% select(-(Transaccion:Monto))
## # A tibble: 24,299 × 3
## Sucursal Cajero ID_Transaccion
## <dbl> <dbl> <chr>
## 1 62 4820 2
## 2 62 4820 2
## 3 62 4820 2
## 4 62 4820 2
## 5 62 4820 2
## 6 62 4820 2
## 7 62 4820 2
## 8 62 4820 2
## 9 62 4820 2
## 10 62 4820 2
## # … with 24,289 more rows
Existen argumentos auxiliares para seleccionar bajo otros criterios, por ejemplo, para seleccionar columnas cuyos nombres inician con “s”:
banco %>% select(starts_with("s"))
## # A tibble: 24,299 × 2
## Sucursal Satisfaccion
## <dbl> <fct>
## 1 62 Muy Bueno
## 2 62 Malo
## 3 62 Regular
## 4 62 Regular
## 5 62 Muy Bueno
## 6 62 Bueno
## 7 62 Regular
## 8 62 Bueno
## 9 62 Muy Bueno
## 10 62 Muy Bueno
## # … with 24,289 more rows
Para seleccionar columnas cuyos nombres contienen “sa”
banco %>% select(contains("sa"))
## # A tibble: 24,299 × 4
## Sucursal ID_Transaccion Transaccion Satisfaccion
## <dbl> <chr> <chr> <fct>
## 1 62 2 Cobro/Pago (Cta externa) Muy Bueno
## 2 62 2 Cobro/Pago (Cta externa) Malo
## 3 62 2 Cobro/Pago (Cta externa) Regular
## 4 62 2 Cobro/Pago (Cta externa) Regular
## 5 62 2 Cobro/Pago (Cta externa) Muy Bueno
## 6 62 2 Cobro/Pago (Cta externa) Bueno
## 7 62 2 Cobro/Pago (Cta externa) Regular
## 8 62 2 Cobro/Pago (Cta externa) Bueno
## 9 62 2 Cobro/Pago (Cta externa) Muy Bueno
## 10 62 2 Cobro/Pago (Cta externa) Muy Bueno
## # … with 24,289 more rows
Set completo de operadores booleanos
Ahora puedo combinar algunos argumentos, por ejemplo, para seleccionar columnas cuyos nombres inician con “s” o terminan con “n”.
banco %>% select(starts_with("s")|ends_with("n"))
## # A tibble: 24,299 × 4
## Sucursal Satisfaccion ID_Transaccion Transaccion
## <dbl> <fct> <chr> <chr>
## 1 62 Muy Bueno 2 Cobro/Pago (Cta externa)
## 2 62 Malo 2 Cobro/Pago (Cta externa)
## 3 62 Regular 2 Cobro/Pago (Cta externa)
## 4 62 Regular 2 Cobro/Pago (Cta externa)
## 5 62 Muy Bueno 2 Cobro/Pago (Cta externa)
## 6 62 Bueno 2 Cobro/Pago (Cta externa)
## 7 62 Regular 2 Cobro/Pago (Cta externa)
## 8 62 Bueno 2 Cobro/Pago (Cta externa)
## 9 62 Muy Bueno 2 Cobro/Pago (Cta externa)
## 10 62 Muy Bueno 2 Cobro/Pago (Cta externa)
## # … with 24,289 more rows
Para seleccionar columnas cuyos nombres inician con “s” y terminan con “n”.
banco %>% select(starts_with("s")&ends_with("n"))
## # A tibble: 24,299 × 1
## Satisfaccion
## <fct>
## 1 Muy Bueno
## 2 Malo
## 3 Regular
## 4 Regular
## 5 Muy Bueno
## 6 Bueno
## 7 Regular
## 8 Bueno
## 9 Muy Bueno
## 10 Muy Bueno
## # … with 24,289 more rows
Para usar el filtrado de manera efectiva, debes saber cómo
seleccionar las observaciones que deseas utilizando los operadores de
comparación. R proporciona el conjunto estándar: >,
>=, <, <=,
!= (no igual) y == (igual).
filter()filter() permite filtrar un subconjunto de observaciones
según sus valores para lo cual son necesarios los operadores de
comparación.
Para filtrar todas las transacciones de la sucursal 267:
banco %>% filter(Sucursal==267)
## # A tibble: 3,329 × 7
## Sucursal Cajero ID_Transaccion Transaccion Tiempo_Servicio… Satisfaccion
## <dbl> <dbl> <chr> <chr> <dbl> <fct>
## 1 267 2503 2 Cobro/Pago (Cta… 450. Muy Bueno
## 2 267 2503 2 Cobro/Pago (Cta… 244. Malo
## 3 267 2503 2 Cobro/Pago (Cta… 101. Malo
## 4 267 2503 2 Cobro/Pago (Cta… 511. Bueno
## 5 267 2503 2 Cobro/Pago (Cta… 405. Malo
## 6 267 2503 2 Cobro/Pago (Cta… 667. Muy Bueno
## 7 267 2503 2 Cobro/Pago (Cta… 274. Malo
## 8 267 2503 2 Cobro/Pago (Cta… 154. Muy Malo
## 9 267 2503 2 Cobro/Pago (Cta… 424. Muy Bueno
## 10 267 2503 2 Cobro/Pago (Cta… 474. Muy Malo
## # … with 3,319 more rows, and 1 more variable: Monto <dbl>
Para filtrar todas las transacciones de la sucursal 267 y hayan durado más de 120 segundos:
banco %>% filter(Sucursal==267 & Tiempo_Servicio_seg>120)
## # A tibble: 2,067 × 7
## Sucursal Cajero ID_Transaccion Transaccion Tiempo_Servicio… Satisfaccion
## <dbl> <dbl> <chr> <chr> <dbl> <fct>
## 1 267 2503 2 Cobro/Pago (Cta… 450. Muy Bueno
## 2 267 2503 2 Cobro/Pago (Cta… 244. Malo
## 3 267 2503 2 Cobro/Pago (Cta… 511. Bueno
## 4 267 2503 2 Cobro/Pago (Cta… 405. Malo
## 5 267 2503 2 Cobro/Pago (Cta… 667. Muy Bueno
## 6 267 2503 2 Cobro/Pago (Cta… 274. Malo
## 7 267 2503 2 Cobro/Pago (Cta… 154. Muy Malo
## 8 267 2503 2 Cobro/Pago (Cta… 424. Muy Bueno
## 9 267 2503 2 Cobro/Pago (Cta… 474. Muy Malo
## 10 267 2503 2 Cobro/Pago (Cta… 350. Muy Bueno
## # … with 2,057 more rows, and 1 more variable: Monto <dbl>
Para filtrar todas las transacciones de la sucursal 267 y hayan durado más de 120 segundos y la evaluación a la satisfacción sea “Muy Malo”:
banco %>% filter(Sucursal==267 & Tiempo_Servicio_seg>120 & Satisfaccion=="Muy Malo")
## # A tibble: 334 × 7
## Sucursal Cajero ID_Transaccion Transaccion Tiempo_Servicio… Satisfaccion
## <dbl> <dbl> <chr> <chr> <dbl> <fct>
## 1 267 2503 2 Cobro/Pago (Cta… 154. Muy Malo
## 2 267 2503 2 Cobro/Pago (Cta… 474. Muy Malo
## 3 267 2503 2 Cobro/Pago (Cta… 270. Muy Malo
## 4 267 2503 2 Cobro/Pago (Cta… 653. Muy Malo
## 5 267 2503 2 Cobro/Pago (Cta… 121. Muy Malo
## 6 267 2503 2 Cobro/Pago (Cta… 151. Muy Malo
## 7 267 2503 2 Cobro/Pago (Cta… 215. Muy Malo
## 8 267 2503 2 Cobro/Pago (Cta… 154. Muy Malo
## 9 267 2503 2 Cobro/Pago (Cta… 278. Muy Malo
## 10 267 2503 2 Cobro/Pago (Cta… 340. Muy Malo
## # … with 324 more rows, and 1 more variable: Monto <dbl>
Para filtrar las transacciones que sean mayor a 3000 dólares y menor a 5000 dólares (incluidos)
banco %>%
filter(Monto>=3000 & Monto<=5000) %>%
select(-c(ID_Transaccion, Sucursal, Cajero))
## # A tibble: 2,130 × 4
## Transaccion Tiempo_Servicio_seg Satisfaccion Monto
## <chr> <dbl> <fct> <dbl>
## 1 Cobro/Pago (Cta externa) 247 Bueno 4080.
## 2 Cobro/Pago (Cta externa) 209 Bueno 3803.
## 3 Cobro/Pago (Cta externa) 329 Bueno 3423.
## 4 Cobro/Pago (Cta externa) 319 Regular 3253.
## 5 Cobro/Pago (Cta externa) 188 Muy Bueno 3083.
## 6 Cobro/Pago (Cta externa) 192 Regular 3819.
## 7 Cobro/Pago (Cta externa) 190 Malo 3522.
## 8 Cobro/Pago (Cta externa) 222 Regular 3073
## 9 Cobro/Pago (Cta externa) 375 Bueno 3541.
## 10 Cobro/Pago (Cta externa) 315 Bueno 3594.
## # … with 2,120 more rows
Otra forma de hacerlo es usando between().
¿Qué sucede si incluyes el nombre de una variable varias veces en una llamada a select()?
¿Cómo tratan por defecto las funciones auxiliares de select() a las palabras en mayúsculas o en minúsculas? ¿Existe distinción?
Muestre el cajero, ID_Transaccion y monto de las transacciones que son depósitos que su tiempo de servicio haya durado menos de 3 minutos y que se hayan realizado en la Sucursal 443.
arrange()arrange() trabaja de manera similar a
filter(), es decir con filas, a diferencia que lo que hace
es cambiar su orden.
Para ordenar el conjunto de datos por Satisfacción de forma alfabética o ascendente:
banco %>%
arrange(Satisfaccion)
Para ordenar el conjunto de datos por Satisfacción de forma descendente:
banco %>%
arrange(desc(Satisfaccion))
mutate()mutate() (del inglés mutar o transformar) crea nuevas
columnas en función de columnas existentes o modifica columnas ya
existentes.
Las columnas existentes que son modificadas, siempre se devolverán a
su ubicación original. Y las nuevas columnas creadas a través de
mutate() se colocarán de acuerdo con los argumentos
.before y .after.
Para crear nueva columna con el tiempo de servicio en minutos:
banco %>%
mutate(Tiempo_Serv_Min=Tiempo_Servicio_seg/60)
Para conservar sólo las nuevas variables use
transmute():
banco %>%
transmute(Tiempo_minutos=Tiempo_Servicio_seg/60)
## # A tibble: 24,299 × 1
## Tiempo_minutos
## <dbl>
## 1 5.18
## 2 2.6
## 3 4.13
## 4 1.65
## 5 2.05
## 6 2.87
## 7 2.33
## 8 4.12
## 9 3.05
## 10 1.52
## # … with 24,289 more rows
Para crear nuevas variables de otras nuevas:
banco %>%
mutate(Tiempo_minutos=Tiempo_Servicio_seg/60,
Tiempo_horas=Tiempo_minutos/60)
Para modificar las variables ya existentes:
banco <- banco %>%
mutate(Sucursal= as.character(Sucursal),
Cajero = as.character(Cajero),
Satisfaccion = parse_factor(Satisfaccion,
levels= c('Muy Malo', 'Malo', 'Regular',
'Bueno', 'Muy Bueno')),
Monto= parse_number(Monto, locale = locale(decimal_mark = ".")))
parse_*()Estas funciones toman un vector de caracteres y devuelven un vector más especializado, como un vector lógico, numérico o una fecha. Hay ocho segmentadores particularmente importantes:
parse_logical() y parse_integer()
analizan valores lógicos y números enteros respectivamente.
parse_double() es un segmentador numérico estricto,
y parse_number() es un segmentador numérico
flexible.
parse_character() parece tan simple que no debiera
ser necesario. Pero una complicación lo hace bastante importante: la
codificación de caracteres (el encoding).
parse_factor() crea factores, la estructura de datos
que R usa para representar variables categóricas con valores fijos y
conocidos.
parse_datetime(), parse_date() y
parse_time() te permiten analizar diversas especificaciones
de fechas y horas.Por ejemplo, podemos visualizar las diferencias entre usar
as.numeric() o parse_number().
parse_number("$1,543.4")
## [1] 1543.4
as.numeric("$1,543.4")
## Warning: NAs introducidos por coerción
## [1] NA
Observamos que parse_number() convierte el dato en tipo
numérico:
class(parse_number("$1,543.4"))
## [1] "numeric"
Podemos definir los decimales con decimal_mark:
parse_number("$1.543,4", locale = locale(decimal_mark = ","))
## [1] 1543.4
El paquete lubridate ofrece un conjunto de funciones
para trabajar con datos de fecha y hora en R.
Los comandos R para fecha y hora generalmente no son intuitivos y cambian según el tipo de objeto de fecha y hora que se utilice.
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 no hace, ya
que carece de capacidades como resistencia a las zonas horarias, los
días bisiestos y los horarios de verano.
Puedes encontrar más información del paquete lubridate
en lubridate.tidyverse.org
Por ejemplo, si deseamos convertir datos numéricos como los años a
períodos, usamos la función years():
t1 <- 2022
lubridate::years(t1)
## [1] "2022y 0m 0d 0H 0M 0S"
class(lubridate::years(t1))
## [1] "Period"
## attr(,"package")
## [1] "lubridate"
También podemos usar las funciones parse_*,
as.Date() y as.POSIXct().
parse_datetime() asume una fecha-hora ISO8601. ISO8601
es un 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.
parse_datetime("2010-10-01T2010")
## [1] "2010-10-01 20:10:00 UTC"
as.Date("2010-10-01T2010")
## [1] "2010-10-01"
parse_datetime("20101010")
## [1] "2010-10-10 UTC"
parse_date() asume un año de cuatro dígitos, un guión
- o /, el mes, un guión - o
/ y luego el día.
parse_date("2010-10-01")
## [1] "2010-10-01"
parse_time() espera la hora, :, minutos,
opcionalmente : y segundos, y un especificador opcional
am/pm:
parse_time("01:10 am")
## 01:10:00
parse_time("20:10:01")
## 20:10:01
Si esos valores por defecto no funcionan con tus datos, puedes proporcionar tu propio formato fecha-hora construido con las siguientes piezas:
Año
%Y (4 dígitos)%y (2 dígitos)Mes
%m (2 dígitos)%b (nombre abreviado, como “ene”)%B (nombre completo, “enero”)Día
%d (2 dígitos)%e (espacio opcional destacado)Hora
%H 0-23 horas%I 0-12, debe utilizarse con %p%p indicador AM/PM%M minutos%S segundos enteros%OS segundos realesPor ejemplo:
parse_date("01/02/15", "%m/%d/%y")
## [1] "2015-01-02"
parse_date("01/02/15", "%d/%m/%y")
## [1] "2015-02-01"
parse_date("01/02/15", "%y/%m/%d")
## [1] "2001-02-15"
Si estás utilizando %b o %B con nombres de
meses no ingleses, necesitarás ajustar el argumento lang
para locale(). Mira la lista de lenguas incorporados en
date_names_langs(). Por ejemplo una fecha en italiano:
parse_date("14 febbraio 2016", "%d %B %Y", locale = locale("it"))
## [1] "2016-02-14"
d3 <- "06-Jun-2017"
d5 <- "12/30/14" # Dec 30, 2014
t1 <- "1705"
t2 <- "11:15:10.12 PM"
summarise()summarise() (resumir en inglés) colapsa toda la
información en una sola fila, y es mucho más útil si la usamos con
group_by()
Para sumar todos los montos de las transacciones:
banco %>%
summarise(monto_total=sum(Monto, na.rm=TRUE))
## # A tibble: 1 × 1
## monto_total
## <dbl>
## 1 48501426.
Podemos agregar más información, por ejemplo el promedio con
mean(), máximo max(), mínimo
min() y conteo de filas con n().
banco %>%
summarise(monto_total=sum(Monto, na.rm=TRUE),
promedio=mean(Monto, na.rm=TRUE),
minimo=min(Monto, na.rm=TRUE),
maximo=max(Monto, na.rm=TRUE),
num_transacciones=n())
## # A tibble: 1 × 5
## monto_total promedio minimo maximo num_transacciones
## <dbl> <dbl> <dbl> <dbl> <int>
## 1 48501426. 1996. 53.8 6278. 24299
group_byAdemás de los 5 verbos básicos revisados, muchas veces podríamos
aplicar las mismas operaciones por grupos. Para ello existe la función
group_by(), que recibe un tibble y regresa un tibble
agrupado al que se le aplicarán funciones por grupos, ya sea via
summarise() o mutate().
Podemos agrupar las mismas condiciones del apartado anterior, agruparemos por Sucursal.
banco %>%
group_by(Sucursal) %>%
summarise(monto_total=sum(Monto, na.rm=TRUE),
promedio=mean(Monto, na.rm=TRUE),
minimo=min(Monto, na.rm=TRUE),
maximo=max(Monto, na.rm=TRUE),
num_transacciones=n())
## # A tibble: 5 × 6
## Sucursal monto_total promedio minimo maximo num_transacciones
## <dbl> <dbl> <dbl> <dbl> <dbl> <int>
## 1 62 4986854. 1758. 114. 4576. 2838
## 2 85 24670195. 2048. 53.8 6230. 12044
## 3 267 6869578. 2064. 62.6 5701. 3329
## 4 443 8710627. 2079. 102. 6278. 4190
## 5 586 3264173. 1720. 149. 4649. 1898
mutate().dplyrLa mayor parte del tiempo, nos vienen muchas tablas de información que debemos combinar para responder a nuestras preguntas de interés, a esto se le llama datos relacionales.
Para trabajar con datos relacionales necesitas verbos que funcionen con pares de tablas y para esto existen tres familias de verbos diseñadas para trabajar con datos relacionales que son las 1) uniones de transformación, 2) uniones de filtro y 3) operaciones de conjuntos:
El lugar más común para encontrar datos relacionales es en un sistema relacional de administración de bases de datos (Relational Data Base Management System en inglés), un concepto que abarca casi todas las bases de datos modernas.
Una de las formas de mostrar las relaciones entre las diferentes tablas es mediante un diagrama:
Las uniones de transformación (del inglés mutating joins) agregan nuevas variables a un data frame a partir de las observaciones coincidentes en otra tabla.
En las uniones de transformación tenemos algunos tipos de uniones:
Para entenderlas, vamos a crear los siguientes data frames:
df_1 <- data.frame(
Nombre= c('Belén', 'Noé', 'Salvador', 'Anne', 'Pablo', 'Rafaela'),
Edad = c(22,18,21,26,25,23),
Ciudad= factor(c('Gye', 'Uio', 'Cue', 'Gye', 'Cue', 'Uio')) )
df_1
## Nombre Edad Ciudad
## 1 Belén 22 Gye
## 2 Noé 18 Uio
## 3 Salvador 21 Cue
## 4 Anne 26 Gye
## 5 Pablo 25 Cue
## 6 Rafaela 23 Uio
df_2 <- data.frame(
A= c('Ana', 'Belén','Jose', 'Anne'),
B= c(100,200,300,200),
C= c('Soltera','Soltera','Casado','Divorciada'))
df_2
## A B C
## 1 Ana 100 Soltera
## 2 Belén 200 Soltera
## 3 Jose 300 Casado
## 4 Anne 200 Divorciada
inner_join() muestra las observaciones
cuyas claves coinciden en ambos conjuntos de datos:
df_1 %>% inner_join(df_2, by = c("Nombre"="A"))
## Nombre Edad Ciudad B C
## 1 Belén 22 Gye 200 Soltera
## 2 Anne 26 Gye 200 Divorciada
left_join() muestra las observaciones
del conjunto de la izquierda pero añade los datos del conjunto de la
derecha, coincidan o no coincidan. Si no coinciden, se agregan con
NA.
df_1 %>% left_join(df_2, by = c("Nombre"="A"))
## Nombre Edad Ciudad B C
## 1 Belén 22 Gye 200 Soltera
## 2 Noé 18 Uio NA <NA>
## 3 Salvador 21 Cue NA <NA>
## 4 Anne 26 Gye 200 Divorciada
## 5 Pablo 25 Cue NA <NA>
## 6 Rafaela 23 Uio NA <NA>
right_join() muestra las observaciones
del conjunto de la derecha pero añade los datos del conjunto de la
izquierda, coincidan o no coincidan. Si no coinciden, se agregan con
NA.
df_1 %>% right_join(df_2, by = c("Nombre"="A"))
## Nombre Edad Ciudad B C
## 1 Belén 22 Gye 200 Soltera
## 2 Anne 26 Gye 200 Divorciada
## 3 Ana NA <NA> 100 Soltera
## 4 Jose NA <NA> 300 Casado
full_join() muestra las observaciones
de ambos conjuntos de datos, cuando los datos no coinciden, se agregan
con NA.
df_1 %>% full_join(df_2, by = c("Nombre"="A"))
## Nombre Edad Ciudad B C
## 1 Belén 22 Gye 200 Soltera
## 2 Noé 18 Uio NA <NA>
## 3 Salvador 21 Cue NA <NA>
## 4 Anne 26 Gye 200 Divorciada
## 5 Pablo 25 Cue NA <NA>
## 6 Rafaela 23 Uio NA <NA>
## 7 Ana NA <NA> 100 Soltera
## 8 Jose NA <NA> 300 Casado
Las uniones de filtro (del inglés filtering joins) filtran observaciones en un data frame con base en si coinciden o no con una observación de otra tabla.
semi_join() muestra las observaciones
del conjunto de la izquierda que tiene coincidencias con el conjunto de
la derecha:
df_1 %>% semi_join(df_2, by = c("Nombre"="A"))
## Nombre Edad Ciudad
## 1 Belén 22 Gye
## 2 Anne 26 Gye
anti_join() muestra las observaciones
del conjunto de la izquierda que no tiene coincidencias con el conjunto
de la derecha:
df_1 %>% anti_join(df_2, by = c("Nombre"="A"))
## Nombre Edad Ciudad
## 1 Noé 18 Uio
## 2 Salvador 21 Cue
## 3 Pablo 25 Cue
## 4 Rafaela 23 Uio
Las operaciones de conjuntos (del inglés set operations) tratan las observaciones como elementos de un conjunto. Las comparaciones se realizan entre conjuntos que contengan las mismas columnas, pues se revisa cómo difieren las observaciones entre los conjuntos.
Para ejemplificar crearemos otro data frame:
df_3 <- data.frame(Nombre= c('Belén', 'Noé', 'María', 'Anne', 'Pablo'),
Edad = c(22,18,21,26,25),
Ciudad= factor(c('Cue', 'Uio', 'Cue', 'Gye', 'Cue'))
)
df_3
## Nombre Edad Ciudad
## 1 Belén 22 Cue
## 2 Noé 18 Uio
## 3 María 21 Cue
## 4 Anne 26 Gye
## 5 Pablo 25 Cue
intersect() devuelve las observaciones
comunes entre ambos conjuntos:
intersect(df_1, df_3)
## Nombre Edad Ciudad
## 1 Noé 18 Uio
## 2 Anne 26 Gye
## 3 Pablo 25 Cue
union() devuelve las observaciones
únicas en ambos conjuntos, es decir que no see repiten en ningun de los
dos conjuntos:
union(df_1, df_3)
## Nombre Edad Ciudad
## 1 Belén 22 Gye
## 2 Noé 18 Uio
## 3 Salvador 21 Cue
## 4 Anne 26 Gye
## 5 Pablo 25 Cue
## 6 Rafaela 23 Uio
## 7 Belén 22 Cue
## 8 María 21 Cue
setdiff() devuelve las observaciones en
el primer conjunto pero que son diferentes del segundo conjunto
setdiff(df_1, df_3)
## Nombre Edad Ciudad
## 1 Belén 22 Gye
## 2 Salvador 21 Cue
## 3 Rafaela 23 Uio
tidyrEl paquete tidyr provee un conjunto de herramientas que
te ayudarán a ordenar datos desordenados. El objetivo de este paquete es
ayudarlo a crear datos ordenados. Los datos ordenados son datos
donde:
Tidy data describe una forma estándar de almacenar datos que
se utiliza siempre que sea posible en todo el
tidyverse.
Puedes encontrar más información del paquete tidyr en tidyr.tidyverse.org
Reglas que hacen que un conjunto de datos sea ordenado
Los analistas de datos sostienen que cerca del 80% del tiempo que utilizan para analizar una data lo dedican a la limpieza de datos, no obstante, esto te da una ventaja porque vas a gastar mucho menos tiempo en resolver preguntas analíticas.
Para estudiar este paquete, utilizaremos algunas tablas cargadas en
el paquete datos. A continuación se muestra la tabla1 que
no tiene, cuya estructura cumple el criterio de ‘tidy data’.
library(datos)
tabla1
## # A tibble: 6 × 4
## pais anio casos poblacion
## <chr> <int> <int> <int>
## 1 Afganistán 1999 745 19987071
## 2 Afganistán 2000 2666 20595360
## 3 Brasil 1999 37737 172006362
## 4 Brasil 2000 80488 174504898
## 5 China 1999 212258 1272915272
## 6 China 2000 213766 1280428583
pivot_wider() (pivotar a lo ancho) se usa cuando una
observación aparece en múltiples filas. Por ejemplo, consideremos la
tabla2: una observación es un país en un año, pero cada observación
aparece en dos filas.
tabla2
## # A tibble: 12 × 4
## pais anio tipo cuenta
## <chr> <int> <chr> <int>
## 1 Afganistán 1999 casos 745
## 2 Afganistán 1999 población 19987071
## 3 Afganistán 2000 casos 2666
## 4 Afganistán 2000 población 20595360
## 5 Brasil 1999 casos 37737
## 6 Brasil 1999 población 172006362
## 7 Brasil 2000 casos 80488
## 8 Brasil 2000 población 174504898
## 9 China 1999 casos 212258
## 10 China 1999 población 1272915272
## 11 China 2000 casos 213766
## 12 China 2000 población 1280428583
Para ordenar esto, debemos identificar dos parámetros:
La columna desde la que obtener los nombres de las variables. En
este caso corresponde a tipo.
La columna desde la que obtener los valores. En este caso
corresponde a cuenta.
Una vez resuelto esto, podemos usar pivot_wider():
tabla2 %>%
pivot_wider(names_from = tipo, values_from = cuenta)
## # A tibble: 6 × 4
## pais anio casos población
## <chr> <int> <int> <int>
## 1 Afganistán 1999 745 19987071
## 2 Afganistán 2000 2666 20595360
## 3 Brasil 1999 37737 172006362
## 4 Brasil 2000 80488 174504898
## 5 China 1999 212258 1272915272
## 6 China 2000 213766 1280428583
Lo que hemos hecho es esto:
Pivotar la tabla2 para un formato ‘ancho’ y ordenado
pivot_longer() (pivotar a lo largo) se usa uando en un
dataset los nombres de las columnas no representan nombres de variables,
sino que representan los valores de una variable. Por ejemplo,
consideremos la tabla4a: los nombres de las columnas 1999 y
2000 representan los valores de la variable año, los
valores en las columnas 1999 y 2000
representan valores de la variable casos y cada fila representa dos
observaciones en lugar de una.
tabla4a
## # A tibble: 3 × 3
## pais `1999` `2000`
## <chr> <int> <int>
## 1 Afganistán 745 2666
## 2 Brasil 37737 80488
## 3 China 212258 213766
Para ordenar esto, debemos identificar tres parámetros:
El conjunto de columnas cuyos nombres son valores y no variables.
En este ejemplo son las columnas 1999 y
2000.
El nombre de la variable cuyos valores forman los nombres de las
columnas. Llamaremos a esto key (clave) y en este caso corresponde a
anio.
El nombre de la variable cuyos valores están repartidos por las
celdas. Llamaremos a esto value (valor) y en este caso corresponde al
número de casos.
Una vez resuelto esto, podemos usar pivot_longer():
tabla4a %>%
pivot_longer(cols = c(`1999`, `2000`),
names_to = "anio",
values_to = "casos")
## # A tibble: 6 × 3
## pais anio casos
## <chr> <chr> <int>
## 1 Afganistán 1999 745
## 2 Afganistán 2000 2666
## 3 Brasil 1999 37737
## 4 Brasil 2000 80488
## 5 China 1999 212258
## 6 China 2000 213766
Lo que hemos hecho es esto:
Pivotar la tabla4a para un formato ‘largo’ y ordenado