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.csvypagos.xlsxy 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)
# 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.
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).
lubridate – 8 minpolizas <- 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.
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?
reporte <- polizas_join %>%
  select(id, fecha_inicio, riesgo, prima, total_pagos, n_pagos)
write_csv(reporte, "reporte_polizas_pagos.csv")
Objetivo: Analizar pagos por mes y riesgo.
pagos_raw con polizas (para heredar
riesgo).total_mes por combinación riesgo +
mes_pago.gap = total_mes - promedio_total_mes por
riesgo.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)