Índice

1Introducción y resumen ejecutivo ObjetivoIndicadoresHallazgosDescripción general
2Contexto y descripción de los datos Origen y estructuraVariables principalesNombres de columnasResumen estadístico
3Análisis de indicadores 3.1 Día y tipo de vehículo3.2 Evolución diaria3.3 Género o titular3.4 Valor por infracción3.5 Comparendos por mes3.6 Personas con más comparendos
4Resultados por consulta Consulta 1: infracción y vehículoConsulta 2: propietario y vehículoConsulta 3: valor por propietarioConsulta 4: top 10 de propietariosConsulta 5: identificación y géneroConsulta 6: evolución en el tiempo
5Hallazgos y conclusiones Hallazgos principalesConclusión general
6Recomendaciones Calidad de los datosGestión y controlPolítica pública
7Referencias Fuente de datosHerramientas
Centro de Gestión y Servicios para el Tránsito

Informe de Gestión Vial:
Análisis de Comparendos
Barranquilla · Abril – Mayo 2010

Analítica de Datos · SENA

Una mirada a las infracciones de tránsito, su frecuencia, impacto económico y comportamiento en el tiempo.

Período de análisis: 12/04/2010 a 27/05/2010
Neider Peñaranda · TAD-13 · 30/10/2026
1

Introducción y resumen ejecutivo

Objetivo

Este informe aplica herramientas estadísticas básicas en R al análisis de los comparendos de tránsito impuestos en Barranquilla entre el 12/04/2010 y el 27/05/2010. Se exploran, describen y visualizan los datos para identificar patrones, tendencias y relaciones relevantes, mediante medidas de frecuencia, concentración y evolución en el tiempo, que apoyen la toma de decisiones en la gestión del tránsito.

Cómo usar este informe

Pasa el cursor sobre cualquier gráfico para leer sus datos exactos. Cada gráfico se dibuja al llegar a él, y el botón «↻ Repetir» lo anima de nuevo. El botón «Ocultar código» (arriba a la derecha) muestra u oculta el código en R de todo el informe.

Indicadores

2.119
Registros
25
Columnas
2
Tipos de vehículo
4
Infracciones
$ 643.698.500
Valor total
1.250
Total en SMLV 2010
Hallazgos

La base tiene buena integridad (0 valores vacíos), pero se detectaron 1 fila duplicada exacta y 17 números de comparendo repetidos con distinto mandamiento. Fueron depurados o señalados para garantizar la calidad del análisis.

Descripción general

La base reúne comparendos aplicados a conductores y propietarios de vehículos en Barranquilla (Atlántico). Cada registro incluye datos del infractor (nombre, género, tipo y número de identificación), del vehículo (placa y tipo), de la infracción (código y nombre), la fecha del comparendo desglosada en día, mes y año, y el valor a pagar. En total tiene 25 columnas y 2.120 registros originales (2.119 tras la depuración), lo que permite un análisis estadístico descriptivo sólido.

2

Contexto y descripción de los datos

Origen y estructura

La información proviene de la base de comparendos de tránsito con 25 variables originales sobre el infractor, la infracción, la fecha, el vehículo y el valor económico del comparendo. A continuación se muestra el código con el que se leyó y depuró la base.

# Lectura y depuración de la base
raw   <- read_excel(ruta, sheet = "BD Comparendos OK")
n_raw <- nrow(raw)
datos <- raw %>% select(-starts_with("#")) %>% distinct() %>% janitor::clean_names()
n_dup <- n_raw - nrow(datos)
datos <- datos %>% mutate(
  ejecutado  = ejecutado %>% str_squish() %>% str_replace_all("G\\.M\\.A\\.C\\.", "GMAC"),
  tipo_id    = recode(tipo_de_identificacion, "Cedula de Ciudadanía" = "Cédula de ciudadanía",
                      "Cedula de Extanjería" = "Cédula de extranjería", "Nit" = "NIT"),
  infraccion = str_to_sentence(nom_infraccion) %>% str_replace("maxima", "máxima"),
  fecha      = as.Date(fecha_de_comparendo),
  smlv       = costo_de_comparendo / smlv_2010,
  dia        = factor(str_to_title(nom_dia), levels = c("Lunes","Martes","Miércoles","Jueves","Viernes","Sábado","Domingo")),
  mes        = factor(str_to_title(nom_mes), levels = c("Abril", "Mayo")),
  vehiculo   = str_to_title(vehiculo))
# Resumen de la base y variables principales
resumen <- tibble(Indicador = c("Registros (base depurada)", "Columnas originales", "Valores vacíos", "Filas duplicadas exactas",
                                "Comparendos únicos", "Propietarios únicos", "Placas únicas", "Período"),
                  Valor = c(fm(nrow(datos)), ncol(raw), sum(is.na(raw)), n_dup, fm(n_distinct(datos$comparendo)),
                            fm(n_distinct(datos$ejecutado)), fm(n_distinct(datos$placa_de_vehiculo)), paste(f_ini, "a", f_fin)))
vars <- c("Tipo de vehículo", "Infracción", "Fecha del comparendo", "Valor del comparendo (COP y SMLV)", "Tipo de identificación", "Propietario (ejecutado)", "Género")
salida('<div class="dos-col">', tabla_html(resumen), '<div class="vars" id="o2"><b>Variables principales</b><ul>', paste0("<li>", vars, "</li>", collapse = ""), '</ul></div></div>')
Indicador Valor
Registros (base depurada) 2.119
Columnas originales 25
Valores vacíos 0
Filas duplicadas exactas 1
Comparendos únicos 2.102
Propietarios únicos 1.247
Placas únicas 1.457
Período 12/04/2010 a 27/05/2010
Variables principales
  • Tipo de vehículo
  • Infracción
  • Fecha del comparendo
  • Valor del comparendo (COP y SMLV)
  • Tipo de identificación
  • Propietario (ejecutado)
  • Género
Depuración de datos

Se eliminó 1 fila duplicada, se unificaron nombres (p. ej. G.M.A.C. por GMAC), se corrigieron etiquetas y se convirtió el valor a SMLV de 2010 ($ 515.000). Cada comparendo vale 0,1, 0,5 o 1 SMLV.

Aplicación de funciones: colnames()

Lo primero es identificar los nombres de las columnas para poder llamarlas correctamente en el análisis.

# Nombres de las columnas originales
cat(paste0('<span class="tag">', str_squish(colnames(raw)), '</span>', collapse = ""))

No. MANDAMIENTO DE PAGOFECHA MANDAMIENTO DE PAGOEJECUTADOTIPO DE IDENTIFICACIONNo. IDENTIFICACION#TIPO DE IDENTIFICACIONGENERO# GENEROCOD. INFRACCION# COD. INFRACCIONNOM.INFRACCION#NOM. INFRACCIONCOMPARENDOFECHA DE COMPARENDOAÑOMESNOM MES# NOM. MESDIANOM DIA# NOM. DiaPLACA DE VEHICULOVEHICULO#VEHICULOCOSTO DE COMPARENDO

Aplicación de funciones: resumen estadístico

Resumen general de la fecha y del valor a pagar, para revisar la distribución y los cuartiles.

# Resumen estadístico (mínimo, cuartiles, mediana, media y máximo)
fq <- as.numeric(datos$fecha); vq <- datos$costo_de_comparendo
est <- tibble(`Estadístico` = c("Mínimo", "1.er cuartil", "Mediana", "Media", "3.er cuartil", "Máximo"),
              `Fecha del comparendo` = format(as.Date(unname(c(min(fq), quantile(fq, .25), median(fq), mean(fq), quantile(fq, .75), max(fq))), origin = "1970-01-01"), "%d/%m/%Y"),
              `Valor del comparendo` = cop(unname(c(min(vq), quantile(vq, .25), median(vq), mean(vq), quantile(vq, .75), max(vq)))))
salida(tabla_html(est))
Estadístico Fecha del comparendo Valor del comparendo
Mínimo 12/04/2010 $ 51.500
1.er cuartil 27/04/2010 $ 257.500
Mediana 06/05/2010 $ 257.500
Media 05/05/2010 $ 303.775
3.er cuartil 16/05/2010 $ 257.500
Máximo 27/05/2010 $ 515.000
3

Análisis de indicadores

3.1 Comparendos por día de la semana y tipo de vehículo

Cómo entender este gráfico

Qué muestra: cuántos comparendos se impusieron cada día de la semana, separados entre autos (azul) y motos (coral).

Cómo leerlo: cada columna es un día; su altura es el total de comparendos y el número en negrita sobre ella es ese total. La parte azul de la columna son los autos y la coral las motos.

Al pasar el cursor: al situarte sobre un día aparece el detalle de autos, motos y el total de ese día.

Para qué sirve: identificar los días con más infracciones para programar operativos de control en esos momentos.

# Barras apiladas por día (autos y motos) con el total encima
d_dia <- datos %>% count(dia, vehiculo) %>%
  mutate(dia = as.character(dia), tip = paste0(vehiculo, ": ", fm(n), " comparendos"))
tot_dia <- datos %>% count(dia) %>%
  mutate(dia = as.character(dia), tip = paste0("<b>Total: ", fm(n), " comparendos</b>"))
p <- plot_ly(height = 460)
for (veh in names(col_veh)) {
  p <- add_bars(p, data = filter(d_dia, vehiculo == veh), x = ~dia, y = ~n, name = veh,
                marker = list(color = col_veh[[veh]]), hoverinfo = "text", hovertext = ~tip)
}
p <- p %>%
  add_trace(data = tot_dia, x = ~dia, y = ~n, type = "scatter", mode = "text", text = ~fm(n),
            textposition = "top center", textfont = list(size = 15, color = pal$marino),
            showlegend = FALSE, hoverinfo = "text", hovertext = ~tip) %>%
  layout(barmode = "stack", hovermode = "x unified",
         xaxis = eje_cat(levels(datos$dia)), yaxis = eje_val(max(tot_dia$n) * 1.18)) %>%
  pl("Comparendos por día de la semana")
graf(p)
Dato a resaltar

Sábado y domingo concentran el 36,2% de los comparendos; el día con más registros es el domingo (396). Los autos representan el 91,4% del total.

3.2 Evolución diaria de los comparendos

La variación diaria permite detectar días atípicos, eventos especiales o aumentos asociados a operativos específicos, clima, festivos o tráfico inusual. El patrón temporal sirve para prever puntos críticos y ajustar los operativos de tránsito.

Cómo entender este gráfico

Qué muestra: el número de comparendos de cada fecha entre abril y mayo, como una línea con el área sombreada debajo.

Cómo leerlo: el eje horizontal son las fechas (una marca por semana) y el vertical la cantidad de comparendos de ese día. Los tres puntos coral con número son los días con más registros.

Al pasar el cursor: sobre cualquier punto de la línea aparecen la fecha, el día de la semana y los comparendos de ese día.

Para qué sirve: ver en qué fechas se disparan las infracciones y reconocer días atípicos, como operativos, festivos o puentes.

# Línea con área y los 3 días pico resaltados
diario <- datos %>% count(fecha, dia) %>%
  mutate(tip = paste0("<b>", dia, " ", format(fecha, "%d/%m/%Y"), "</b><br>", fm(n), " comparendos"))
picos <- diario %>% slice_max(n, n = 3, with_ties = FALSE)
p <- plot_ly(height = 440) %>%
  add_trace(data = diario, x = ~fecha, y = ~n, type = "scatter", mode = "lines+markers",
            fill = "tozeroy", fillcolor = "rgba(20,184,166,.20)", name = "Comparendos",
            line = list(color = pal$turquesa, width = 3), marker = list(color = pal$turquesa, size = 6),
            hoverinfo = "text", hovertext = ~tip) %>%
  add_trace(data = picos, x = ~fecha, y = ~n, type = "scatter", mode = "markers+text", name = "Días pico",
            text = ~n, textposition = "top center", textfont = list(color = pal$coral, size = 15),
            marker = list(color = pal$coral, size = 13, line = list(color = "white", width = 2)),
            hoverinfo = "text", hovertext = ~tip) %>%
  layout(xaxis = list(title = "", type = "date", tickformat = "%d/%m", dtick = 7 * 24 * 3600 * 1000,
                      tick0 = as.character(min(diario$fecha)), gridcolor = "#E5EAF2", fixedrange = TRUE),
         yaxis = eje_val(max(diario$n) * 1.25)) %>%
  pl("Comparendos por fecha de infracción")
graf(p)

3.3 Comparendos por género o tipo de titular

Se cuenta la cantidad de comparendos según el género del infractor o si el titular es una empresa.

Cómo entender este gráfico

Qué muestra: cuántos comparendos corresponden a mujeres, hombres, empresas y cédulas nuevas.

Cómo leerlo: cada columna es una categoría; encima aparece la cantidad de comparendos y, entre paréntesis, el porcentaje que representa del total. Las columnas van de la más alta a la más baja.

Al pasar el cursor: sobre una columna aparecen la categoría, la cantidad y su porcentaje del total.

Para qué sirve: saber quién concentra las infracciones y si conviene diferenciar las estrategias entre personas naturales y empresas.

# Barras por género con cantidad y porcentaje
gen <- datos %>% count(genero = str_to_title(genero)) %>% mutate(p = n / sum(n)) %>% arrange(desc(n)) %>%
  mutate(txt = paste0(fm(n), "<br>(", pct(p), ")"),
         tip = paste0("<b>", genero, "</b><br>", fm(n), " comparendos<br>", pct(p), " del total"),
         col = unname(col_gen[genero]))
p <- plot_ly(gen, x = ~genero, y = ~n, type = "bar", marker = list(color = gen$col),
             text = ~txt, textposition = "outside", cliponaxis = FALSE,
             textfont = list(size = 15, color = pal$marino),
             hoverinfo = "text", hovertext = ~tip, height = 440) %>%
  layout(xaxis = eje_cat(gen$genero), yaxis = eje_val(max(gen$n) * 1.3)) %>%
  pl("Distribución de comparendos por género o empresa", leyenda = FALSE)
graf(p)
Lectura

La categoría con más comparendos es «Mujer» (45,7%). Las empresas aportan el 22,0% de los comparendos, lo que indica la necesidad de fortalecer el control sobre las flotas vehiculares corporativas y de diferenciar las estrategias entre personas naturales y jurídicas.

3.4 Valor económico por tipo de infracción

Se suman los valores de los comparendos agrupados por la infracción cometida. Es el valor impuesto, no el recaudo efectivo, porque la base no trae fechas de pago.

Cómo entender este gráfico

Qué muestra: cuánto dinero suman los comparendos de cada tipo de infracción.

Cómo leerlo: cada barra horizontal es una infracción y su longitud es el valor total en pesos. A la derecha se ve el monto y, entre paréntesis, el porcentaje del valor total. Van ordenadas de mayor a menor.

Al pasar el cursor: sobre una barra aparecen el nombre completo de la infracción, su valor, su participación y el número de comparendos.

Para qué sirve: priorizar las infracciones que más pesan en el valor total, que no siempre son las más frecuentes.

# Barras horizontales del valor económico por infracción
inf_v <- datos %>% group_by(infraccion) %>% summarise(v = sum(costo_de_comparendo), n = n(), .groups = "drop") %>%
  arrange(desc(v)) %>% mutate(p = v / sum(v))
inf_g <- inf_v %>% arrange(v) %>%
  mutate(et = wrapbr(infraccion, 28), txt = paste0(cop(v), "  (", pct(p), ")"),
         tip = paste0("<b>", infraccion, "</b><br>Valor: ", cop(v), "<br>Participación: ", pct(p), "<br>Comparendos: ", fm(n)))
p <- plot_ly(inf_g, x = ~v, y = ~et, type = "bar", orientation = "h", marker = list(color = pal$coral),
             text = ~txt, textposition = "outside", cliponaxis = FALSE,
             textfont = list(size = 14, color = pal$marino),
             hoverinfo = "text", hovertext = ~tip, height = 430) %>%
  layout(xaxis = eje_val(max(inf_g$v) * 1.65, showticklabels = FALSE, showgrid = FALSE),
         yaxis = eje_cat(inf_g$et)) %>%
  pl("Valor económico de los comparendos por infracción", leyenda = FALSE)
graf(p)
Lectura

«Velocidad superior a la máxima permitida» aporta $ 418.695.000 (65,0%), lo que indica alta frecuencia y sanción elevada. Le sigue «No detenerse ante una luz roja o amarilla» con $ 197.760.000. Entre las dos suman el 95,8% del valor total; «Transitar en sentido contrario» tiene un valor mínimo, por su baja ocurrencia o menor detección.

3.5 Comparendos por mes

Se agrupan los comparendos por el mes en que ocurrieron para revisar la variación mensual.

Cómo entender este gráfico

Qué muestra: el total de comparendos de abril y de mayo.

Cómo leerlo: la altura de cada columna es el total del mes; encima aparece ese total y el promedio de comparendos por día. Abril empieza el 12/04, así que tiene menos días y conviene comparar con el promedio diario, no con el total.

Al pasar el cursor: sobre una columna aparecen el total, los días con registros, el promedio diario y el valor del mes.

Para qué sirve: comparar los dos meses de forma justa y ver si la actividad aumentó o bajó.

# Barras de comparendos por mes con promedio diario
mes_t <- datos %>% group_by(mes) %>% summarise(n = n(), dias = n_distinct(fecha), v = sum(costo_de_comparendo), .groups = "drop") %>%
  mutate(prom = n / dias, mes = as.character(mes),
         txt = paste0("<b>", fm(n), " comparendos</b><br>", format(round(prom, 1), decimal.mark = ","), " por día"),
         tip = paste0("<b>", mes, "</b><br>", fm(n), " comparendos<br>", dias, " días con registros<br>",
                      format(round(prom, 1), decimal.mark = ","), " por día<br>Valor: ", cop(v)))
p <- plot_ly(mes_t, x = ~mes, y = ~n, type = "bar",
             marker = list(color = unname(c(Abril = pal$azul, Mayo = pal$turquesa)[mes_t$mes])),
             text = ~txt, textposition = "outside", cliponaxis = FALSE, textfont = list(size = 15, color = pal$marino),
             hoverinfo = "text", hovertext = ~tip, height = 430) %>%
  layout(xaxis = eje_cat(mes_t$mes), yaxis = eje_val(max(mes_t$n) * 1.3), bargap = 0.5) %>%
  pl("Comparendos por mes", leyenda = FALSE)
graf(p)
Lectura

Mayo registra 1.408 comparendos frente a 711 de abril (98% más). Pero abril solo cubre 19 días (desde el 12/04/2010) y mayo 27, así que la comparación justa es el promedio diario: 37,4 frente a 52,1 (39% más).

3.6 Personas naturales con más comparendos

Se identifican las 10 personas con más comparendos registrados, excluyendo empresas (se incluyen los empates en el último lugar).

Cómo entender este gráfico

Qué muestra: las personas naturales (sin empresas) con mayor número de comparendos acumulados.

Cómo leerlo: cada barra horizontal es una persona y el número a la derecha es su cantidad de comparendos. La de arriba es la que más acumula.

Al pasar el cursor: sobre una barra aparecen el nombre, la cantidad de comparendos y el valor acumulado.

Para qué sirve: reconocer a los reincidentes para enfocar campañas educativas y acciones sancionatorias en ellos.

# Top 10 de personas naturales por número de comparendos
pers_all <- datos %>% filter(str_to_upper(genero) != "EMPRESA") %>%
  group_by(ejecutado) %>% summarise(n = n(), v = sum(costo_de_comparendo), .groups = "drop")
pers <- pers_all %>% slice_max(n, n = 10, with_ties = TRUE) %>% arrange(n) %>%
  mutate(et = wrapbr(ejecutado, 45),
         tip = paste0("<b>", ejecutado, "</b><br>", n, " comparendos<br>Valor: ", cop(v)))
p <- plot_ly(pers, x = ~n, y = ~et, type = "bar", orientation = "h", marker = list(color = pal$violeta),
             text = ~n, textposition = "outside", cliponaxis = FALSE, textfont = list(size = 14, color = pal$marino),
             hoverinfo = "text", hovertext = ~tip, height = 120 + 40 * nrow(pers)) %>%
  layout(xaxis = eje_val(max(pers$n) * 1.15, tickformat = "d"), yaxis = eje_cat(pers$et), bargap = 0.3) %>%
  pl("Top 10 de personas naturales con más comparendos", leyenda = FALSE)
graf(p)
Lectura

La persona natural con más comparendos acumula 27, frente a 10 de la siguiente. Hay 289 personas naturales con 2 o más comparendos. Identificar a los reincidentes permite focalizar intervenciones educativas y sancionatorias más precisas.

4

Resultados por consulta

Consulta 1. Frecuencia de infracciones según el tipo de vehículo

Cómo entender este gráfico

Qué muestra: a la izquierda, qué porcentaje de los comparendos corresponde a autos y a motos; a la derecha, cuántos comparendos hay de cada infracción, separados por tipo de vehículo.

Cómo leerlo: en la dona, cada color es un tipo de vehículo, el porcentaje va dentro del anillo y el total de registros, en el centro. En las barras, la longitud es la cantidad de comparendos y los colores indican cuánto aporta cada vehículo.

Al pasar el cursor: en la dona aparecen el vehículo, la cantidad y el porcentaje; en las barras, la infracción completa y los comparendos de cada vehículo.

Para qué sirve: ver qué vehículo infringe más y en cuáles infracciones pesan más los autos o las motos.

# Dona de participación por vehículo + barras por infracción
q1 <- datos %>% count(vehiculo) %>% mutate(p = n / sum(n))
p_dona <- plot_ly(q1, labels = ~vehiculo, values = ~n, type = "pie", hole = 0.58, sort = FALSE,
                  direction = "clockwise", textinfo = "percent",
                  textfont = list(color = "white", size = 17),
                  marker = list(colors = unname(col_veh[q1$vehiculo]), line = list(color = "white", width = 3)),
                  hovertemplate = "<b>%{label}</b><br>%{value:,.0f} comparendos<br>%{percent:.1%}<extra></extra>",
                  height = 460) %>%
  layout(annotations = list(list(text = paste0("Total<br><b>", fm(sum(q1$n)), "</b>"), x = 0.5, y = 0.5,
                                 showarrow = FALSE, font = list(size = 18, color = pal$marino)))) %>%
  pl("Participación por vehículo", margen = list(t = 70, r = 10, b = 20, l = 10)) %>%
  layout(legend = list(orientation = "h", x = 0.5, xanchor = "center", y = -0.02))

q1b <- datos %>% count(infraccion, vehiculo) %>%
  mutate(et = wrapbr(infraccion, 24), tip = paste0("<b>", infraccion, "</b><br>", vehiculo, ": ", fm(n), " comparendos"))
orden1 <- q1b %>% group_by(infraccion, et) %>% summarise(t = sum(n), .groups = "drop") %>% arrange(t) %>%
  mutate(tip = paste0("<b>", infraccion, "</b><br>Total: ", fm(t), " comparendos"))
p_barras <- plot_ly(height = 460)
for (veh in names(col_veh)) {
  p_barras <- add_bars(p_barras, data = filter(q1b, vehiculo == veh), x = ~n, y = ~et, orientation = "h",
                       name = veh, marker = list(color = col_veh[[veh]]), hoverinfo = "text", hovertext = ~tip)
}
p_barras <- p_barras %>%
  add_trace(data = orden1, x = ~t, y = ~et, type = "scatter", mode = "text", text = ~fm(t),
            textposition = "middle right", textfont = list(size = 14, color = pal$marino),
            showlegend = FALSE, hoverinfo = "text", hovertext = ~tip) %>%
  layout(barmode = "stack", xaxis = eje_val(max(orden1$t) * 1.15), yaxis = eje_cat(orden1$et)) %>%
  pl("Comparendos por infracción y vehículo")

htmltools::div(class = "dos-col", style = "grid-template-columns:1fr 1.5fr", graf(p_dona), graf(p_barras))
# Tabla de la consulta 1
t1 <- datos %>% group_by(infraccion) %>%
  summarise(Auto = sum(vehiculo == "Auto"), Moto = sum(vehiculo == "Moto"), Total = n(), Valor = sum(costo_de_comparendo), .groups = "drop") %>%
  arrange(desc(Total)) %>%
  mutate(`% registros` = pct(Total / sum(Total)), Valor = cop(Valor), across(c(Auto, Moto, Total), fm)) %>%
  rename(`Infracción` = infraccion)
salida(tabla_html(t1))
Infracción Auto Moto Total Valor % registros
Velocidad superior a la máxima permitida 1.467 159 1.626 $ 418.695.000 76,7%
No detenerse ante una luz roja o amarilla 363 21 384 $ 197.760.000 18,1%
No respetar el paso de peatones 105 0 105 $ 27.037.500 5,0%
Transitar en sentido contrario 2 2 4 $ 206.000 0,2%
Total a conciliar

En el dashboard esta consulta mostraba solo 396 registros y $ 116.647.500 porque la segmentación de día estaba en DOMINGO. Aquí se usa toda la base: 2.119 registros y $ 643.698.500.

Consulta 2. Distribución de comparendos por propietario y tipo de vehículo

Cómo entender este gráfico

Qué muestra: los 15 propietarios con más comparendos y qué parte de ellos corresponde a autos y a motos.

Cómo leerlo: cada barra horizontal es un propietario; el número al final es su total de comparendos. Los colores dividen la barra entre autos (azul) y motos (coral).

Al pasar el cursor: sobre cada tramo de color aparecen el nombre completo del propietario y los comparendos de ese vehículo.

Para qué sirve: ubicar a los propietarios que más comparendos acumulan, casi siempre entidades financieras o empresas, para priorizar la gestión de cobro.

# Top 15 propietarios, barras apiladas por vehículo
top15 <- prop %>% slice_max(n, n = 15, with_ties = FALSE) %>% arrange(n) %>%
  mutate(et = wrapbr(ejecutado, 30), tip = paste0("<b>", ejecutado, "</b><br>Total: ", n, " comparendos"))
q2 <- datos %>% filter(ejecutado %in% top15$ejecutado) %>% count(ejecutado, vehiculo) %>%
  mutate(et = wrapbr(ejecutado, 30), tip = paste0("<b>", ejecutado, "</b><br>", vehiculo, ": ", n, " comparendos"))
p <- plot_ly(height = 600)
for (veh in names(col_veh)) {
  p <- add_bars(p, data = filter(q2, vehiculo == veh), x = ~n, y = ~et, orientation = "h",
                name = veh, marker = list(color = col_veh[[veh]]), hoverinfo = "text", hovertext = ~tip)
}
p <- p %>%
  add_trace(data = top15, x = ~n, y = ~et, type = "scatter", mode = "text", text = ~n,
            textposition = "middle right", textfont = list(size = 14, color = pal$marino),
            showlegend = FALSE, hoverinfo = "text", hovertext = ~tip) %>%
  layout(barmode = "stack", xaxis = eje_val(max(top15$n) * 1.12, tickformat = "d"), yaxis = eje_cat(top15$et)) %>%
  pl("Los 15 propietarios con más comparendos")
graf(p)
Hallazgo

Los propietarios con más comparendos son entidades financieras y empresas (leasing y transporte). Hay 1.247 propietarios distintos y 899 (72%) tienen un solo comparendo. En el dashboard esta consulta estaba limitada a domingos y propietarios con 3 o más comparendos (67 registros).

Consulta 3. Distribución porcentual del valor económico por propietario

Cómo entender este gráfico

Qué muestra: qué porcentaje del dinero total de los comparendos corresponde a los 6 propietarios con mayor valor y qué parte queda en «Otros propietarios».

Cómo leerlo: cada porción de la dona es un propietario y su tamaño es su participación en el valor total; el porcentaje está dentro de la porción y en la leyenda de la derecha. El centro muestra el valor total.

Al pasar el cursor: sobre una porción aparecen el propietario, su valor en pesos y su porcentaje. Si haces clic en la leyenda, ocultas o muestras esa porción.

Para qué sirve: medir qué tan concentrado o repartido está el valor: si «Otros propietarios» es la porción más grande, el valor está muy atomizado.

# Dona del valor económico: top 6 propietarios y el resto
q3 <- datos %>% group_by(ejecutado) %>% summarise(v = sum(costo_de_comparendo), .groups = "drop") %>% arrange(desc(v)) %>%
  mutate(grupo = if_else(row_number() <= 6, ejecutado, "Otros propietarios")) %>%
  group_by(grupo) %>% summarise(v = sum(v), .groups = "drop") %>%
  mutate(p = v / sum(v), orden = if_else(grupo == "Otros propietarios", 0, v)) %>% arrange(desc(orden)) %>%
  mutate(et = str_trunc(grupo, 32))
colores3 <- c(pal$azul, pal$turquesa, pal$ambar, pal$coral, pal$violeta, pal$marino, pal$gris)
p <- plot_ly(q3, labels = ~et, values = ~v, type = "pie", hole = 0.58, sort = FALSE,
             direction = "clockwise", textinfo = "percent", insidetextorientation = "horizontal",
             textfont = list(color = "white", size = 14),
             marker = list(colors = colores3[seq_len(nrow(q3))], line = list(color = "white", width = 3)),
             hovertemplate = "<b>%{label}</b><br>$ %{value:,.0f}<br>%{percent:.1%}<extra></extra>",
             height = 500) %>%
  layout(annotations = list(list(text = paste0("Total<br><b>", cop(sum(q3$v)), "</b>"), x = 0.5, y = 0.5,
                                 showarrow = FALSE, font = list(size = 16, color = pal$marino)))) %>%
  pl("Valor económico por propietario", margen = list(t = 70, r = 10, b = 20, l = 10)) %>%
  layout(legend = list(orientation = "v", x = 1.02, y = 0.5, font = list(size = 13)))
graf(p)
Observación

El valor económico está muy atomizado: los 6 mayores propietarios suman solo el 10,5% del valor total. Nota: en el dashboard este gráfico contaba registros, no dinero; aquí se calcula con el valor real del comparendo.

Consulta 4. Top 10 de propietarios con más comparendos

Cómo entender esta tabla

Qué muestra: una tabla con los 10 propietarios que más comparendos acumulan, con su tipo de identificación, cantidad, valor y participación.

Cómo leerlo: cada fila es un propietario, ordenado del que más comparendos tiene al que menos. La columna «% del total» incluye una barrita cuyo largo es proporcional a su participación.

Al pasar el cursor: la fila bajo el cursor se resalta para seguirla con facilidad.

Para qué sirve: tener a la mano la lista concreta de propietarios a priorizar en la gestión de cobro.

# Top 10 de propietarios (conteo de comparendos, no suma de códigos)
q4 <- datos %>% group_by(ejecutado, tipo_id) %>% summarise(n = n(), v = sum(costo_de_comparendo), .groups = "drop") %>%
  arrange(desc(n)) %>% slice_head(n = 10) %>% mutate(p = n / nrow(datos))
t4 <- q4 %>% transmute(`#` = row_number(), Propietario = ejecutado, `Tipo de ID` = tipo_id, Comparendos = n,
                       Valor = cop(v), SMLV = fm(v / smlv_2010),
                       `% del total` = paste0('<span class="mini" style="width:', as.integer(round(p / max(p) * 60)), 'px"></span>', pct(p)))
salida(tabla_html(t4))
# Propietario Tipo de ID Comparendos Valor SMLV % del total
1 LEASING BANCOLOMBIA S.A. C.F. NIT 61 $ 19.827.500 38 2,9%
2 TRANSPORTES MST Y CIA S EN C NIT 48 $ 13.905.000 27 2,3%
3 FINANCIERA INTERNACIONAL S.A. NIT 32 $ 10.557.500 20 1,5%
4 LEASING DE OCCIDENTE S.A. C.F. NIT 28 $ 9.527.500 18 1,3%
5 LILIANA ROZO PINZON Cédula de ciudadanía 27 $ 7.467.500 14 1,3%
6 GMAC FINANCIERA DE COLOMBI NIT 21 $ 6.180.000 12 1,0%
7 LEASING DE CREDITO S.A. NIT 21 $ 5.922.500 12 1,0%
8 UINON FAMILIAR CHARRIS S.EN C NIT 13 $ 4.120.000 8 0,6%
9 ELVIRA DEL CARMEN GARRIDO AREVALO Cédula de ciudadanía 10 $ 2.575.000 5 0,5%
10 MIGUEL HERNANDO GARAY CALLE Cédula de ciudadanía 9 $ 2.111.500 4 0,4%
Nota

El top 10 concentra el 12,7% de los comparendos y el 12,8% del valor. Corrección frente al dashboard: la tabla original sumaba el código de la infracción; aquí se cuentan comparendos.

Consulta 5. Frecuencia de infracciones por tipo de identificación y género

Cómo entender este gráfico

Qué muestra: a la izquierda, cuántos comparendos hay según el documento con que se identifica el infractor (cédula de ciudadanía, de extranjería o NIT); a la derecha, cada infracción dividida por género o tipo de titular.

Cómo leerlo: en las columnas, la altura y el número arriba indican la cantidad de comparendos. En las barras horizontales, la longitud es la cantidad de comparendos de cada infracción y los colores indican quién la cometió (mujer, hombre, empresa).

Al pasar el cursor: sobre una columna aparecen el tipo de documento y su cantidad; sobre un tramo de color, la infracción completa y los comparendos de ese género.

Para qué sirve: conocer el perfil de quien comete cada infracción para diseñar mensajes y controles distintos para personas y empresas.

# Barras por tipo de identificación + infracción por género
q5a <- datos %>% count(tipo_id) %>% arrange(desc(n)) %>%
  mutate(et = wrapbr(tipo_id, 14), tip = paste0("<b>", tipo_id, "</b><br>", fm(n), " comparendos"))
pa <- plot_ly(q5a, x = ~et, y = ~n, type = "bar",
              marker = list(color = c(pal$azul, pal$turquesa, pal$ambar)[seq_len(nrow(q5a))]),
              text = ~fm(n), textposition = "outside", cliponaxis = FALSE, textfont = list(size = 14, color = pal$marino),
              hoverinfo = "text", hovertext = ~tip, height = 470) %>%
  layout(xaxis = eje_cat(q5a$et), yaxis = eje_val(max(q5a$n) * 1.2)) %>%
  pl("Por tipo de identificación", leyenda = FALSE, margen = list(t = 70, r = 10, b = 60, l = 20))

q5b <- datos %>% count(infraccion, genero = str_to_title(genero)) %>%
  mutate(et = wrapbr(infraccion, 22), tip = paste0("<b>", infraccion, "</b><br>", genero, ": ", fm(n), " comparendos"))
orden5 <- q5b %>% group_by(et) %>% summarise(t = sum(n), .groups = "drop") %>% arrange(t)
pb <- plot_ly(height = 470)
for (g in unique(q5b$genero)) {
  pb <- add_bars(pb, data = filter(q5b, genero == g), x = ~n, y = ~et, orientation = "h", name = g,
                 marker = list(color = unname(col_gen[g])), hoverinfo = "text", hovertext = ~tip)
}
pb <- pb %>% layout(barmode = "stack", xaxis = eje_val(max(orden5$t) * 1.05), yaxis = eje_cat(orden5$et)) %>%
  pl("Infracción según género")

htmltools::div(class = "dos-col", style = "grid-template-columns:1fr 1.4fr", graf(pa), graf(pb))
Total a conciliar

El dashboard mostraba 396 registros y 3 infracciones (solo domingos). La base depurada completa tiene 2.119 registros y 4 infracciones: «Transitar en sentido contrario» solo aparece en días que no son domingo.

Consulta 6. Evolución de los comparendos (semanal y mensual)

Cómo entender este gráfico

Qué muestra: cómo cambian semana a semana el número de comparendos (barras turquesa, eje izquierdo) y el dinero que suman (línea ámbar, eje derecho, en millones de pesos).

Cómo leerlo: cada barra es una semana que empieza el lunes indicado en el eje horizontal; su altura y el número encima son los comparendos. La línea ámbar sube o baja según el valor económico de esa semana. La última semana está incompleta.

Al pasar el cursor: sobre una barra o un punto de la línea aparecen la semana, los comparendos y el valor económico de esa semana.

Para qué sirve: ver si el valor sube igual que la cantidad de comparendos o si cambia por el tipo de infracción, y detectar semanas críticas.

# Barras de comparendos + línea de valor económico (doble eje), por semana
q6 <- datos %>% mutate(semana = lubridate::floor_date(fecha, "week", week_start = 1)) %>%
  group_by(semana) %>% summarise(n = n(), v = sum(costo_de_comparendo), .groups = "drop") %>%
  mutate(tip = paste0("<b>Semana del ", format(semana, "%d/%m/%Y"), "</b><br>Comparendos: ", fm(n), "<br>Valor: ", cop(v)))
p <- plot_ly(height = 480) %>%
  add_bars(data = q6, x = ~semana, y = ~n, width = 5 * 86400000, name = "Comparendos",
           marker = list(color = pal$turquesa), text = ~fm(n), textposition = "outside", cliponaxis = FALSE,
           textfont = list(size = 14, color = pal$marino), hoverinfo = "text", hovertext = ~tip) %>%
  add_trace(data = q6, x = ~semana, y = ~v, yaxis = "y2", type = "scatter", mode = "lines+markers",
            name = "Valor económico", line = list(color = pal$ambar, width = 4),
            marker = list(color = pal$ambar, size = 9), hoverinfo = "text", hovertext = ~tip) %>%
  layout(xaxis = list(title = "", type = "date", tickformat = "%d/%m", tickvals = as.character(q6$semana),
                      gridcolor = "#E5EAF2", fixedrange = TRUE),
         yaxis = eje_val(max(q6$n) * 1.2, title = list(text = "Comparendos", font = list(color = pal$turquesa))),
         yaxis2 = list(overlaying = "y", side = "right", range = c(0, max(q6$v) * 1.2), showgrid = FALSE,
                       zeroline = FALSE, fixedrange = TRUE, tickprefix = "$ ", tickformat = ".2s",
                       title = list(text = "Valor económico", font = list(color = pal$ambar)))) %>%
  pl("Comparendos (barras) y valor (línea) por semana<br><sup>Semana que inicia el lunes indicado; la última está incompleta</sup>",
     margen = list(t = 95, r = 90, b = 55, l = 70))
graf(p)
# Resumen mensual
t6 <- datos %>% group_by(Mes = mes) %>%
  summarise(Comparendos = n(), Dias = n_distinct(fecha), Valor = sum(costo_de_comparendo), .groups = "drop") %>%
  mutate(`Promedio diario` = format(round(Comparendos / Dias, 1), nsmall = 1, decimal.mark = ",", trim = TRUE), Comparendos = fm(Comparendos),
         `Días con registros` = Dias, Valor = cop(Valor)) %>% select(-Dias)
salida(tabla_html(t6))
Mes Comparendos Valor Promedio diario Días con registros
Abril 711 $ 216.506.000 37,4 19
Mayo 1.408 $ 427.192.500 52,1 27
Cobertura limitada

Solo se analizan abril (desde el 12/04/2010) y mayo (hasta el 27/05/2010), con 2.119 registros y $ 643.698.500. No permite evaluar tendencias anuales ni estacionalidad; por eso la evolución se presenta por semana.

5

Hallazgos y conclusiones

Hallazgos principales

Calidad: 25 columnas, 0 valores vacíos y 1 fila duplicada exacta (de 2.120 a 2.119 registros).
Comparendos repetidos: 17 números de comparendo aparecen dos veces con distinto No. de mandamiento; hay que validar si es doble mandamiento o error de digitación.
Perfil del infractor: la categoría con más comparendos es «Mujer» (45,7%) y el vehículo más frecuente es el auto (91,4%); las empresas aportan el 22,0%.
Infracción dominante: «Velocidad superior a la máxima permitida» representa el 76,7% de los comparendos y el 65,0% del valor; las dos infracciones principales suman el 95,8% del valor total.
Fin de semana: sábado y domingo reúnen el 36,2% de los comparendos.
Evolución: mayo supera a abril en 98% en total y en 39% por día, porque abril solo cubre desde el 12/04/2010.
Concentración y reincidencia: el top 10 de propietarios suma solo el 12,7% de los comparendos y 72% de los propietarios tiene un único comparendo; entre las personas naturales, el mayor reincidente acumula 27.
Dashboard: las consultas 1, 5 y 6 estaban filtradas a domingos (396 registros, $ 116.647.500) y las 2 y 3 a domingos con 3 o más comparendos; la 4 sumaba códigos. Todo se corrigió en este informe.
Alcance: el período es corto (12/04/2010 a 27/05/2010), así que las conclusiones no son tendencias de largo plazo.
Conclusión general

Los resultados subrayan la importancia de implementar políticas públicas basadas en datos: desde campañas educativas focalizadas hasta operativos estratégicos según el tipo de vehículo, el día y el tipo de infractor. La gestión efectiva de los comparendos no solo debe sancionar, sino también prevenir, orientar y transformar los hábitos de conducción para mejorar la seguridad vial colectiva.

6

Recomendaciones

Calidad de los datos

1
Validar los comparendos con número repetido y la fila duplicada con el área de cobro coactivo.
2
Quitar o fijar de forma explícita las segmentaciones del dashboard (día = domingo) para que los totales coincidan en todas las consultas.
3
Normalizar la escritura de los propietarios (p. ej. GMAC / G.M.A.C.) y no truncar los nombres en la base.
4
Corregir la consulta 4 (contar comparendos, no sumar códigos) y la 3 (usar valor económico).

Gestión y control

5
Priorizar la gestión de las entidades financieras y empresas del top 10, y reforzar el control en fines de semana y sobre las infracciones de mayor valor.
6
Diseñar intervenciones educativas y sancionatorias focalizadas en los reincidentes, con estrategias diferenciadas para personas naturales y jurídicas.

Política pública

7
Destinar parte de los recursos recaudados a seguridad vial y registrar fechas de pago para medir el recaudo efectivo.
8
Ampliar la cobertura a más meses y años para medir tendencias y estacionalidad.
7

Referencias

Fuente de datos

Secretaría de Tránsito de Barranquilla. Base de datos de comparendos, abril–mayo de 2010 (archivo BD_Comparendos_TAD_13.xlsx).

Herramientas

Procesamiento y visualización en R version 4.6.1 (2026-06-24 ucrt) con los paquetes tidyverse, plotly, scales y htmltools.

Datos que mueven una movilidad más segura