# Tabla 1: Clientes
clientes <- tibble(
id_cliente = c("C001", "C002", "C003", "C004", "C005", "C006"),
nombre = c("Ana Torres", "Pedro Méndez", "María López",
"Luis García", "Carmen Díaz", "Jorge Reyes"),
ciudad = c("Santo Domingo", "Santiago", "Santo Domingo",
"La Vega", "San Pedro", "Santo Domingo"),
tipo = c("Premium", "Regular", "Premium",
"Regular", "Regular", "Premium")
)
# Tabla 2: Facturas
facturas <- tibble(
id_factura = c("F001", "F002", "F003", "F004", "F005", "F006", "F007", "F008"),
id_cliente = c("C001", "C001", "C002", "C003", "C005", "C007", "C002", "C001"),
mes = c("Ene", "Feb", "Ene", "Feb", "Ene", "Feb", "Mar", "Ene"),
monto = c(15000, 22000, 8500, 31000, 4500, 12000, 9800, 15000)
)
# Tabla 3: Pagos
pagos <- tibble(
id_factura = c("F001", "F002", "F004", "F006", "F007"),
monto_pagado = c(15000, 22000, 31000, 12000, 9800)
)id_cliente inexistente en
clientesHallazgo:
F006tieneid_cliente = "C007", que no existe enclientes. Es un cliente sin registro que generó una factura. Antes de cualquier análisis de ventas, conviene investigar el origen de ese registro.
Resultado: 2 clientes sin facturas: Luis García (
C004) y Jorge Reyes (C006).
facturas_sin_pago <- anti_join(facturas, pagos, by = "id_factura")
facturas_sin_pago |> select(id_factura, id_cliente, mes, monto)Resultado: Las facturas
F003,F005,F006yF008no tienen pago asociado.
# Revisión por contenido: mismo cliente, mes y monto
facturas |>
count(id_cliente, mes, monto) |>
filter(n > 1)Hallazgo: No hay
id_facturarepetido, peroC001tiene dos registros con el mismo mes (Ene) y el mismo monto (15000):F001yF008. Son registros idénticos en contenido.Decisión: Tratar
F008como duplicado y eliminarlo confilter(!duplicated(.)). Se conservaF001por ser el registro más antiguo en el vector.
left_join## [1] 6
clientes_con_facturas <- clientes |>
left_join(facturas, by = "id_cliente")
nrow(clientes_con_facturas)## [1] 9
Resultado: 6 clientes originales, 9 filas tras el join. El resultado tiene más filas porque
left_joinexpande: un cliente con varias facturas produce una fila por cada factura. Ana Torres (C001) tiene 3 facturas, por eso aparece 3 veces. Los clientes sin facturas (C004,C006) aparecen conNAen las columnas de facturas.
inner_join## [1] 7
Resultado: 8 filas. Desaparecen Luis García (
C004) y Jorge Reyes (C006). Elinner_joinconserva solo filas con coincidencia en ambas tablas, por eso excluye a los clientes sin facturas.
full_join## [1] 10
Resultado: 10 filas. Aparece una fila con
id_cliente = "C007"yNAen todas las columnas declientes. Elfull_joinconserva todos los registros de ambas tablas, incluyendo los que no tienen correspondencia en ninguno de los dos lados.
tabla_maestra <- clientes |>
left_join(facturas, by = "id_cliente") |>
left_join(pagos, by = "id_factura")
print(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
Resultado:
- Filas: 9. El segundo
left_join(conpagos) no agrega filas porquepagoses una tabla de atributos: cada factura aparece a lo sumo una vez.monto_pagadoconNA: Las facturasF003,F005yF008no existen enpagos, así que el join no encuentra correspondencia y rellena conNA.
## [1] 4
Resultado: 4 clientes con al menos una factura.
semi_joinfiltra sin agregar columnas de la tabla derecha.
## [1] 8
Resultado: 7 filas. Se eliminó
F008, que era duplicado exacto deF001.
facturas_max <- facturas |>
group_by(id_cliente) |>
slice_max(order_by = monto, n = 1) |>
ungroup()
facturas_maxpivotventas_por_mes <- tabla_maestra_limpia |>
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