knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.2.1     ✔ readr     2.2.0
## ✔ forcats   1.0.1     ✔ stringr   1.6.0
## ✔ ggplot2   4.0.3     ✔ tibble    3.3.1
## ✔ lubridate 1.9.5     ✔ tidyr     1.3.2
## ✔ purrr     1.2.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(readxl)
BD1 <- read_excel("BD1.xlsx")
BD2 <- read_excel("BD2.xlsx")
base_completa <- left_join(BD1, BD2, by = "REGISTRO")

Exploración inicial de la base de datos

library(knitr)

resumen <- data.frame(
  Descripción = c("Total de registros", "Total de variables", "Comunas", "Géneros"),
  Valor = c(
    nrow(base_completa),
    ncol(base_completa),
    n_distinct(base_completa$COMUNA),
    n_distinct(base_completa$GENERO)
  )
)

kable(resumen, caption = "Resumen general de la base de datos")
Resumen general de la base de datos
Descripción Valor
Total de registros 4673
Total de variables 422
Comunas 20
Géneros 2

Punto A — Categorización social y económica

tabla_ocupación <- base_completa %>%
  count(PD) %>%
  mutate(Porcentaje = (n / sum(n)) * 100)

kable(tabla_ocupación,
      digits = 1,
      col.names = c("Ocupación", "Cantidad", "Porcentaje (%)"),
      caption = "Distribución por Ocupación")
Distribución por Ocupación
Ocupación Cantidad Porcentaje (%)
1 1123 24.0
2 1001 21.4
3 360 7.7
4 427 9.1
5 1343 28.7
6 304 6.5
10 16 0.3
11 6 0.1
77 4 0.1
88 88 1.9
99 1 0.0

La población encuestada tiene una muestra donde aproximadamente el 51% son mujeres y el 49% son hombres. Respecto al estrato económico, la gran mayoría habita en estratos medio-bajo, siendo el estrato 2 el de mayor representación con un 43.3%.

library(knitr)

# Tabla ESTRATO
kable(
  as.data.frame(table(base_completa$ESTRATO, useNA = "always")),
  col.names = c("Estrato", "Cantidad"),
  caption = "Distribución por Estrato"
)
Distribución por Estrato
Estrato Cantidad
NA 4673
# Tabla ESTRATO_DEC
kable(
  as.data.frame(table(base_completa$ESTRATO_DEC, useNA = "always")) %>%
    mutate(Porcentaje = round(Freq / sum(Freq) * 100, 1)),
  col.names = c("Estrato", "Cantidad", "Porcentaje (%)"),
  caption = "Distribución por Estrato Declarado"
)
Distribución por Estrato Declarado
Estrato Cantidad Porcentaje (%)
1 753 16.1
2 2026 43.4
3 1282 27.4
4 141 3.0
5 82 1.8
6 3 0.1
7 386 8.3
NA 0 0.0
ggplot(base_completa, aes(x = factor(ESTRATO_DEC))) +
  geom_bar(fill = "#99E0B3", color = "black") +
  labs(title = "Distribución de la población por Estrato",
       x = "Estrato",
       y = "Cantidad de P. Encuestadas") +
  theme_minimal()

Punto B — Percepción de seguridad (Variables P1 a P6)

grafico_punto_b <- base_completa %>%
  select(REGISTRO, P1, P2, P3, P4, P5, P6) %>%
  pivot_longer(cols = P1:P6, names_to = "Pregunta", values_to = "Respuesta") %>%
  filter(!is.na(Respuesta) & Respuesta != 999) %>%
  mutate(Respuesta = factor(Respuesta)) %>%
  group_by(Pregunta, Respuesta) %>%
  summarise(Cantidad = n(), .groups = 'drop') %>%
  group_by(Pregunta) %>%
  mutate(Porcentaje = (Cantidad / sum(Cantidad)) * 100)
ggplot(grafico_punto_b, aes(x = Respuesta, y = Porcentaje, fill = Respuesta)) +
  geom_col(color = "black", show.legend = FALSE) +
  facet_wrap(~ Pregunta, scales = "free_x") +
  labs(title = "Distribución de Percepción de Seguridad (P1 a P6)",
       x = "Escala de Respuesta",
       y = "Porcentaje (%)") +
  theme_minimal()

La percepción general de seguridad en la ciudad, comuna y barrio tiende a ser segura, sin embargo, al comparar con el año anterior, la tendencia se desplaza hacia “Inseguro”. Los picos de “Muy seguro” y “Muy inseguro” son atípicos en la percepción actual, no así al compararla con el año anterior.

Punto C — Percepción según género y estrato

Por género

datos_cruce_genero <- base_completa %>%
  select(REGISTRO, GENERO, P1, P2, P3, P4, P5, P6) %>%
  pivot_longer(cols = P1:P6, names_to = "Pregunta", values_to = "Respuesta") %>%
  filter(!is.na(Respuesta) & Respuesta != 999 & !is.na(GENERO)) %>%
  mutate(Genero_Txt = factor(GENERO, labels = c("Masculino", "Femenino")),
         Respuesta = factor(Respuesta)) %>%
  group_by(Pregunta, Genero_Txt, Respuesta) %>%
  summarise(Cantidad = n(), .groups = 'drop') %>%
  group_by(Pregunta, Genero_Txt) %>%
  mutate(Porcentaje = (Cantidad / sum(Cantidad)) * 100)
ggplot(datos_cruce_genero, aes(x = Respuesta, y = Porcentaje, fill = Genero_Txt)) +
  geom_col(position = "dodge", color = "black") +
  facet_wrap(~ Pregunta) +
  labs(title = "Comparativa de Percepción (P1-P6) por Género",
       x = "Escala de Respuesta",
       y = "Porcentaje (%)",
       fill = "Género") +
  scale_fill_manual(values = c("Masculino" = "#3498db", "Femenino" = "pink")) +
  theme_minimal()

Por estrato

datos_cruce_estrato <- base_completa %>%
  select(REGISTRO, ESTRATO_DEC, P1, P2, P3, P4, P5, P6) %>%
  pivot_longer(cols = P1:P6, names_to = "Pregunta", values_to = "Respuesta") %>%
  filter(!is.na(Respuesta) & Respuesta != 999 & !is.na(ESTRATO_DEC)) %>%
  mutate(Estrato_Txt = factor(ESTRATO_DEC),
         Respuesta = factor(Respuesta)) %>%
  group_by(Pregunta, Estrato_Txt, Respuesta) %>%
  summarise(Cantidad = n(), .groups = 'drop') %>%
  group_by(Pregunta, Estrato_Txt) %>%
  mutate(Porcentaje = (Cantidad / sum(Cantidad)) * 100)
ggplot(datos_cruce_estrato, aes(x = Respuesta, y = Porcentaje, fill = Estrato_Txt)) +
  geom_col(position = "dodge", color = "black") +
  geom_text(aes(label = Estrato_Txt),
            position = position_dodge(width = 0.9),
            vjust = -0.5,
            size = 2.8) +
  facet_wrap(~ Pregunta) +
  labs(title = "Comparativa de Percepción (P1-P6) por Estrato Socioeconómico",
       x = "Escala de Respuesta",
       y = "Porcentaje (%)",
       fill = "Estrato") +
  theme_minimal()

Punto D — Índice de Victimización

Índice para toda la ciudad

indice_ciudad <- base_completa %>%
  mutate(es_victima = ifelse(P20A == 1, 1, 0)) %>%
  summarise(
    Indice_Total = sum(es_victima * FACTOR, na.rm = TRUE) / sum(FACTOR, na.rm = TRUE)
  )
print(indice_ciudad)
## # A tibble: 1 × 1
##   Indice_Total
##          <dbl>
## 1        0.130

El índice de victimización para la ciudad es de 0.13, es decir, del 13%.

Índice por comunas

library(knitr)

indice_por_comuna <- base_completa %>%
  mutate(es_victima = ifelse(P20A == 1, 1, 0)) %>%
  group_by(COMUNA) %>%
  summarise(
    Indice_Victimizacion = sum(es_victima * FACTOR, na.rm = TRUE) / sum(FACTOR, na.rm = TRUE)
  ) %>%
  arrange(desc(Indice_Victimizacion))
kable(indice_por_comuna)
COMUNA Indice_Victimizacion
5 0.2174689
13 0.1653720
7 0.1443258
9 0.1428635
90 0.1427988
60 0.1419080
1 0.1412376
80 0.1355578
16 0.1325322
3 0.1296867
10 0.1225782
2 0.1224477
8 0.1146999
11 0.1142255
70 0.1057429
4 0.0997149
6 0.0726010
15 0.0595877
12 0.0433211
50 0.0000000

El mayor índice de victimización corresponde a la comuna 5 con un índice de 0.217 (21.7%), mientras que el menor corresponde a la comuna 50 con un índice de 0.