Propósito

Leer CSV/Excel, limpiar factores y fechas, y combinar tablas con joins de dplyr. Duración estimada: 40–50 min. Cero humo, todo utilidad.

Descarga los insumos: polizas.csv y pagos.xlsx y ponlos en tu carpeta de trabajo (o ajusta las rutas abajo).

# Paquetes sugeridos
# install.packages(c("readr","readxl","dplyr","lubridate","forcats"))
library(readr); library(readxl); library(dplyr)
library(lubridate); library(forcats)

1) Lectura de datos (readr / readxl) – 10 min

# Rutas (ajusta si hace falta)
ruta_csv  <- "polizas.csv"
ruta_xlsx <- "pagos.xlsx"

# CSV con especificación de tipos
polizas_raw <- read_csv(
  ruta_csv,
  col_types = cols(
    id           = col_character(),
    fecha_inicio = col_date(format = "%Y-%m-%d"),
    edad         = col_integer(),
    riesgo       = col_character(),
    prima        = col_double()
  )
)

# Excel (hoja 'pagos')
pagos_raw <- read_excel(ruta_xlsx, sheet = "pagos",
                        col_types = c("text", "date", "numeric"))

glimpse(polizas_raw)
glimpse(pagos_raw)

# Escribir CSV de respaldo
write_csv(polizas_raw, "polizas_backup.csv")

Mini-reto 1.1: ¿Qué pasa si fecha_inicio no tiene formato ISO? Prueba col_date() con format = "%d/%m/%Y" en un ejemplo artificial.


2) Limpieza de factores y strings – 10 min

library(stringr)

polizas <- polizas_raw %>%
  mutate(
    riesgo = str_trim(riesgo),               # quitar espacios
    riesgo = str_to_title(riesgo),           # "alto" -> "Alto"
    riesgo = factor(riesgo, levels = c("Bajo","Medio","Alto"), ordered = TRUE)
  )

count(polizas, riesgo)

Mini-reto 2.1: Colapsa Medio y Bajo en un nivel "No-Alto" usando forcats::fct_collapse (solo para probar).


3) Fechas con lubridate – 8 min

polizas <- polizas %>%
  mutate(
    anio   = year(fecha_inicio),
    mes    = month(fecha_inicio, label = TRUE, abbr = TRUE, locale = "es"),
    antig  = as.integer(Sys.Date() - fecha_inicio),   # días desde inicio
    f_mes  = floor_date(fecha_inicio, unit = "month")
  )

# Ejemplo de parseo alterno
ej <- "31/03/2025"
fecha_ej <- dmy(ej)  # day-month-year
fecha_ej

Mini-reto 3.1: Crea una columna trimestre con quarter(fecha_inicio, with_year = TRUE) y cuenta pólizas por trimestre.


4) Joins modernos con dplyr – 15 min

# Resumen de pagos por id
pagos_sum <- pagos_raw %>%
  mutate(mes_pago = floor_date(fecha_pago, "month")) %>%
  group_by(id) %>%
  summarise(
    total_pagos = sum(valor, na.rm = TRUE),
    n_pagos     = n(),
    .groups = "drop"
  )

# LEFT JOIN: traer totales a la tabla de pólizas
polizas_join <- polizas %>%
  left_join(pagos_sum, by = "id") %>%
  mutate(
    total_pagos = replace_na(total_pagos, 0),
    n_pagos     = replace_na(n_pagos, 0L)
  )

# Diagnósticos útiles
sin_pagos <- polizas %>% anti_join(pagos_sum, by = "id")
solo_en_pagos <- pagos_sum %>% anti_join(polizas, by = "id")

nrow(sin_pagos); nrow(solo_en_pagos)

# INNER JOIN "explota" a nivel de pago (uno-a-muchos)
polizas_detalle <- polizas %>% inner_join(pagos_raw, by = "id")

Notas flash
- left_join: conserva todas las filas de la izquierda (pólizas).
- inner_join: solo coincidencias.
- full_join: une todo (útil para conciliaciones).
- semi_join: filtra izquierda por coincidencias; anti_join: diferencias.

Mini-reto 4.1: Calcula la prima promedio y el total de pagos por riesgo. ¿Quién paga más?


5) Exportar resultados – 5 min

reporte <- polizas_join %>%
  select(id, fecha_inicio, riesgo, prima, total_pagos, n_pagos)

write_csv(reporte, "reporte_polizas_pagos.csv")

Mini-reto final (con guía) – 10 min

Objetivo: Analizar pagos por mes y riesgo.

  1. Une pagos_raw con polizas (para heredar riesgo).
  2. Calcula total_mes por combinación riesgo + mes_pago.
  3. Crea gap = total_mes - promedio_total_mes por riesgo.
  4. Exporta reporte_riesgo_mes.csv.
sol <- pagos_raw %>%
  mutate(mes_pago = floor_date(fecha_pago, "month")) %>%
  left_join(polizas %>% select(id, riesgo), by = "id") %>%
  group_by(riesgo, mes_pago) %>%
  summarise(total_mes = sum(valor, na.rm = TRUE), .groups = "drop") %>%
  group_by(riesgo) %>%
  mutate(prom_riesgo = mean(total_mes)) %>%
  ungroup() %>%
  mutate(gap = total_mes - prom_riesgo)

write_csv(sol, "reporte_riesgo_mes.csv")
head(sol, 6)

Chequeo rápido