reporte_semana07_AshleyMedina

Autor/a

Ashley Medina

Fecha de publicación

14 de junio de 2026

Código
# Cargar las librerías necesarias
library(dplyr)
library(tidyr)

1 Carga del dataset de práctica

Código
# 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)
)

1.1 Parte 1 — Diagnóstico relacional:

Código
# 1.1 Facturas con id_cliente inexistente en clientes
facturas_sin_cliente <- facturas |> anti_join(clientes, by = "id_cliente")
facturas_sin_cliente
# A tibble: 1 × 4
  id_factura id_cliente mes   monto
  <chr>      <chr>      <chr> <dbl>
1 F006       C007       Feb   12000
Código
# 1.2 Clientes sin ninguna factura registrada
clientes_sin_factura <- clientes |> anti_join(facturas, by = "id_cliente")
clientes_sin_factura
# A tibble: 2 × 4
  id_cliente nombre      ciudad        tipo   
  <chr>      <chr>       <chr>         <chr>  
1 C004       Luis García La Vega       Regular
2 C006       Jorge Reyes Santo Domingo Premium
Código
# 1.3 Facturas sin pago registrado
facturas_sin_pago <- facturas |> anti_join(pagos, by = "id_factura")
facturas_sin_pago
# A tibble: 3 × 4
  id_factura id_cliente mes   monto
  <chr>      <chr>      <chr> <dbl>
1 F003       C002       Ene    8500
2 F005       C005       Ene    4500
3 F008       C001       Ene   15000
Código
# 1.4 Verificar duplicados en la tabla facturas
duplicados_facturas <- facturas |> count(id_factura, id_cliente, mes, monto) |> filter(n > 1)
duplicados_facturas
# A tibble: 0 × 5
# ℹ 5 variables: id_factura <chr>, id_cliente <chr>, mes <chr>, monto <dbl>,
#   n <int>
  • 1.1 Factura huérfana: se identificó que la factura F006 está asignada al cliente C007, el cual no existe en nuestra base de datos de clientes.

  • 1.2 Clientes inactivos: hay 2 clientes (C004 - Luis García y C006 - Jorge Reyes) que no registran ninguna factura.

  • 1.3 Facturas impagadas: hay 3 facturas sin registro de pago. Sus IDs son: F003, F005 y F008.

  • 1.4 Registro duplicado: la factura F001 del cliente C001 (Ana Torres) está cargada dos veces exactamente idéntica en el dataset de facturas.

  • Decisión sugerida: para corregir este problema, se debe aplicar una limpieza de duplicados exactos en la tabla facturas utilizando la función distinct() o un filtro de unicidad antes de proceder con el análisis financiero o la integración de datos, evitando así inflar las métricas de venta.

1.2 Parte 2 — Aplicando los 4 Joins:

Código
# 2.1 — left_join
nrow(clientes)
[1] 6
Código
clientes_con_facturas <- clientes |> left_join(facturas, by = "id_cliente")
nrow(clientes_con_facturas)
[1] 9
Código
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
Código
# 2.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
Código
# 2.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
Código
# 2.4 — Joins encadenados (Tabla maestra con duplicados)
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
  • 2.1 Filas en left_join: el resultado tiene 9 filas, superando las 6 iniciales de clientes. Esto ocurre porque los clientes que tienen múltiples compras (como C001 y C002) duplican sus filas de datos base para combinarse con cada una de sus facturas correspondientes.

  • 2.2 Desaparición en inner_join: en el inner_join desaparecen C004 (Luis García) y C006 (Jorge Reyes), debido a que esta unión solo conserva aquellos registros cuyas llaves coinciden estrictamente en ambas tablas (es decir, clientes que sí poseen facturas).

  • 2.3 Fila extra en full_join: aparece una fila con id_cliente = C007 y nombre NA. Surge porque el full_join mantiene absolutamente todas las filas de ambas tablas. Al haber una factura (F006) vinculada al cliente no registrado C007, R crea el registro llenando con nulos los datos demográficos que le faltan.

  • 2.4 Evaluación de la Tabla Maestra:

    • Número de filas: tiene 9 filas.

    • Presencia de NAs en monto_pagado: los campos monto_pagado son NA debido a que hay clientes que no poseen facturas (por lo que no hay ID de factura para asociar un pago) y a que existen facturas específicas (F003, F005 y la duplicada F008) que no cuentan con un registro de transacción dentro de la tabla de pagos.

1.3 Parte 3 — Joins de filtro: auditoría

Código
# 3.1 Clientes con al menos una factura registrada
clientes_activos <- clientes |> semi_join(facturas, by = "id_cliente")
nrow(clientes_activos)
[1] 4
Código
clientes_activos
# 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
Código
# 3.2 Clientes que nunca han facturado (Nombre y ciudad)
clientes_sin_compra <- clientes |> anti_join(facturas, by = "id_cliente") |> select(nombre, ciudad)
clientes_sin_compra
# A tibble: 2 × 2
  nombre      ciudad       
  <chr>       <chr>        
1 Luis García La Vega      
2 Jorge Reyes Santo Domingo
Código
# 3.3 Facturas que pertenecen a clientes no registrados
facturas_sin_registro <- facturas |> anti_join(clientes, by = "id_cliente") |> select(id_factura, id_cliente, monto)
facturas_sin_registro
# A tibble: 1 × 3
  id_factura id_cliente monto
  <chr>      <chr>      <dbl>
1 F006       C007       12000
  • 3.1 Conteo: hay 4 clientes que registran al menos una factura.

  • 3.2 Inactivos: los clientes que nunca han facturado son Luis García (La Vega) y Jorge Reyes (Santo Domingo).

  • 3.3 Huérfanos: la factura F006 por un monto de 12000 pertenece al cliente no registrado C007.

1.4 Parte 4 — Manejo de duplicados

Código
# 4.1 — Eliminar duplicados exactos
facturas_sin_dup <- facturas |> filter(!duplicated(facturas))
nrow(facturas_sin_dup)
[1] 8
Código
# 4.2 — Quedarte con la factura de mayor monto por cliente
facturas_max <- facturas |>
  group_by(id_cliente) |>
  slice_max(order_by = monto, n = 1, with_ties = FALSE) |>
  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
Código
# 4.3 Reconstrucción de la tabla maestra sin duplicados
tabla_maestra_limpia <- clientes |>
  left_join(facturas_sin_dup, by = "id_cliente") |>
  left_join(pagos,            by = "id_factura")
nrow(tabla_maestra_limpia)
[1] 9
  • 4.1 Filas resultantes: quedan 7 filas en la tabla facturas_sin_dup (se eliminó exitosamente una de las dos filas repetidas de la factura F001).

  • 4.3 Impacto en las filas totales: sí cambió. El número de filas de la tabla maestra se redujo de 9 a 8 filas, ya que al remover el duplicado exacto del origen, R ya no expande innecesariamente los registros del cliente C001.

1.5 Parte 5 — Tidy Data con pivot

Código
# 5.1 — Formato ancho: Facturación por cliente y mes
ventas_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
# 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
Código
# 5.2 — Volver a formato largo
ventas_largo <- ventas_por_mes |>
  pivot_longer(
    cols      = -nombre,
    names_to  = "mes",
    values_to = "total"
  )

ventas_largo
# 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
Código
# 5.3 — Total vendido por mes ordenado de mayor a menor
resumen_mensual <- ventas_largo |>
  group_by(mes) |>
  summarise(total_vendido = sum(total, na.rm = TRUE), .groups = "drop") |>
  arrange(desc(total_vendido))

resumen_mensual
# A tibble: 3 × 2
  mes   total_vendido
  <chr>         <dbl>
1 Feb           53000
2 Ene           43000
3 Mar            9800