Semana 07 - Joins, Tidy Data y Relaciones entre Tablas
Author
Johamnely Mateo
Introducción
En esta práctica se trabaja con relaciones entre tablas utilizando diferentes tipos de joins del paquete dplyr.
El objetivo principal es analizar la relación entre clientes, facturas y pagos, identificar inconsistencias en los datos, manejar duplicados y transformar información utilizando herramientas de tidy data como pivot_wider() y pivot_longer().
Librerías
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.2.1 ✔ readr 2.2.0
✔ forcats 1.0.1 ✔ stringr 1.6.0
✔ ggplot2 4.0.3 ✔ tibble 3.3.1
✔ lubridate 1.9.5 ✔ tidyr 1.3.2
✔ purrr 1.2.2
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
# A tibble: 6 × 4
id_cliente nombre ciudad tipo
<chr> <chr> <chr> <chr>
1 C001 Ana Torres Santo Domingo Premium
2 C002 Pedro Méndez Santiago Regular
3 C003 María López Santo Domingo Premium
4 C004 Luis García La Vega Regular
5 C005 Carmen Díaz San Pedro Regular
6 C006 Jorge Reyes Santo Domingo Premium
# A tibble: 8 × 4
id_factura id_cliente mes monto
<chr> <chr> <chr> <dbl>
1 F001 C001 Ene 15000
2 F002 C001 Feb 22000
3 F003 C002 Ene 8500
4 F004 C003 Feb 31000
5 F005 C005 Ene 4500
6 F006 C007 Feb 12000
7 F007 C002 Mar 9800
8 F008 C001 Ene 15000
# A tibble: 0 × 2
# ℹ 2 variables: id_factura <chr>, n <int>
Observación
No existen facturas duplicadas exactas por id_factura.
Sin embargo, un mismo cliente puede tener múltiples facturas, lo cual es completamente válido en un sistema de facturación.
Parte 3 - Aplicando los 4 Joins
3.1 Left Join
nrow(clientes)
[1] 6
clientes_con_facturas <- clientes %>%left_join(facturas, by ="id_cliente")nrow(clientes_con_facturas)
[1] 9
clientes_con_facturas
# A tibble: 9 × 7
id_cliente nombre ciudad tipo id_factura mes monto
<chr> <chr> <chr> <chr> <chr> <chr> <dbl>
1 C001 Ana Torres Santo Domingo Premium F001 Ene 15000
2 C001 Ana Torres Santo Domingo Premium F002 Feb 22000
3 C001 Ana Torres Santo Domingo Premium F008 Ene 15000
4 C002 Pedro Méndez Santiago Regular F003 Ene 8500
5 C002 Pedro Méndez Santiago Regular F007 Mar 9800
6 C003 María López Santo Domingo Premium F004 Feb 31000
7 C004 Luis García La Vega Regular <NA> <NA> NA
8 C005 Carmen Díaz San Pedro Regular F005 Ene 4500
9 C006 Jorge Reyes Santo Domingo Premium <NA> <NA> NA
Observación
El resultado contiene más filas porque algunos clientes tienen múltiples facturas, por lo tanto el join replica la información del cliente para cada factura relacionada.
3.2 Inner Join
clientes_inner <- clientes %>%inner_join(facturas, by ="id_cliente")clientes_inner
# A tibble: 7 × 7
id_cliente nombre ciudad tipo id_factura mes monto
<chr> <chr> <chr> <chr> <chr> <chr> <dbl>
1 C001 Ana Torres Santo Domingo Premium F001 Ene 15000
2 C001 Ana Torres Santo Domingo Premium F002 Feb 22000
3 C001 Ana Torres Santo Domingo Premium F008 Ene 15000
4 C002 Pedro Méndez Santiago Regular F003 Ene 8500
5 C002 Pedro Méndez Santiago Regular F007 Mar 9800
6 C003 María López Santo Domingo Premium F004 Feb 31000
7 C005 Carmen Díaz San Pedro Regular F005 Ene 4500
Observación
Los clientes sin facturas desaparecen del resultado porque inner_join() solo conserva coincidencias presentes en ambas tablas.
3.3 Full Join
clientes_full <- clientes %>%full_join(facturas, by ="id_cliente")clientes_full
# A tibble: 10 × 7
id_cliente nombre ciudad tipo id_factura mes monto
<chr> <chr> <chr> <chr> <chr> <chr> <dbl>
1 C001 Ana Torres Santo Domingo Premium F001 Ene 15000
2 C001 Ana Torres Santo Domingo Premium F002 Feb 22000
3 C001 Ana Torres Santo Domingo Premium F008 Ene 15000
4 C002 Pedro Méndez Santiago Regular F003 Ene 8500
5 C002 Pedro Méndez Santiago Regular F007 Mar 9800
6 C003 María López Santo Domingo Premium F004 Feb 31000
7 C004 Luis García La Vega Regular <NA> <NA> NA
8 C005 Carmen Díaz San Pedro Regular F005 Ene 4500
9 C006 Jorge Reyes Santo Domingo Premium <NA> <NA> NA
10 C007 <NA> <NA> <NA> F006 Feb 12000
Observación
Aparece una fila adicional correspondiente al cliente C007 proveniente de la tabla facturas, aunque dicho cliente no existe en la tabla clientes.
3.4 Joins encadenados
tabla_maestra <- clientes %>%left_join(facturas, by ="id_cliente") %>%left_join(pagos, by ="id_factura")tabla_maestra
# A tibble: 9 × 8
id_cliente nombre ciudad tipo id_factura mes monto monto_pagado
<chr> <chr> <chr> <chr> <chr> <chr> <dbl> <dbl>
1 C001 Ana Torres Santo Domin… Prem… F001 Ene 15000 15000
2 C001 Ana Torres Santo Domin… Prem… F002 Feb 22000 22000
3 C001 Ana Torres Santo Domin… Prem… F008 Ene 15000 NA
4 C002 Pedro Méndez Santiago Regu… F003 Ene 8500 NA
5 C002 Pedro Méndez Santiago Regu… F007 Mar 9800 9800
6 C003 María López Santo Domin… Prem… F004 Feb 31000 31000
7 C004 Luis García La Vega Regu… <NA> <NA> NA NA
8 C005 Carmen Díaz San Pedro Regu… F005 Ene 4500 NA
9 C006 Jorge Reyes Santo Domin… Prem… <NA> <NA> NA NA
Cantidad de filas
nrow(tabla_maestra)
[1] 9
Observación
Algunos valores de monto_pagado son NA porque existen facturas que todavía no tienen pagos registrados en la tabla pagos.
# A tibble: 4 × 4
id_cliente nombre ciudad tipo
<chr> <chr> <chr> <chr>
1 C001 Ana Torres Santo Domingo Premium
2 C002 Pedro Méndez Santiago Regular
3 C003 María López Santo Domingo Premium
4 C005 Carmen Díaz San Pedro Regular
# A tibble: 8 × 4
id_factura id_cliente mes monto
<chr> <chr> <chr> <dbl>
1 F001 C001 Ene 15000
2 F002 C001 Feb 22000
3 F003 C002 Ene 8500
4 F004 C003 Feb 31000
5 F005 C005 Ene 4500
6 F006 C007 Feb 12000
7 F007 C002 Mar 9800
8 F008 C001 Ene 15000
Cantidad de filas luego de eliminar duplicados
nrow(facturas_sin_dup)
[1] 8
5.2 Factura de mayor monto por cliente
facturas_max <- facturas %>%group_by(id_cliente) %>%slice_max(order_by = monto, n =1) %>%ungroup()facturas_max
# A tibble: 5 × 4
id_factura id_cliente mes monto
<chr> <chr> <chr> <dbl>
1 F002 C001 Feb 22000
2 F007 C002 Mar 9800
3 F004 C003 Feb 31000
4 F005 C005 Ene 4500
5 F006 C007 Feb 12000
5.3 Nueva tabla maestra usando facturas_sin_dup
tabla_maestra_2 <- clientes %>%left_join(facturas_sin_dup, by ="id_cliente") %>%left_join(pagos, by ="id_factura")tabla_maestra_2
# A tibble: 9 × 8
id_cliente nombre ciudad tipo id_factura mes monto monto_pagado
<chr> <chr> <chr> <chr> <chr> <chr> <dbl> <dbl>
1 C001 Ana Torres Santo Domin… Prem… F001 Ene 15000 15000
2 C001 Ana Torres Santo Domin… Prem… F002 Feb 22000 22000
3 C001 Ana Torres Santo Domin… Prem… F008 Ene 15000 NA
4 C002 Pedro Méndez Santiago Regu… F003 Ene 8500 NA
5 C002 Pedro Méndez Santiago Regu… F007 Mar 9800 9800
6 C003 María López Santo Domin… Prem… F004 Feb 31000 31000
7 C004 Luis García La Vega Regu… <NA> <NA> NA NA
8 C005 Carmen Díaz San Pedro Regu… F005 Ene 4500 NA
9 C006 Jorge Reyes Santo Domin… Prem… <NA> <NA> NA NA
Número de filas
nrow(tabla_maestra_2)
[1] 9
Observación
El número de filas no cambia porque originalmente no existían duplicados exactos en la tabla facturas.
# A tibble: 4 × 4
nombre Ene Feb Mar
<chr> <dbl> <dbl> <dbl>
1 Ana Torres 30000 22000 0
2 Carmen Díaz 4500 0 0
3 María López 0 31000 0
4 Pedro Méndez 8500 0 9800
Tabla de ventas por mes
knitr::kable( ventas_por_mes,caption ="Ventas por Mes por Cliente")
# A tibble: 12 × 3
nombre mes total
<chr> <chr> <dbl>
1 Ana Torres Ene 30000
2 Ana Torres Feb 22000
3 Ana Torres Mar 0
4 Carmen Díaz Ene 4500
5 Carmen Díaz Feb 0
6 Carmen Díaz Mar 0
7 María López Ene 0
8 María López Feb 31000
9 María López Mar 0
10 Pedro Méndez Ene 8500
11 Pedro Méndez Feb 0
12 Pedro Méndez Mar 9800
Tabla en formato largo
knitr::kable( ventas_largo,caption ="Ventas en Formato Largo")
# A tibble: 3 × 2
mes total_vendido
<chr> <dbl>
1 Feb 53000
2 Ene 43000
3 Mar 9800
Tabla total vendido por mes
knitr::kable( total_por_mes,caption ="Total Vendido por Mes")
Total Vendido por Mes
mes
total_vendido
Feb
53000
Ene
43000
Mar
9800
Conclusión
Durante esta práctica se trabajó con diferentes tipos de joins utilizando dplyr, permitiendo comprender cómo se relacionan distintas tablas dentro de un sistema de información.
Además, se aplicaron técnicas de auditoría de datos mediante anti_join() y semi_join(), manejo de duplicados y transformación de datos utilizando pivot_wider() y pivot_longer().
Finalmente, se construyó una tabla maestra consolidada y diferentes resúmenes analíticos para validar la correcta integración de los datos.