── 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
Tarea de la Semana 7 - Joins, Tidy Data y Relaciones entre Tablas Dataset de práctica
Carga de librerías y datos
Tabla Clientes
| id_cliente | nombre | ciudad | tipo |
|---|---|---|---|
| C001 | Ana Torres | Santo Domingo | Premium |
| C002 | Pedro Méndez | Santiago | Regular |
| C003 | María López | Santo Domingo | Premium |
| C004 | Luis García | La Vega | Regular |
| C005 | Carmen Díaz | San Pedro | Regular |
| C006 | Jorge Reyes | Santo Domingo | Premium |
Tabla Facturas
| id_factura | id_cliente | mes | monto |
|---|---|---|---|
| F001 | C001 | Ene | 15000 |
| F002 | C001 | Feb | 22000 |
| F003 | C002 | Ene | 8500 |
| F004 | C003 | Feb | 31000 |
| F005 | C005 | Ene | 4500 |
| F006 | C007 | Feb | 12000 |
| F007 | C002 | Mar | 9800 |
| F008 | C001 | Ene | 15000 |
Tabla Pagos
| id_factura | monto_pagado |
|---|---|
| F001 | 15000 |
| F002 | 22000 |
| F004 | 31000 |
| F006 | 12000 |
| F007 | 9800 |
Diagnóstico Relacional
1.1 Facturas con clientes inexistentes
facturas_huerfanas <- facturas |>
anti_join(clientes, by = "id_cliente")
facturas_huerfanas |>
knitr::kable(caption = "Facturas con clientes no registrados")| id_factura | id_cliente | mes | monto |
|---|---|---|---|
| F006 | C007 | Feb | 12000 |
## Se encontró una factura asociada al cliente C007, el cuál no existe en la tabla de clientes. Esto representa un riesgo huérfano o posible error de captura.1.2 Clientes sin facturas
clientes_sin_factura <- clientes |>
anti_join(facturas, by = "id_cliente")
clientes_sin_factura |>
knitr::kable(caption = "Clientes sin facturas registradas")| id_cliente | nombre | ciudad | tipo |
|---|---|---|---|
| C004 | Luis García | La Vega | Regular |
| C006 | Jorge Reyes | Santo Domingo | Premium |
## Existen 2 clientes sin facturas registradas: Luis García y Jorge Reyes.1.3 Facturas sin pago registrado
facturas_sin_pago <- facturas |>
anti_join(pagos, by = "id_factura")
facturas_sin_pago |>
knitr::kable(caption = "Facturas sin pago registrado")| id_factura | id_cliente | mes | monto |
|---|---|---|---|
| F003 | C002 | Ene | 8500 |
| F005 | C005 | Ene | 4500 |
| F008 | C001 | Ene | 15000 |
## Son F003, F005 y F0081.4 Verificación de duplicados
facturas |>
count(id_cliente) |>
filter(n > 1) |>
knitr::kable(caption = "Clientes con más de una factura registrada")| id_cliente | n |
|---|---|
| C001 | 3 |
| C002 | 2 |
## Los clientes C001 y C002 aparecen varias veces porque poseen múltiples facturas. No se consideran duplicados reales, ya que cada factura tiene un identificador distinto.Aplicando los 4 Joins
2.1 Left Join
nrow(clientes)[1] 6
Filas después del left_join(): 9
2.2 Inner Join
clientes_inner <- clientes |>
inner_join(facturas, by = "id_cliente")
clientes_inner |>
knitr::kable(caption = "Resultado de inner_join entre clientes y facturas")| id_cliente | nombre | ciudad | tipo | id_factura | mes | monto |
|---|---|---|---|---|---|---|
| C001 | Ana Torres | Santo Domingo | Premium | F001 | Ene | 15000 |
| C001 | Ana Torres | Santo Domingo | Premium | F002 | Feb | 22000 |
| C001 | Ana Torres | Santo Domingo | Premium | F008 | Ene | 15000 |
| C002 | Pedro Méndez | Santiago | Regular | F003 | Ene | 8500 |
| C002 | Pedro Méndez | Santiago | Regular | F007 | Mar | 9800 |
| C003 | María López | Santo Domingo | Premium | F004 | Feb | 31000 |
| C005 | Carmen Díaz | San Pedro | Regular | F005 | Ene | 4500 |
## Los clientes C004 (Luis García) y C006 (Jorge Reyes) desaaprecen porque no tienen facturas registradas.2.3 Full Join
clientes_full <- clientes |>
full_join(facturas, by = "id_cliente")
clientes_full |>
knitr::kable(caption = "Resultado de full_join entre clientes y facturas")| id_cliente | nombre | ciudad | tipo | id_factura | mes | monto |
|---|---|---|---|---|---|---|
| C001 | Ana Torres | Santo Domingo | Premium | F001 | Ene | 15000 |
| C001 | Ana Torres | Santo Domingo | Premium | F002 | Feb | 22000 |
| C001 | Ana Torres | Santo Domingo | Premium | F008 | Ene | 15000 |
| C002 | Pedro Méndez | Santiago | Regular | F003 | Ene | 8500 |
| C002 | Pedro Méndez | Santiago | Regular | F007 | Mar | 9800 |
| C003 | María López | Santo Domingo | Premium | F004 | Feb | 31000 |
| C004 | Luis García | La Vega | Regular | NA | NA | NA |
| C005 | Carmen Díaz | San Pedro | Regular | F005 | Ene | 4500 |
| C006 | Jorge Reyes | Santo Domingo | Premium | NA | NA | NA |
| C007 | NA | NA | NA | F006 | Feb | 12000 |
## Aparece una fila adicional correspondiente al cliente C007, ya que existe en facturas pero no en clientes.2.4 Tabla Maestra
tabla_maestra <- clientes |>
left_join(facturas, by = "id_cliente") |>
left_join(pagos, by = "id_factura")
tabla_maestra |>
knitr::kable(caption = "Tabla maestra: clientes, facturas y pagos")| id_cliente | nombre | ciudad | tipo | id_factura | mes | monto | monto_pagado |
|---|---|---|---|---|---|---|---|
| C001 | Ana Torres | Santo Domingo | Premium | F001 | Ene | 15000 | 15000 |
| C001 | Ana Torres | Santo Domingo | Premium | F002 | Feb | 22000 | 22000 |
| C001 | Ana Torres | Santo Domingo | Premium | F008 | Ene | 15000 | NA |
| C002 | Pedro Méndez | Santiago | Regular | F003 | Ene | 8500 | NA |
| C002 | Pedro Méndez | Santiago | Regular | F007 | Mar | 9800 | 9800 |
| C003 | María López | Santo Domingo | Premium | F004 | Feb | 31000 | 31000 |
| C004 | Luis García | La Vega | Regular | NA | NA | NA | NA |
| C005 | Carmen Díaz | San Pedro | Regular | F005 | Ene | 4500 | NA |
| C006 | Jorge Reyes | Santo Domingo | Premium | NA | NA | NA | NA |
## La tabla maestra tiene 9 filas; algunos de los valores de "monto_pagado" aparecen como "NA" porque esas facturas no tienen pago registrado.
## Los clientes sin facturas también generan valores faltantes.Joins de Filtro: Auditoría
3.1 Clientes con al menos una factura
clientes_con_factura <- clientes |>
semi_join(facturas, by = "id_cliente")
clientes_con_factura |>
knitr::kable(caption = "Clientes con al menos una factura")| id_cliente | nombre | ciudad | tipo |
|---|---|---|---|
| C001 | Ana Torres | Santo Domingo | Premium |
| C002 | Pedro Méndez | Santiago | Regular |
| C003 | María López | Santo Domingo | Premium |
| C005 | Carmen Díaz | San Pedro | Regular |
## 4 clientes tienen al menos una factura.3.2 Clientes que nunca han facturado
clientes |>
anti_join(facturas, by = "id_cliente") |>
select(nombre, ciudad) |>
knitr::kable(caption = "Clientes sin facturas registradas")| nombre | ciudad |
|---|---|
| Luis García | La Vega |
| Jorge Reyes | Santo Domingo |
3.3 Facturas de clientes no registrados
facturas |>
anti_join(clientes, by = "id_cliente") |>
select(id_factura, id_cliente, monto) |>
knitr::kable(caption = "Facturas de clientes no registrados")| id_factura | id_cliente | monto |
|---|---|---|
| F006 | C007 | 12000 |
Manejo de Duplicados
4.1 Eliminar duplicados exactos
facturas_sin_dup <- facturas |>
(\(df) filter(df, !duplicated(df)))()
facturas_sin_dup |>
knitr::kable(caption = "Tabla de facturas sin duplicados")| id_factura | id_cliente | mes | monto |
|---|---|---|---|
| F001 | C001 | Ene | 15000 |
| F002 | C001 | Feb | 22000 |
| F003 | C002 | Ene | 8500 |
| F004 | C003 | Feb | 31000 |
| F005 | C005 | Ene | 4500 |
| F006 | C007 | Feb | 12000 |
| F007 | C002 | Mar | 9800 |
| F008 | C001 | Ene | 15000 |
## Permanecen las 8 filas originales porque no existen duplicados exactos.4.2 Factura de mayor monto por cliente
facturas_max <- facturas |>
group_by(id_cliente) |>
slice_max(order_by = monto, n = 1) |>
ungroup()
facturas_max |>
knitr::kable(caption = "Factura de mayor monto por cliente")| id_factura | id_cliente | mes | monto |
|---|---|---|---|
| F002 | C001 | Feb | 22000 |
| F007 | C002 | Mar | 9800 |
| F004 | C003 | Feb | 31000 |
| F005 | C005 | Ene | 4500 |
| F006 | C007 | Feb | 12000 |
4.3 Reconstrucción de tabla maestra
tabla_maestra2 <- clientes |>
left_join(facturas_sin_dup, by = "id_cliente") |>
left_join(pagos, by = "id_factura")
tabla_maestra2 |>
knitr::kable(caption = "Tabla maestra sin duplicados")| id_cliente | nombre | ciudad | tipo | id_factura | mes | monto | monto_pagado |
|---|---|---|---|---|---|---|---|
| C001 | Ana Torres | Santo Domingo | Premium | F001 | Ene | 15000 | 15000 |
| C001 | Ana Torres | Santo Domingo | Premium | F002 | Feb | 22000 | 22000 |
| C001 | Ana Torres | Santo Domingo | Premium | F008 | Ene | 15000 | NA |
| C002 | Pedro Méndez | Santiago | Regular | F003 | Ene | 8500 | NA |
| C002 | Pedro Méndez | Santiago | Regular | F007 | Mar | 9800 | 9800 |
| C003 | María López | Santo Domingo | Premium | F004 | Feb | 31000 | 31000 |
| C004 | Luis García | La Vega | Regular | NA | NA | NA | NA |
| C005 | Carmen Díaz | San Pedro | Regular | F005 | Ene | 4500 | NA |
| C006 | Jorge Reyes | Santo Domingo | Premium | NA | NA | NA | NA |
## El número de filas no cambia porque no existían duplicados exactos que eliminar.Tidy Data con pivot
5.1 Ventas por mes en formato ancho
tabla_maestra <- clientes |>
left_join(facturas_sin_dup, by = "id_cliente") |>
left_join(pagos, by = "id_factura")
ventas_por_mes <- tabla_maestra |>
filter(!is.na(mes)) |>
group_by(nombre, mes) |>
summarise(total = sum(monto, na.rm = TRUE), .groups = "drop") |>
pivot_wider(
names_from = mes,
values_from = total,
values_fill = 0
)
ventas_por_mes |>
knitr::kable(caption = "Ventas por mes en formato ancho")| nombre | Ene | Feb | Mar |
|---|---|---|---|
| Ana Torres | 30000 | 22000 | 0 |
| Carmen Díaz | 4500 | 0 | 0 |
| María López | 0 | 31000 | 0 |
| Pedro Méndez | 8500 | 0 | 9800 |
5.2 Conversión a formato largo
ventas_largo <- ventas_por_mes |>
pivot_longer(
cols = -nombre,
names_to = "mes",
values_to = "total"
)
ventas_largo |>
knitr::kable(caption = "Ventas por mes en formato largo")| nombre | mes | total |
|---|---|---|
| Ana Torres | Ene | 30000 |
| Ana Torres | Feb | 22000 |
| Ana Torres | Mar | 0 |
| Carmen Díaz | Ene | 4500 |
| Carmen Díaz | Feb | 0 |
| Carmen Díaz | Mar | 0 |
| María López | Ene | 0 |
| María López | Feb | 31000 |
| María López | Mar | 0 |
| Pedro Méndez | Ene | 8500 |
| Pedro Méndez | Feb | 0 |
| Pedro Méndez | Mar | 9800 |
5.3 Total vendido por mes
ventas_totales_mes <- ventas_largo |>
group_by(mes) |>
summarise(total_vendido = sum(total), .groups = "drop") |>
arrange(desc(total_vendido))
ventas_totales_mes |>
knitr::kable(caption = "Ventas totales por mes de mayor a menor")| mes | total_vendido |
|---|---|
| Feb | 53000 |
| Ene | 43000 |
| Mar | 9800 |