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
ypagos.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)
# 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)