Se trata de dos archivos excel: validación de evidencias por agente y reporte de evidencia
library(openxlsx)
val_agente = read.xlsx("/home/dferroa/Documentos/Secretaria de Movilidad/CAMARAS/VALIDACION DE EVIDENCIAS POR AGENTE_oct-dic-2024.xlsx")
registro = read.xlsx("/home/dferroa/Documentos/Secretaria de Movilidad/CAMARAS/Reporte_evidencias_de_oct_a_dic_2024.xlsx")
registros_agentes = left_join(registro, val_agente, by = c('FECHA.EVIDENCIA','CAMARA','PLACA','INFRACCIONES.APROBADAS','INFRACCIONES.RECHAZADAS')) %>%
mutate(COMPARENDO.APROBADO = ifelse(ESTADO == "aprobado", 1,0)) %>%
mutate(COMPARENDO.RECHAZADO = ifelse(ESTADO == "rechazado", 1,0))
## Warning in left_join(registro, val_agente, by = c("FECHA.EVIDENCIA", "CAMARA", : Detected an unexpected many-to-many relationship between `x` and `y`.
## ℹ Row 2628 of `x` matches multiple rows in `y`.
## ℹ Row 282141 of `y` matches multiple rows in `x`.
## ℹ If a many-to-many relationship is expected, set `relationship =
## "many-to-many"` to silence this warning.
colnames(registros_agentes)
## [1] "FECHA.EVIDENCIA" "HORA.EVIDENCIA.x"
## [3] "PUNTO.DE.FOTODETECCION" "CAMARA"
## [5] "PLACA" "VELOCIDAD.DEL.VEHICULO"
## [7] "VELOCIDAD.LIMITE" "ESTADO"
## [9] "TIPO" "INFRACCIONES.POR.VALIDAR"
## [11] "INFRACCIONES.APROBADAS" "INFRACCIONES.RECHAZADAS"
## [13] "CLASE.VEHICULO" "TIPO.SERVICIO"
## [15] "MODALIDAD.DE.SERVICIO" "LOCALIDAD"
## [17] "HORA.EVIDENCIA.y" "FECHA.VALIDACION"
## [19] "HORA.VALIDACION" "IDENTIFICACION.AGENTE"
## [21] "MOTIVO" "OBSERVACIONES"
## [23] "COMPARENDO.APROBADO" "COMPARENDO.RECHAZADO"
duplicados <- duplicated(registros_agentes)
sum(duplicados)
## [1] 0
sum(duplicados_columnas <- registros_agentes %>%
duplicated(subset = c("PLACA", "FECHA.EVIDENCIA")))
## [1] 0
evidenciaXagente = registros_agentes %>%
group_by(IDENTIFICACION.AGENTE) %>%
summarise(CONTEO = n(),
PORCENTAJE = round((n() / nrow(registros_agentes))* 100,1) ,
.groups = "drop") %>%
as.data.frame()
ggplot(evidenciaXagente, aes(x = reorder(IDENTIFICACION.AGENTE, -CONTEO), y = CONTEO)) +
geom_bar(stat = "identity", fill = "#b1615c") + # Usar un color específico de Cassatt1
geom_text(aes(label = paste0(PORCENTAJE, "%")), vjust = -0.5, size = 2.2) + # Agregar etiquetas de porcentaje
labs(
title = "Evidencias revisadas por Agente",
x = "Agentes",
y = "Conteo"
) +
theme_minimal() +
theme(
axis.text.x = element_text(angle = 45, hjust = 0.8), # Rotar los nombres de los agentes
plot.title = element_text(hjust = 0.5, size = 16, face = "bold") # Ajustar el título
)
## GRÁFICA
GENERAL DE PARETO DEL NÚMERO DE REVISIÓN DE EVIDENCIAS POR AGENTE
evidenciaXagente <- evidenciaXagente %>%
arrange(desc(CONTEO)) %>%
mutate(PORCENTAJE_ACUMULADO = cumsum(PORCENTAJE))
punto_80 <- evidenciaXagente %>%
filter(PORCENTAJE_ACUMULADO >= 80) %>%
slice(1)
ggplot(evidenciaXagente, aes(x = reorder(IDENTIFICACION.AGENTE, -CONTEO), y = CONTEO)) +
geom_bar(stat = "identity", fill = "#b1615c") + # Barras de conteo
geom_line(aes(y = PORCENTAJE_ACUMULADO * max(CONTEO) / 100), # Línea acumulada
group = 1, color = "blue", linewidth = 0.5) +
geom_point(aes(y = PORCENTAJE_ACUMULADO * max(CONTEO) / 100), color = "blue") +
# Resaltar el punto del 80% en la línea acumulada en la misma altura
geom_point(data = punto_80, aes(x = IDENTIFICACION.AGENTE,
y = PORCENTAJE_ACUMULADO * max(CONTEO) / 100),
color = "red", size = 4) + # Resaltamos el punto en la línea acumulada
geom_text(aes(label = paste0(PORCENTAJE, "%")), vjust = -0.5, size = 2) + # Etiquetas de porcentaje
labs(
title = "Análisis de Pareto: Conteo y Porcentaje Acumulado por Agente",
x = "Agentes",
y = "Conteo",
caption = "Línea azul: Porcentaje acumulado"
) +
scale_y_continuous(
sec.axis = sec_axis(~ . * 100 / max(evidenciaXagente$CONTEO), name = "Porcentaje Acumulado (%)") # Eje secundario para porcentaje
) +
theme_minimal() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1, size = 4), # Rotar los nombres de los agentes
plot.title = element_text(hjust = 0.5, size = 16, face = "bold") # Ajustar el título
)
Los
agentes que concentran el 80% de la revisión de evidencias de oct a dic
de 2024 son:
ochenta_agentes = evidenciaXagente %>%
mutate(PORCENTAJE_ACUMULADO = cumsum(PORCENTAJE)) %>%
filter(PORCENTAJE_ACUMULADO <= 80)
print(ochenta_agentes$IDENTIFICACION.AGENTE)
## [1] "AGENTE 6" NA "AGENTE 8" "AGENTE 3" "AGENTE 16" "AGENTE 12"
## [7] "AGENTE 2" "AGENTE 18" "AGENTE 24" "AGENTE 19" "AGENTE 17" "AGENTE 22"
## [13] "AGENTE 26" "AGENTE 13"
comparendo_aprobado =
registros_agentes %>%
filter(COMPARENDO.APROBADO == 1) %>%
group_by(IDENTIFICACION.AGENTE)%>%
summarise(CONTEO = n()) %>%
ungroup() %>%
mutate(APROBADO = round((CONTEO/sum(registros_agentes$COMPARENDO.APROBADO)* 100),1)) %>%
as.data.frame()
ggplot(comparendo_aprobado, aes(x = reorder(IDENTIFICACION.AGENTE, -APROBADO), y = APROBADO)) +
geom_bar(stat = "identity", , fill = "#b1615c", show.legend = FALSE) +
geom_text(aes(label = paste0(APROBADO, "%")), hjust = -0.3, size = 2, vjust = 0.5) +
labs(title = "Porcentaje comparendos aprobados por agente",
x = "Agente",
y = "Porcentaje") +
coord_flip()+
theme_minimal()+
theme(axis.text.y = element_text(size = 6, angle = 0, vjust = 0.5, hjust = 0.5),
plot.title = element_text(hjust = 0.5, size = 16, face = "bold"))
## AGENTES
QUE MENOS IMPUSIERON COMPARENDOS POR VELOCIDAD
comparendo_rechazado =
registros_agentes %>%
filter(COMPARENDO.RECHAZADO == 1) %>%
group_by(IDENTIFICACION.AGENTE)%>%
summarise(CONTEO = n()) %>%
ungroup() %>%
mutate(RECHAZADO = round((CONTEO/sum(registros_agentes$COMPARENDO.RECHAZADO)* 100),1)) %>%
as.data.frame() %>%
arrange(desc(RECHAZADO))
ggplot(comparendo_rechazado, aes(x = reorder(IDENTIFICACION.AGENTE, -RECHAZADO), y = RECHAZADO)) +
geom_bar(stat = "identity", , fill = "#b1615c", show.legend = FALSE) +
geom_text(aes(label = paste0(RECHAZADO, "%")), hjust = -0.3, size = 2, vjust = 0.5) +
labs(title = "Porcentaje comparendos rechazados por agente",
x = "Agente",
y = "Porcentaje") +
coord_flip()+
theme_minimal()+
theme(axis.text.y = element_text(size = 6, angle = 0, vjust = 0.5, hjust = 0.5),
plot.title = element_text(hjust = 0.5, size = 16, face = "bold"))
##
PORCENTAJE RECHAZOS Y APROBADOS POR AGENTE
aprobado_rechazadoXagente <- registros_agentes %>%
group_by(IDENTIFICACION.AGENTE, ESTADO) %>%
summarise(CONTEO = n()) %>%
mutate(PORCENTAJE = round(100 * CONTEO / sum(CONTEO), 2)) %>%
as.data.frame()
## `summarise()` has grouped output by 'IDENTIFICACION.AGENTE'. You can override
## using the `.groups` argument.
color_apr <- met.brewer(name = "Cassatt1", n = 8, type = "discrete")[1]
color_rec <- met.brewer(name = "Cassatt1", n = 8, type = "discrete")[8]
ggplot(aprobado_rechazadoXagente, aes(x = IDENTIFICACION.AGENTE, y = PORCENTAJE, fill = ESTADO)) +
geom_bar(stat = "identity", position = position_dodge(width = 0.9)) +
geom_text(aes(label = paste0(PORCENTAJE, "%")),
position = position_dodge(width = 0.9),
size = 1.2, # Tamaño ajustado para mejor visibilidad
hjust = -0.1) + # Ajusta la posición horizontal de las etiquetas
ylim(0, 100) +
labs(title = "Porcentaje de evidencias por estado y por agente",
x = "Agente",
y = "Porcentaje (%)",
caption = "Fuente: ") +
scale_fill_manual(values = c("aprobado" = color_apr, "rechazado" = color_rec)) +
theme_minimal() +
theme(plot.caption = element_text(size = 8, hjust = 0.5, face = "italic", color = "grey"),
legend.text = element_text(size = 8),
legend.title = element_text(size = 9),
legend.key.size = unit(0.4, "cm"),
legend.spacing.y = unit(0.2, "cm"),
legend.margin = margin(0, 0, 0, 0),
axis.text.y = element_text(size = 5, angle = 0, vjust = 0.5, hjust = 0.5)) +
coord_flip()
##
RAZONES DE RECHAZO EN GENERAL
motivos <- c("BAJA CALIDAD O FALLA EN FOTOGRAFIA",
"NO APLICA INFRACCIÓN AL TIPO DE VEHICULO",
"SUPERO INFRACCIONES IMPUESTAS POR DIA AL MISMO CONDUCTOR",
"BAJA CALIDAD O FALLA EN VIDEO",
"ERROR EN CARGUE DE FOTO O VIDEO",
"NO SE EVIDENCIA INFRACCION O FALLA EN CAMARA",
"ERROR EN IDENTIFICACIÓN DE PLACA",
"EXCEDER TIEMPO LIMITE LEGAL PARA VALIDAR",
"FACTORES AMBIENTALES",
"FACTORES HUMANOS",
"FORMATO NO DILIGENCIADO CORRECTAMENTE",
"INCONSISTENCIA CARACTERISTICAS DEL VEHICULO",
"INFORMACION INSUFICIENTE PARA GENERAR UN COMPARENDO",
"NO REGISTRA DATOS SUFICIENTES",
"VEHICULO FUERA DE RANGO DE VIDEO")
for (MOTIVO_ACTUAL in motivos) {
registros_agentes[[MOTIVO_ACTUAL]] <- as.integer(grepl(MOTIVO_ACTUAL, registros_agentes$MOTIVO))
}
motivos_por_agente <- registros_agentes %>%
group_by(IDENTIFICACION.AGENTE) %>%
summarise(CONTEO_GENERAL= n(),across(all_of(motivos), sum, .names = "count_{.col}")) %>%
mutate(across(starts_with("count_"), ~ round((./ CONTEO_GENERAL)*100,1), .names = "prop_{.col}")) %>%
mutate(orden = match(IDENTIFICACION.AGENTE, comparendo_rechazado$IDENTIFICACION.AGENTE)) %>%
arrange(orden) %>%
select(-orden) %>%
select(IDENTIFICACION.AGENTE,CONTEO_GENERAL,starts_with("prop_")) %>%
rename_with(~ gsub("^prop_count_", "", .x)) %>% # Eliminar "prop_count_"
rename_with(~ gsub(" ", "\n", .x))
motivos_por_agente <- registros_agentes %>%
group_by(IDENTIFICACION.AGENTE) %>%
summarise(CONTEO_GENERAL= n(),across(all_of(motivos), sum, .names = "count_{.col}")) %>%
#mutate(orden = match(IDENTIFICACION.AGENTE, comparendo_rechazado$IDENTIFICACION.AGENTE)) %>%
#arrange(orden) %>%
select(-CONTEO_GENERAL) %>%
select(IDENTIFICACION.AGENTE,starts_with("count_")) %>%
rename_with(~ gsub("^count_", "", .x)) %>% # Eliminar "prop_count_"
rename_with(~ gsub(" ", "\n", .x))
tabla_contingencia <- motivos_por_agente %>%
select(-IDENTIFICACION.AGENTE) %>% # Excluir la columna de agentes
summarise(across(everything(), sum)) %>% # Sumar por columnas
mutate(IDENTIFICACION.AGENTE = "TOTAL") # Agregar fila de total
tabla_contingencia <- motivos_por_agente %>%
mutate(TOTAL_FILA = rowSums(select(., -IDENTIFICACION.AGENTE))) %>% # Sumar filas
bind_rows(tabla_contingencia) # Unir con la fila de totales
total_general <- sum(tabla_contingencia[nrow(tabla_contingencia), -1], na.rm = TRUE)
tabla_contingencia[nrow(tabla_contingencia), "TOTAL_FILA"] <- total_general
#colnames(tabla_contingencia)[1] <- "IDENTIFICACION.AGENTE"
tabla_contingencia_percent <- tabla_contingencia %>%
mutate(across(-IDENTIFICACION.AGENTE, ~ round((. / total_general) * 100,1))) %>%
mutate(orden = match(IDENTIFICACION.AGENTE, comparendo_rechazado$IDENTIFICACION.AGENTE)) %>%
arrange(orden) %>%
select(-orden) %>%
mutate(across(-IDENTIFICACION.AGENTE, ~ as.numeric(gsub(",", ".", .)))) %>%
mutate(across(where(is.numeric), ~ replace(., is.na(.), 0)))
# Imprimir la tabla formateada
tabla_contingencia_percent %>%
kable("html", escape = FALSE) %>%
kable_styling(bootstrap_options = c("striped", "hover"))
| IDENTIFICACION.AGENTE | BAJA CALIDAD O FALLA EN FOTOGRAFIA | NO APLICA INFRACCIÓN AL TIPO DE VEHICULO | SUPERO INFRACCIONES IMPUESTAS POR DIA AL MISMO CONDUCTOR | BAJA CALIDAD O FALLA EN VIDEO | ERROR EN CARGUE DE FOTO O VIDEO | NO SE EVIDENCIA INFRACCION O FALLA EN CAMARA | ERROR EN IDENTIFICACIÓN DE PLACA | EXCEDER TIEMPO LIMITE LEGAL PARA VALIDAR | FACTORES AMBIENTALES | FACTORES HUMANOS | FORMATO NO DILIGENCIADO CORRECTAMENTE | INCONSISTENCIA CARACTERISTICAS DEL VEHICULO | INFORMACION INSUFICIENTE PARA GENERAR UN COMPARENDO | NO REGISTRA DATOS SUFICIENTES | VEHICULO FUERA DE RANGO DE VIDEO | TOTAL_FILA |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| NA | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 |
| AGENTE 6 | 4.2 | 0.3 | 0.0 | 0.0 | 0.4 | 2.5 | 0.5 | 0 | 0.1 | 0.1 | 0.2 | 0.0 | 0 | 1.1 | 0.0 | 9.4 |
| AGENTE 8 | 1.3 | 0.4 | 0.0 | 0.1 | 0.9 | 1.5 | 0.8 | 0 | 0.2 | 0.1 | 0.4 | 0.0 | 0 | 1.0 | 0.0 | 6.8 |
| AGENTE 12 | 1.5 | 0.4 | 0.0 | 0.0 | 0.2 | 1.9 | 1.0 | 0 | 0.1 | 0.0 | 0.4 | 0.0 | 0 | 1.1 | 0.0 | 6.6 |
| AGENTE 24 | 1.4 | 0.2 | 0.0 | 0.0 | 0.3 | 2.3 | 0.4 | 0 | 0.4 | 0.1 | 0.8 | 0.0 | 0 | 0.5 | 0.0 | 6.5 |
| AGENTE 16 | 0.9 | 0.3 | 0.0 | 0.0 | 0.8 | 1.7 | 0.9 | 0 | 0.1 | 0.2 | 0.5 | 0.0 | 0 | 1.0 | 0.0 | 6.4 |
| AGENTE 18 | 1.2 | 0.2 | 0.0 | 0.0 | 0.4 | 2.0 | 0.5 | 0 | 0.1 | 0.1 | 0.5 | 0.1 | 0 | 1.0 | 0.0 | 6.3 |
| AGENTE 2 | 1.8 | 0.2 | 0.0 | 0.0 | 0.0 | 2.4 | 0.7 | 0 | 0.0 | 0.0 | 1.0 | 0.0 | 0 | 0.0 | 0.0 | 6.1 |
| AGENTE 3 | 1.4 | 0.4 | 0.0 | 0.0 | 0.2 | 1.7 | 0.6 | 0 | 0.1 | 0.1 | 0.4 | 0.1 | 0 | 1.0 | 0.0 | 6.0 |
| AGENTE 19 | 1.0 | 0.2 | 0.0 | 0.0 | 0.0 | 2.3 | 0.3 | 0 | 0.1 | 0.1 | 0.9 | 0.1 | 0 | 0.2 | 0.0 | 5.2 |
| AGENTE 17 | 1.7 | 0.3 | 0.0 | 0.0 | 0.0 | 1.6 | 0.4 | 0 | 0.0 | 0.1 | 0.9 | 0.0 | 0 | 0.0 | 0.0 | 5.0 |
| AGENTE 22 | 1.8 | 0.2 | 0.0 | 0.0 | 0.0 | 0.9 | 0.2 | 0 | 0.0 | 0.0 | 1.0 | 0.0 | 0 | 0.0 | 0.0 | 4.2 |
| AGENTE 13 | 1.1 | 0.2 | 0.0 | 0.0 | 0.1 | 1.3 | 0.4 | 0 | 0.0 | 0.0 | 0.2 | 0.0 | 0 | 0.7 | 0.0 | 3.9 |
| AGENTE 25 | 0.7 | 0.2 | 0.0 | 0.0 | 0.0 | 1.3 | 0.4 | 0 | 0.1 | 0.1 | 0.2 | 0.0 | 0 | 0.5 | 0.0 | 3.5 |
| AGENTE 26 | 1.2 | 0.2 | 0.0 | 0.0 | 0.0 | 0.6 | 0.6 | 0 | 0.0 | 0.0 | 0.7 | 0.0 | 0 | 0.0 | 0.0 | 3.6 |
| AGENTE 20 | 1.0 | 0.1 | 0.0 | 0.0 | 0.0 | 1.2 | 0.3 | 0 | 0.0 | 0.0 | 0.1 | 0.0 | 0 | 0.4 | 0.0 | 3.2 |
| AGENTE 11 | 1.1 | 0.1 | 0.0 | 0.0 | 0.0 | 0.3 | 0.4 | 0 | 0.1 | 0.0 | 0.3 | 0.0 | 0 | 0.4 | 0.0 | 2.8 |
| AGENTE 1 | 0.6 | 0.1 | 0.0 | 0.0 | 0.0 | 0.6 | 0.5 | 0 | 0.0 | 0.0 | 0.6 | 0.0 | 0 | 0.0 | 0.0 | 2.5 |
| AGENTE 9 | 0.5 | 0.1 | 0.0 | 0.0 | 0.1 | 0.7 | 0.2 | 0 | 0.0 | 0.0 | 0.4 | 0.0 | 0 | 0.0 | 0.0 | 1.9 |
| AGENTE 21 | 0.6 | 0.1 | 0.0 | 0.0 | 0.1 | 0.3 | 0.2 | 0 | 0.0 | 0.0 | 0.2 | 0.0 | 0 | 0.1 | 0.0 | 1.7 |
| AGENTE 7 | 0.5 | 0.1 | 0.0 | 0.0 | 0.0 | 0.5 | 0.2 | 0 | 0.0 | 0.0 | 0.1 | 0.0 | 0 | 0.2 | 0.0 | 1.7 |
| AGENTE 27 | 0.5 | 0.1 | 0.0 | 0.0 | 0.0 | 0.4 | 0.2 | 0 | 0.0 | 0.0 | 0.3 | 0.0 | 0 | 0.0 | 0.0 | 1.5 |
| AGENTE 29 | 0.5 | 0.1 | 0.0 | 0.0 | 0.0 | 0.5 | 0.1 | 0 | 0.0 | 0.1 | 0.2 | 0.0 | 0 | 0.0 | 0.0 | 1.5 |
| AGENTE 23 | 0.9 | 0.1 | 0.0 | 0.0 | 0.0 | 0.0 | 0.1 | 0 | 0.0 | 0.0 | 0.2 | 0.0 | 0 | 0.0 | 0.0 | 1.3 |
| AGENTE 5 | 0.7 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.1 | 0.0 | 0 | 0.0 | 0.0 | 0.9 |
| AGENTE 10 | 0.2 | 0.0 | 0.0 | 0.0 | 0.0 | 0.1 | 0.1 | 0 | 0.0 | 0.0 | 0.1 | 0.0 | 0 | 0.0 | 0.0 | 0.5 |
| AGENTE 15 | 0.2 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.3 |
| AGENTE 28 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.1 | 0.1 | 0 | 0.0 | 0.0 | 0.1 | 0.0 | 0 | 0.0 | 0.0 | 0.4 |
| AGENTE 14 | 0.1 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.2 |
| AGENTE 4 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 |
| TOTAL | 28.7 | 4.5 | 0.1 | 0.3 | 3.8 | 28.9 | 9.8 | 0 | 1.7 | 1.3 | 10.9 | 0.5 | 0 | 9.5 | 0.1 | 100.0 |