Semana07_rubi_pineda

Author

Rubi Pineda

Published

14 Jun 2026

Code
#| echo: true

library (tidyverse)
Code
# 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)
)

clientes
# 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
Code
facturas
# 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
Code
pagos
# A tibble: 5 × 2
  id_factura monto_pagado
  <chr>             <dbl>
1 F001              15000
2 F002              22000
3 F004              31000
4 F006              12000
5 F007               9800

1 Diagnóstico Relacional

1.1 1.1

Code
facturas %>%
  anti_join(clientes, by = "id_cliente")
# A tibble: 1 × 4
  id_factura id_cliente mes   monto
  <chr>      <chr>      <chr> <dbl>
1 F006       C007       Feb   12000
Code
# La factura "F006" aparece con un id_cliente "C007", el cual no esta en la tabla de clientes.

1.2 1.2

Code
clientes %>%
  anti_join(facturas, by = "id_cliente")
# 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
Code
# Hay dos clientes sin factura registrada, Luis García C004 Y Jorge Reyes C006.

1.3 1.3

Code
cat("Facturas sin pago registrado:",
    facturas %>%
      anti_join(pagos, by = "id_factura") %>%
      pull(id_factura),
    "\n"
)
Facturas sin pago registrado: F003 F005 F008 
Code
# Facturas sin pago registrado: F003 F005 F008 

1.4 1.4

Code
# Verifica si hay duplicados en la tabla facturas usando count() + filter(n > 1). ¿Cuál es el id_cliente que tiene una factura duplicada? Documenta en un comentario qué decisión tomarías.


facturas %>%
  count(id_factura) %>%
  filter(n > 1)
# A tibble: 0 × 2
# ℹ 2 variables: id_factura <chr>, n <int>
Code
# No hay facturas duplicadas y no hay id_cliente con factura duplicada, ya que todos tienen un id_factura diferente.

#  En el caso de C001, existen dos facturas con el mismo monto y mes, pero con id_factura diferentes. Antes de eliminarlas, verificaría si se trata de una duplicación por error o de dos transacciones diferentes.

# Si fuese un error del sistema, seria mas probable que aparezca una factura debajo de la otra, ejemplo ficticio 007 y 008, ya que en bases de datos el campo ID suele ser autoincremental. Al parecer, aqui se inserta manual, ya que los meses y facturas estan "sorteados". En este caso, solo puedo guiarme del id_factura para decidir y al no ser iguales, lo tomaría como valido.

2 Aplicando los 4 Joins

2.1 2.1

Code
#left_join: Une clientes con facturas por id_cliente. Llama al resultado clientes_con_facturas. ¿Cuántas filas tiene el resultado y por qué tiene más filas que la tabla clientes?
  
  
nrow(clientes)
[1] 6
Code
clientes_con_facturas <- clientes %>%
  left_join(facturas, by = "id_cliente")
nrow(clientes_con_facturas)
[1] 9
Code
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
Code
#El resultado tiene 9 filas. Esto pasa porque algunos clientes tienen más de una factura. Por ejemplo, C001 tiene 3 facturas y C002 tiene 2, por eso sus registros se repiten al hacer el join.

2.2 2.2

Code
# inner_join:Une clientes con facturas usando inner_join. ¿Qué clientes desaparecen del resultado comparado con el left_join? Documenta en un comentario.

ccf_inner <- clientes %>%
  inner_join(facturas, by = "id_cliente")

ccf_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
Code
clientes %>%
  anti_join(facturas, by = "id_cliente")
# 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
Code
# Desaparecen Luis G. C004 y Jorge R. C006 porque no tienen facturas (aparecian NA en el left) y el inner_join solo muestra las coincidencias entre ambas tablas.

2.3 2.3

Code
# Une clientes con facturas usando full_join. ¿Qué fila extra aparece que no estaba en ninguna de las dos tablas originales? Explica en un comentario por qué aparece esa fila.

ccf_full <- clientes %>%
  full_join(facturas, by = "id_cliente")

ccf_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
Code
# Aparece una fila para el cliente C007, porque hay una factura con ese id_cliente, pero el cliente no está registrado en la tabla clientes. Al usar full join se muestra todo de ambas tablas.

2.4 2.4

Code
# Joins encadenados: Construye una tabla maestra uniendo las **tres tablas** en un solo pipeline:

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
Code
# La tabla_maestra tiene 9 filas. Algunos monto_pagado son NA porque esas facturas no tienen un pago registrado en la tabla pagos.

3 Joins de Filtro: Auditoría

3.1 3.1

Code
# Usa semi_join() para obtener solo los clientes que sí tienen al menos una factura. 
  

clientes_con_una_factura <- clientes %>%
  semi_join(facturas, by = "id_cliente")

clientes_con_una_factura
# 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
Code
nrow(clientes_con_una_factura)
[1] 4
Code
# Hay 4 clientes con al menos una factura.

3.2 3.2

Code
# Usa anti_join() para obtener los clientes que nunca han facturado. Muestra su nombre y ciudad.

clientes %>%
  anti_join(facturas, by = "id_cliente") %>%
  select(nombre, ciudad)
# A tibble: 2 × 2
  nombre      ciudad       
  <chr>       <chr>        
1 Luis García La Vega      
2 Jorge Reyes Santo Domingo
Code
# Luis García de La Vega y Jorge Reyes de Santo Domingo, nunca han facturado.

3.3 3.3

Code
# Usa anti_join() al revés: ¿qué facturas pertenecen a clientes que no están registrados? Muestra el id_factura, id_cliente y monto.

facturas %>%
  anti_join(clientes, by = "id_cliente") %>%
  select(id_factura, id_cliente, monto)
# A tibble: 1 × 3
  id_factura id_cliente monto
  <chr>      <chr>      <dbl>
1 F006       C007       12000
Code
# La factura F006 del id_cliente C007 que no está registrado.

4 Manejo de Duplicados

4.1 Eliminar duplicados exactos:

Code
facturas_sin_dup <- facturas %>%
  filter(!duplicated(.))

nrow(facturas_sin_dup)
[1] 8
Code
facturas_sin_dup
# 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
Code
# En este caso, quedan las mismas 8 filas de facturas, porque no hay duplicados.

4.2 Quedarte con la factura de mayor monto por cliente:

Code
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
Code
# Se conserva la factura de mayor monto para cada cliente, hay 5 filas.

4.3 4.3

Code
#Vuelve a construir la tabla_maestra del Parte 2.4 pero esta vez usando facturas_sin_dup en lugar de facturas. ¿Cambió el número de filas?

tabla_maestra <- clientes %>%
  left_join(facturas_sin_dup, 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
Code
nrow(tabla_maestra)
[1] 9
Code
# La tabla tiene 9 filas porque algunos clientes tienen varias facturas y se repiten en el join. Además, se mantienen los clientes sin compras (C004 y C006), y la factura de C007 no aparece porque ese cliente no está registrado. En total, se muestran 7 facturas asociadas a clientes registrados y 2 clientes sin facturas.

5 Tidy Data con pivot

5.1 Formato ancho

Code
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
# 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

5.2 Volver a formato largo

Code
ventas_largo <- ventas_por_mes |>
  pivot_longer(
    cols      = -nombre,      # Todo excepto la columna 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

5.3 5.3

Code
# Con ventas_largo, usa group_by() + summarise() para calcular el total vendido por mes y ordena de mayor a menor.

ventas_largo %>%
  group_by(mes) %>%
  summarise(
    total_vendido = sum(total),
    .groups = "drop"
  ) %>%
  arrange(desc(total_vendido))
# A tibble: 3 × 2
  mes   total_vendido
  <chr>         <dbl>
1 Feb           53000
2 Ene           43000
3 Mar            9800