Análisis Descriptivo Exploratorio de la Salud Mental y Calidad de Atención en Policías de Puno
Informe Inicial (Estudio Piloto)
Author
Nadine López Villanes
Published
Invalid Date
# --- Carga de datos desde archivo Excel ---# Especificar el nombre del archivo Excel. Se asume que el archivo está# en el mismo directorio donde se encuentra este archivo .qmd.archivo_excel <-"Data SM.xlsx"# Nombre del archivo proporcionado# Utilizar read_excel para leer el archivo.# Si los datos estuvieran en una hoja diferente a la primera, se especificaría con 'sheet = "NombreHoja"'.tryCatch({ datos_raw <-read_excel(archivo_excel)# Mensaje de confirmación (se mostrará al renderizar el documento si no hay errores)message("El archivo Excel ha sido cargado exitosamente.")}, error =function(e) {# Mensaje de error si la carga falla, y detener el proceso de renderizadostop("ERROR: No se pudo cargar el archivo Excel. Verifique el nombre del archivo y su ubicación. Mensaje original: ", e$message)})# --- Exploración Inicial de los datos cargados ---# Mostrar las primeras filas para inspeccionar la estructura y el contenido inicialcat("### Primeras 6 filas de los datos cargados\n") # Usar Markdown para subtítulos
### Primeras 6 filas de los datos cargados
print(head(datos_raw))
# A tibble: 6 × 19
`Marca temporal` 1. Para iniciar, indique por favo…¹ 2. Ingrese su edad e…²
<dttm> <chr> <chr>
1 2025-01-23 20:50:03 DPTO PUNO, PROVINCIA PUNO DISTRITO… 41
2 2025-01-23 21:01:33 Puno, Puno, Chucuito 34
3 2025-01-23 21:02:01 <NA> 31
4 2025-01-23 21:04:51 Puno Puno Chucuito 25
5 2025-01-23 21:12:09 Puno, puno, chucuito 33
6 2025-01-23 21:15:07 Puno puno puno 38
# ℹ abbreviated names:
# ¹`1. Para iniciar, indique por favor el departamento, provincia y distrito en el cual se encuentra laborando. (Ejemplo: Cusco, Cusco, Wanchaq)`,
# ²`2. Ingrese su edad en números`
# ℹ 16 more variables: `3. Indique su sexo` <chr>,
# `4. En qué tipo de comisaría labora` <chr>,
# `5. ¿Cuál es su rango policial?` <chr>,
# `6. Tiempo de servicio en la Policía Nacional:` <chr>, …
# Mostrar la estructura y tipos de datos detectados por Rcat("### Estructura de los datos (str)\n")
### Estructura de los datos (str)
print(str(datos_raw))
tibble [334 × 19] (S3: tbl_df/tbl/data.frame)
$ Marca temporal : POSIXct[1:334], format: "2025-01-23 20:50:03" "2025-01-23 21:01:33" ...
$ 1. Para iniciar, indique por favor el departamento, provincia y distrito en el cual se encuentra laborando. (Ejemplo: Cusco, Cusco, Wanchaq) : chr [1:334] "DPTO PUNO, PROVINCIA PUNO DISTRITO CHUCUITO" "Puno, Puno, Chucuito" NA "Puno Puno Chucuito" ...
$ 2. Ingrese su edad en números : chr [1:334] "41" "34" "31" "25" ...
$ 3. Indique su sexo : chr [1:334] "Mujer" "Varón" "Varón" "Varón" ...
$ 4. En qué tipo de comisaría labora : chr [1:334] "A. Comisaría básica" "A. Comisaría básica" "A. Comisaría básica" "A. Comisaría básica" ...
$ 5. ¿Cuál es su rango policial? : chr [1:334] "A. Suboficial" "B. Oficial" "A. Suboficial" "A. Suboficial" ...
$ 6. Tiempo de servicio en la Policía Nacional: : chr [1:334] "C. De 10 a 15 años" "B. De 5 a 10 años" "B. De 5 a 10 años" "A. Menos de 5 años" ...
$ 7. ¿Qué tipo de casos atiende con mayor frecuencia? : chr [1:334] "g. Otros" "b. Violencia psicológica" "g. Otros" "g. Otros" ...
$ 8. ¿Considera que tiene los recursos necesarios (infraestructura, herramientas, personal) para atender adecuadamente a las víctimas? : chr [1:334] "c. Muy pocas veces" "b. A veces" "a. Siempre" "d. Nunca" ...
$ 9. En una escala del 1 al 5, donde 1 es “nunca” y 5 es “siempre”, ¿con qué frecuencia siente que su trabajo lo agota emocionalmente? : chr [1:334] "a. 1 (nunca)" "b. 2 (raramente)" "a. 1 (nunca)" "a. 1 (nunca)" ...
$ 10. En una escala del 1 al 5, donde 1 es “nunca” y 5 es “siempre”, ¿Cree que el estrés laboral afecta su capacidad para atender adecuadamente a los ciudadanos?: chr [1:334] "b. 2 (en desacuerdo)" "d. 4 (de acuerdo)" "a. 1 (totalmente en desacuerdo)" "a. 1 (totalmente en desacuerdo)" ...
$ 11. ¿Qué factores considera más estresantes en su trabajo diario? : chr [1:334] "b. Falta de recursos" "a. Carga laboral" "f. otros" "b. Falta de recursos" ...
$ 12. En una escala del 1 al 5, donde 1 es “muy baja” y 5 es “muy alta”, ¿cómo califica la calidad de atención que su comisaría brinda a las víctimas? : chr [1:334] "d. 4" "d. 4" "a. 1 (muy baja)" "e. 5 (muy alta)" ...
$ 13. ¿Qué factores considera que limitan la calidad de atención a las víctimas? (puede marcar más de una). : chr [1:334] "c. Falta de logística" "a. Sobrecarga laboral" "b. Falta de especialización" "c. Falta de logística" ...
$ 14. ¿Ha recibido formación o capacitación sobre salud mental por parte de la Policía? : chr [1:334] "b. No" "a. Sí" "b. No" "b. No" ...
$ 15 ¿Cuenta con acceso a servicios psicológicos en su unidad policial, la región policial o a través de la Dirección de Sanidad Policial? : chr [1:334] "a. Sí" "a. Sí" "a. Sí" "b. No" ...
$ 16. ¿Le gustaría recibir información personalizada en su celular para el manejo del estrés, ansiedad y la depresión? : chr [1:334] "b. No" "a. Sí" "a. Sí" "a. Sí" ...
$ 17. ¿Le gustaría contar con mayores recursos cognitivos para sentirse bien? : chr [1:334] "b. No" "a. Sí" "a. Sí" "a. Sí" ...
$ 18. ¿Qué red social usa más? : chr [1:334] "d. Facebook" "d. Facebook" "d. Facebook" "d. Facebook" ...
NULL
# Mostrar un resumen básico para cada columna (identificar NAs iniciales y rangos)cat("### Resumen básico de los datos cargados (summary)\n")
### Resumen básico de los datos cargados (summary)
print(summary(datos_raw))
Marca temporal
Min. :2025-01-23 20:50:03.07
1st Qu.:2025-01-24 11:34:06.29
Median :2025-01-24 13:18:37.46
Mean :2025-01-24 22:12:14.91
3rd Qu.:2025-01-24 20:05:17.05
Max. :2025-01-28 17:35:08.13
1. Para iniciar, indique por favor el departamento, provincia y distrito en el cual se encuentra laborando. (Ejemplo: Cusco, Cusco, Wanchaq)
Length:334
Class :character
Mode :character
2. Ingrese su edad en números 3. Indique su sexo
Length:334 Length:334
Class :character Class :character
Mode :character Mode :character
4. En qué tipo de comisaría labora 5. ¿Cuál es su rango policial?
Length:334 Length:334
Class :character Class :character
Mode :character Mode :character
6. Tiempo de servicio en la Policía Nacional:
Length:334
Class :character
Mode :character
7. ¿Qué tipo de casos atiende con mayor frecuencia?
Length:334
Class :character
Mode :character
8. ¿Considera que tiene los recursos necesarios (infraestructura, herramientas, personal) para atender adecuadamente a las víctimas?
Length:334
Class :character
Mode :character
9. En una escala del 1 al 5, donde 1 es “nunca” y 5 es “siempre”, ¿con qué frecuencia siente que su trabajo lo agota emocionalmente?
Length:334
Class :character
Mode :character
10. En una escala del 1 al 5, donde 1 es “nunca” y 5 es “siempre”, ¿Cree que el estrés laboral afecta su capacidad para atender adecuadamente a los ciudadanos?
Length:334
Class :character
Mode :character
11. ¿Qué factores considera más estresantes en su trabajo diario?
Length:334
Class :character
Mode :character
12. En una escala del 1 al 5, donde 1 es “muy baja” y 5 es “muy alta”, ¿cómo califica la calidad de atención que su comisaría brinda a las víctimas?
Length:334
Class :character
Mode :character
13. ¿Qué factores considera que limitan la calidad de atención a las víctimas? (puede marcar más de una).
Length:334
Class :character
Mode :character
14. ¿Ha recibido formación o capacitación sobre salud mental por parte de la Policía?
Length:334
Class :character
Mode :character
15 ¿Cuenta con acceso a servicios psicológicos en su unidad policial, la región policial o a través de la Dirección de Sanidad Policial?
Length:334
Class :character
Mode :character
16. ¿Le gustaría recibir información personalizada en su celular para el manejo del estrés, ansiedad y la depresión?
Length:334
Class :character
Mode :character
17. ¿Le gustaría contar con mayores recursos cognitivos para sentirse bien?
Length:334
Class :character
Mode :character
18. ¿Qué red social usa más?
Length:334
Class :character
Mode :character
# --- Limpieza y Preparación de Datos ---# Este chunk procesa los datos cargados en 'datos_raw'.# Definir los nombres originales de las columnas TAL COMO FUERON CARGADOS desde el archivo Excel.# Esta lista se basa en la cadena de texto que proporcionaste previamente.# La usamos como referencia para el mapeo de posición.nombres_originales_referencia <-c("Marca temporal","1. Para iniciar, indique por favor el departamento, provincia y distrito en el cual se encuentra laborando. (Ejemplo: Cusco, Cusco, Wanchaq)","2. Ingrese su edad en números","3. Indique su sexo","4. En qué tipo de comisaría labora","5. ¿Cuál es su rango policial?","6. Tiempo de servicio en la Policía Nacional:","7. ¿Qué tipo de casos atiende con mayor frecuencia?","8. ¿Considera que tiene los recursos necesarios (infraestructura, herramientas, personal) para atender adecuadamente a las víctimas?","9. En una escala del 1 al 5, donde 1 es “nunca” y 5 es “siempre”, ¿con qué frecuencia siente que su trabajo lo agota emocionalmente?","10. En una escala del 1 al 5, donde 1 es “nunca” y 5 es “siempre”, ¿Cree que el estrés laboral afecta su capacidad para atender adecuadamente a los ciudadanos? ","11. ¿Qué factores considera más estresantes en su trabajo diario? ","12. En una escala del 1 al 5, donde 1 es “muy baja” y 5 es “muy alta”, ¿cómo califica la calidad de atención que su comisaría brinda a las víctimas?","13. ¿Qué factores considera que limitan la calidad de atención a las víctimas? (puede marcar más de una).","14. ¿Ha recibido formación o capacitación sobre salud mental por parte de la Policía?","15 ¿Cuenta con acceso a servicios psicológicos en su unidad policial, la región policial o a través de la Dirección de Sanidad Policial?","16. ¿Le gustaría recibir información personalizada en su celular para el manejo del estrés, ansiedad y la depresión?","17. ¿Le gustaría contar con mayores recursos cognitivos para sentirse bien?","18. ¿Qué red social usa más?")# Definir los nuevos nombres descriptivos para cada columna.# Este vector debe tener el mismo número de elementos (19) que las columnas cargadas# y cada nuevo nombre debe estar en la posición que corresponde a su nombre original.nombres_nuevos <-c("Marca Temporal", # Posición 1"Ubicación", # Posición 2 (Pregunta 1) - Ahora con tilde"Edad", # Posición 3 (Pregunta 2) - No necesita backticks"Sexo", # Posición 4 (Pregunta 3) - No necesita backticks"Tipo de comisaría", # Posición 5 (Pregunta 4)"Rango policial", # Posición 6 (Pregunta 5) - No necesita backticks"Tiempo de servicio", # Posición 7 (Pregunta 6)"Tipo de casos que atiende frecuentemente", # Posición 8 (Pregunta 7) - Nombre actualizado"Recursos necesarios", # Posición 9 (Pregunta 8)"Trabajo agota emocionalmente", # Posición 10 (Pregunta 9) - Typo corregido"Estrés laboral fecta la calidad de atención", # Posición 11 (Pregunta 10) - Typo se mantiene según lista"Factores estresantes", # Posición 12 (Pregunta 11)"Calidad de atención", # Posición 13 (Pregunta 12) - Typo corregido"Factores que limitan la calidad", # Posición 14 (Pregunta 13) - Ahora será categórica simplificada"Capacitación en salud mental", # Posición 15 (Pregunta 14)"Acceso a servicios psicológicos", # Posición 16 (Pregunta 15)"Recibir información personalizada", # Posición 17 (Pregunta 16)"Mayores recursos cognitivos", # Posición 18 (Pregunta 17)"Uso de red social"# Posición 19 (Pregunta 18))# --- Verificar Número de Columnas y Asignar Nombres por Posición ---# Verificamos que el número de columnas cargadas coincida con el número de nombres nuevos.# Si coincide, renombramos por posición. Esto evita el problema de la coincidencia exacta del texto del nombre.nombres_cargados <-names(datos_raw) # Obtener los nombres cargados para referencia/mensajesif(ncol(datos_raw) ==length(nombres_nuevos)) { datos <- datos_raw # Crear una copia para trabajar llamada 'datos'colnames(datos) <- nombres_nuevos # Asignar los nombres nuevos *por posición*message("Las columnas han sido renombradas exitosamente por posición (verificación solo por número de columnas).")} else {# Este error se activará si el número de columnas cargadas no es 19.warning("ADVERTENCIA CRÍTICA: El número de columnas cargadas (", ncol(datos_raw), ") NO coincide con el número de nombres nuevos (", length(nombres_nuevos), ").")warning("No se pudo renombrar por posición. Por favor, verifica tu archivo Excel y la lista 'nombres_nuevos'.")stop("Deteniendo la ejecución.")}# --- Limpieza y Conversión de Variables ---# Utilizamos mutate de dplyr para transformar las columnas renombradas en el dataframe 'datos'.# *** NOTA: USAR COMILLAS INVERSAS `` ` `` PARA NOMBRES CON ESPACIOS O CARACTERES ESPECIALES ***datos <- datos %>%mutate(# --- Limpieza robusta para la variable EDAD ---# Convertir a caracter, extraer solo dígitos al inicio, convertir a numérico, manejar implausibles.Edad =as.character(Edad), # Asegurar que es caracterEdad_extraida =str_extract(Edad, "^[0-9]+"), # Extraer dígitos desde el inicioEdad =suppressWarnings(as.numeric(Edad_extraida)), # Convertir a numérico, suppressWarnings para NA en fallosEdad =if_else(Edad >100| Edad <18, NA_real_, Edad), # Marcar como NA edades implausibles (ej. >100 o <18)Edad_extraida =NULL, # Eliminar columna temporal# --- Limpieza para SEXO ---# Convertir a caracter, reemplazar "Masculino" y vacíos con NA, convertir a factor con niveles específicos.Sexo =as.character(Sexo), # Asegurar que es caracter# Reemplazar "Masculino" (u otras variantes si las hay) y entradas vacías con NASexo =if_else(str_detect(Sexo, fixed("Masculino", ignore_case =TRUE)) | Sexo =="", NA_character_, Sexo),# Opcional: estandarizar otras variantes si existen (ej. "Varon" sin tilde)# Sexo = str_replace(Sexo, fixed("Varon", ignore_case = TRUE), "Varón"),Sexo =factor(Sexo, levels =c("Varón", "Mujer")), # Convertir a factor con los niveles válidos# --- Limpieza y Conversión a Factor Ordenado para Variables de Escala 1-5 ---# Remover el prefijo "letra. " y convertir el texto resultante a un factor ordenado.# Trabajo agota emocionalmente (Q9)`Trabajo agota emocionalmente`=str_replace(as.character(`Trabajo agota emocionalmente`), "^[a-z]\\.\\s*", ""), # Remover "a. ", "b. ", etc.# Definir niveles manualmente para asegurar el orden correcto`Trabajo agota emocionalmente`=factor(`Trabajo agota emocionalmente`,levels =c("1 (nunca)", "2 (raramente)", "3 (a veces)", "4 (frecuentemente)", "5 (siempre)"),ordered =TRUE), # Es una escala ordinal# Estrés laboral fecta la calidad de atención (Q10)`Estrés laboral fecta la calidad de atención`=str_replace(as.character(`Estrés laboral fecta la calidad de atención`), "^[a-z]\\.\\s*", ""), # Remover "a. ", "b. ", etc.# Definir niveles manualmente usando las etiquetas exactas observadas en tus datos de Q10`Estrés laboral fecta la calidad de atención`=factor(`Estrés laboral fecta la calidad de atención`,levels =c("1 (totalmente en desacuerdo)", "2 (en desacuerdo)", "3 (neutral)", "4 (de acuerdo)", "5 (totalmente de acuerdo)"),ordered =TRUE),# Calidad de atención (Q12)`Calidad de atención`=str_replace(as.character(`Calidad de atención`), "^[a-z]\\.\\s*", ""), # Remover "a. ", "b. ", etc.# Definir niveles manualmente usando las etiquetas exactas observadas en tus datos de Q12`Calidad de atención`=factor(`Calidad de atención`,levels =c("1 (muy baja)", "2", "3", "4", "5 (muy alta)"), # Incluye categorías que solo tienen el númeroordered =TRUE),# --- Limpieza y Simplificación para Factores que limitan la calidad (Q13 - Ahora Categórica Única) ---# Se queda con las 5 categorías especificadas y agrupa el resto en "Otros".`Factores que limitan la calidad`=as.character(`Factores que limitan la calidad`), # Asegurar que es caracter para procesar`Factores que limitan la calidad`=str_trim(`Factores que limitan la calidad`), # Limpiar espacios# Usar case_match para asignar las categorías finales`Factores que limitan la calidad`=case_match(`Factores que limitan la calidad`,# Mapear las 5 categorías específicas a sí mismas (usando el texto exacto de tus datos si es posible)"c. Falta de logística"~"c. Falta de logística","b. Falta de especialización"~"b. Falta de especialización","a. Sobrecarga laboral"~"a. Sobrecarga laboral","d. Falta de sistemas de información"~"d. Falta de sistemas de información","e. Salud mental deteriorada del personal"~"e. Salud mental deteriorada del personal",# Mantener NA como NA, y cualquier otro valor como "Otros".NA_character_~NA_character_,.default ="Otros" ),# Convertir la variable simplificada a factor con los niveles definidos.`Factores que limitan la calidad`=factor(`Factores que limitan la calidad`,levels =c("c. Falta de logística","b. Falta de especialización","a. Sobrecarga laboral","d. Falta de sistemas de información","e. Salud mental deteriorada del personal","Otros"), # Asegurar que "Otros" también sea un nivelordered =FALSE# No es una variable inherentemente ordenada ),# --- Conversión de otras variables categóricas/ordinales a tipo 'factor' ---# Utilizar as.character() antes de as.factor() es una buena práctica.# Definir niveles explícitamente para ordinales o si se necesita un orden/subconjunto específico.`Tipo de comisaría`=as.factor(as.character(`Tipo de comisaría`)), # Convertir a factor`Rango policial`=as.factor(as.character(`Rango policial`)), # Convertir a factor# 'Tiempo de servicio' es una variable ordinal: Definir los niveles explícitamente y en el orden correcto.`Tiempo de servicio`=factor(as.character(`Tiempo de servicio`),levels =c("A. Menos de 5 años", "B. De 5 a 10 años", "C. De 10 a 15 años", "D. De 15 a 20 años", "E. Más de 20 años"),ordered =TRUE),`Tipo de casos que atiende frecuentemente`=as.factor(as.character(`Tipo de casos que atiende frecuentemente`)), # Convertir a factor# 'Recursos necesarios' es una variable ordinal: Definir los niveles explícitamente y en el orden correcto.`Recursos necesarios`=factor(as.character(`Recursos necesarios`),levels =c("a. Siempre", "b. A veces", "c. Muy pocas veces", "d. Nunca"),ordered =TRUE),`Capacitación en salud mental`=as.factor(as.character(`Capacitación en salud mental`)), # Variable Sí/No`Acceso a servicios psicológicos`=as.factor(as.character(`Acceso a servicios psicológicos`)), # Variable Sí/No`Recibir información personalizada`=as.factor(as.character(`Recibir información personalizada`)), # Variable Sí/No`Mayores recursos cognitivos`=as.factor(as.character(`Mayores recursos cognitivos`)), # Variable Sí/No`Uso de red social`=as.factor(as.character(`Uso de red social`)) # Convertir a factor# Para Factores estresantes, si no tiene estructura de letra. Categoría, solo convertir a factor.# Si tiene estructura de letra. Categoría, se necesitaría limpieza similar a las escalas 1-5.# Basado en la data, parece ser texto libre o categorías directas.# `Factores estresantes` = as.factor(as.character(`Factores estresantes`)) # Mantener como factor si es categórica simple# La variable 'Ubicación' se mantiene como texto/caracter.# La variable 'Marca Temporal' se mantiene como POSIXct. )# Opcional: Si read_excel cargó columnas vacías al final con nombres como "...19", puedes eliminarlas aquí.# Comprueba la salida de str(datos) o names(datos) si sospechas que hay columnas extra.# Ejemplo: datos <- datos %>% select(-starts_with("..."))message("\nProceso de limpieza y conversión de variables completado.")# Mostrar la estructura final de los datos después de la limpieza para verificar los tiposcat("\n--- Estructura de los datos limpios (str) ---\n")
# Verificar la cantidad de valores perdidos (NA) en cada columna después de la limpiezacat("\n--- Conteo de Valores Perdidos (NA) por Columna después de la limpieza ---\n")
--- Conteo de Valores Perdidos (NA) por Columna después de la limpieza ---
print(colSums(is.na(datos)))
Marca Temporal
0
Ubicación
16
Edad
9
Sexo
3
Tipo de comisaría
0
Rango policial
0
Tiempo de servicio
0
Tipo de casos que atiende frecuentemente
0
Recursos necesarios
0
Trabajo agota emocionalmente
0
Estrés laboral fecta la calidad de atención
0
Factores estresantes
0
Calidad de atención
0
Factores que limitan la calidad
0
Capacitación en salud mental
0
Acceso a servicios psicológicos
0
Recibir información personalizada
0
Mayores recursos cognitivos
0
Uso de red social
0
cat("### Estadísticas Descriptivas para Variables Numéricas (Edad)\n")
### Estadísticas Descriptivas para Variables Numéricas (Edad)
# Asegurarse de que la variable Edad existe y es numéricaif("Edad"%in%names(datos) &&is.numeric(datos$Edad)) {# Usar describe de psych para un resumen conciso de Edad descr_edad <- psych::describe(datos$Edad) %>%as.data.frame() %>% tibble::rownames_to_column("Variable") %>%select(Variable, n, mean, sd, median, min, max, range, se) %>%mutate(Variable ="Edad") # Asegurar que el nombre de la variable es "Edad"# Formatear la tabla con gt gt_table_edad <-gt(descr_edad) %>%fmt_number(columns =vars(mean, sd, se), decimals =2) %>%fmt_number(columns =vars(median, min, max, range), decimals =1) %>%fmt_number(columns =vars(n), decimals =0) %>%cols_label(Variable ="Variable",n ="N Válido",mean ="Media",sd ="Desv. Est.",median ="Mediana",min ="Mínimo",max ="Máximo",range ="Rango",se ="Error Est. Media" ) %>%tab_header(title ="Estadísticas Descriptivas para Edad") %>%tab_footnote(footnote ="N Válido indica el número de observaciones sin valores perdidos (NA) para Edad.")print(gt_table_edad)} else {cat("La variable 'Edad' no existe o no es numérica después de la limpieza. No se pudo generar la tabla de estadísticas.\n")}
cat("### Mediana y Moda para Variables de Escala (Ordinales)\n")
### Mediana y Moda para Variables de Escala (Ordinales)
# Función para calcular la moda# Adaptada para trabajar con factores ordenados y devolver las etiquetas de categoría.get_mode <-function(v) { v <- v[!is.na(v)] # Remove NAsif (length(v) ==0) return(NA_character_) # Devolver NA carácter si no hay datos válidosif (is.factor(v)) {# Para factores, trabajamos con los valores numéricos subyacentes para el conteo v_numeric <-as.numeric(v) tbl <-table(v_numeric) modes_numeric <-as.numeric(names(tbl)[tbl ==max(tbl)])# Mapear los valores numéricos de la moda de vuelta a sus etiquetas originales modes_labels <-levels(v)[modes_numeric]if (length(modes_labels) >1) {# Si hay múltiples modas, devolver las etiquetas ordenadas separadas por comareturn(paste(sort(modes_labels), collapse =", ")) } else {# Si hay una sola moda, devolver su etiquetareturn(modes_labels) } } else {# Si por alguna razón no es un factor (ej. texto libre), calculamos la moda del texto literal.# Esto es menos común para escalas 1-5 después de la limpieza esperada. tbl <-table(v) modes <-names(tbl)[tbl ==max(tbl)]if (length(modes) >1) {return(paste(sort(modes), collapse =", ")) } else {return(as.character(modes)) } }}# Definir los nombres de las variables de escala usando comillas inversas (Nombres actualizados)variables_escala_nombres <-c("Trabajo agota emocionalmente", "Estrés laboral fecta la calidad de atención", "Calidad de atención")# Asegurarse de que las variables de escala existen y son factores ordenados después de la limpieza# Usar `all(variables_escala_nombres %in% names(datos))` para verificar existenciaif(all(variables_escala_nombres %in%names(datos)) &&all(sapply(datos %>%select(all_of(variables_escala_nombres)), is.ordered))) { # Verificar si son factores ordenados# --- Calcular Estadísticas Numéricas (N Válido, Mediana) ---# Usar across para aplicar summarise a las variables de escala numeric_stats_summary <- datos %>%summarise(across(all_of(variables_escala_nombres), ~sum(!is.na(.x)), .names ="N_Valido_{col}"), # N Válidoacross(all_of(variables_escala_nombres), ~median(as.numeric(.x), na.rm =TRUE), .names ="Mediana_{col}") # Mediana )# --- Calcular Estadísticas de Carácter (Moda) ---# Usar across para aplicar get_mode a las variables de escala char_stats_summary <- datos %>%summarise(across(all_of(variables_escala_nombres), ~get_mode(.x), .names ="Moda_{col}") # Moda )# --- Construir la tabla final manualmente para GT ---# Esto evita los problemas de tipo y renombrado con pivot_longer/wider. stats_for_gt_manual <-tibble( Estadística =c("N Válido", "Mediana", "Moda"),# Referenciar los valores calculados en numeric_stats_summary y char_stats_summary# Usar los nombres de columna exactos de esas summaries (combinación de Estadística_NombreVariable)# Acceder a las columnas usando el operador $ y los nombres completos con comillas inversas si es necesario.# Columna para 'Trabajo agota emocionalmente'`Trabajo agota emocionalmente`=c(as.character(numeric_stats_summary$`N_Valido_Trabajo agota emocionalmente`), # Convertir a carácteras.character(numeric_stats_summary$`Mediana_Trabajo agota emocionalmente`), # Convertir a carácter char_stats_summary$`Moda_Trabajo agota emocionalmente`# Ya es carácter ),# Columna para 'Estrés laboral fecta la calidad de atención'`Estrés laboral fecta la calidad de atención`=c(as.character(numeric_stats_summary$`N_Valido_Estrés laboral fecta la calidad de atención`),as.character(numeric_stats_summary$`Mediana_Estrés laboral fecta la calidad de atención`), char_stats_summary$`Moda_Estrés laboral fecta la calidad de atención` ),# Columna para 'Calidad de atención'`Calidad de atención`=c(as.character(numeric_stats_summary$`N_Valido_Calidad de atención`),as.character(numeric_stats_summary$`Mediana_Calidad de atención`), char_stats_summary$`Moda_Calidad de atención` ) )# Esta tabla stats_for_gt_manual ya tiene la estructura final deseada.# --- Formatear la tabla con gt ---# Usamos la tabla construida manualmente. gt_table_escalas <-gt(stats_for_gt_manual) %>%# Formatear valores numéricos (N Válido, Mediana)# Identificamos las filas por el texto de la columna Estadística# Usar los nombres de columna renombrados (que coinciden con los nombres en el tibble manual)fmt_number(columns =c(`Trabajo agota emocionalmente`, `Estrés laboral fecta la calidad de atención`, `Calidad de atención`),rows = Estadística =="N Válido", # Solo para la fila "N Válido"decimals =0) %>%# N Válidos sin decimales# Formatear Mediana con un decimalfmt_number(columns =c(`Trabajo agota emocionalmente`, `Estrés laboral fecta la calidad de atención`, `Calidad de atención`),rows = Estadística =="Mediana", # Solo para la fila "Mediana"decimals =1) %>%# Asegurarse de que la columna Estadística sea visible y legiblecols_label(Estadística ="Estadística") %>%# Los nombres de las columnas de variables ya están bien en el tibble manualtab_header(title ="Mediana y Moda para Variables de Escala") %>%tab_footnote(footnote ="N Válido indica el número de observaciones sin valores perdidos (NA). La Mediana se calcula sobre el valor numérico (1-5) de la escala. La Moda muestra el valor(es) más frecuente(s) como etiqueta de categoría.")print(gt_table_escalas)} else {cat("Las variables de escala no existen o no son factores ordenados después de la limpieza. No se pudieron calcular las estadísticas para escalas.\n")cat("Verifique la salida de str(datos) después de la limpieza.\n")}
# --- Tablas de Frecuencia (Todas las variables categóricas y ordinales) ---# Función para generar una tabla de frecuencia con conteos y porcentajes, formateada con gt# Toma el dataframe, la variable a analizar (usando curly-curly {{}} para tidy evaluation)# y un nombre descriptivo para la tabla. Espera que la variable sea un factor o pueda ser convertida a factor.# *** NOTA: {{variable}} manejará los nombres con espacios si la variable se pasa correctamente ***generar_frecuencia_gt <-function(data, variable, nombre_variable) {cat(paste0("### Tabla de Frecuencia para: ", nombre_variable, "\n")) # Usar Markdown para subtítulo# Crear la tabla de frecuencia usando dplyr::count# Usar as.factor() para asegurar que incluso si una variable numérica discreta se pasa,# se trate como factor para contar categorías. Filter NAs.# Si la variable ya es un factor (como las escalas limpias ahora), count la maneja directamente. freq_df <- data %>%filter(!is.na({{variable}})) %>%# Filtrar NAs antes de contarcount({{variable}}, sort =TRUE, name ="Frecuencia") %>%# Contar los valores (si es factor, usa los niveles)rename(Categoria =names(.)[1] ) %>%# Renombrar la primera columna (el nombre de la variable) a Categoriamutate(Proporción = Frecuencia /sum(Frecuencia)) %>%# Calcular proporción sobre el total de válidosmutate(Porcentaje = Proporción *100) # Convertir a porcentaje# Formatear la tabla usando gt gt_table_freq <-gt(freq_df) %>%# Formatear númerosfmt_number(columns =vars(Proporción), decimals =3) %>%fmt_number(columns =vars(Porcentaje), decimals =1) %>%fmt_number(columns =vars(Frecuencia), decimals =0) %>%# Añadir encabezados amigablescols_label(Categoria ="Categoría",Frecuencia ="Frecuencia", Proporción ="Proporción",Porcentaje ="Porcentaje (%)" ) %>%# Añadir un título a la tablatab_header(title =paste("Distribución de", nombre_variable)) %>%# Opcional: Nota al pie sobre NAs if relevantetab_footnote(footnote ="Los valores perdidos (NA) no se incluyen en esta tabla.")# Mostrar la tabla gtprint(gt_table_freq)}# Aplicar la función de generación de tablas a cada variable categórica o ordinal# Usar las variables limpias que son factores.# *** USAR COMILLAS INVERSAS `` ` `` PARA NOMBRES CON ESPACIOS O CARACTERES ESPECIALES ***generar_frecuencia_gt(datos, Sexo, "Sexo")
# Aplicar a las variables de escala 1-5 (usando las columnas factor limpias con nombres actualizados)generar_frecuencia_gt(datos, `Trabajo agota emocionalmente`, "Agotamiento Emocional (Escala 1-5)")
# Aplicar a la variable Factores que limitan la calidad (ahora categórica simple)generar_frecuencia_gt(datos, `Factores que limitan la calidad`, "Factores que Limitan la Calidad de Atención")
# --- El análisis univariado específico para Factores_Limitan_Calidad (Q13 - Multi-Respuesta) ya NO es necesario ---# Ya que la variable fue simplificada a una sola respuesta categórica en la limpieza.# El código anterior para multi-respuesta se elimina o comenta.
# Las opciones fig-align, fig-width, fig-height ya están definidas en el setup global.# Si se necesitan valores diferentes para un gráfico específico, se pueden añadir aquí.# --- Gráficos Univariados utilizando ggplot2 ---# Estos gráficos ayudan a visualizar la distribución de cada variable.# *** NOTA: USAR COMILLAS INVERSAS `` ` `` PARA NOMBRES CON ESPACIOS O CARACTERES ESPECIALES EN AES() ***# Histograma para la variable numérica 'Edad'. Filtramos NAs para el gráfico.cat("### Histograma: Distribución de Edades de los Policías\n")
### Histograma: Distribución de Edades de los Policías
ggplot(datos %>%filter(!is.na(Edad)), aes(x = Edad)) +geom_histogram(binwidth =5, fill ="skyblue", color ="black", alpha =0.8) +# binwidth ajusta el ancho de las barras de edadlabs(title ="Distribución de Edades de los Policías", x ="Edad", y ="Frecuencia") +theme_minimal() # Tema gráfico limpio
# Diagrama de barras para la variable categórica 'Sexo'.cat("### Diagrama de Barras: Distribución por Sexo\n")
### Diagrama de Barras: Distribución por Sexo
ggplot(datos %>%filter(!is.na(Sexo)), aes(x = Sexo)) +geom_bar(fill ="lightgreen", color ="black", alpha =0.8) +labs(title ="Distribución por Sexo", x ="Sexo", y ="Frecuencia") +theme_minimal()
# Diagrama de barras para la variable categórica 'Tipo de comisaría'.cat("### Diagrama de Barras: Distribución por Tipo de Comisaría\n")
### Diagrama de Barras: Distribución por Tipo de Comisaría
ggplot(datos %>%filter(!is.na(`Tipo de comisaría`)), aes(x =`Tipo de comisaría`)) +geom_bar(fill ="orange", color ="black", alpha =0.8) +labs(title ="Distribución por Tipo de Comisaría", x ="Tipo de Comisaría", y ="Frecuencia") +theme_minimal()
# Diagrama de barras para la variable categórica 'Rango policial'.cat("### Diagrama de Barras: Distribución por Rango Policial\n")
### Diagrama de Barras: Distribución por Rango Policial
ggplot(datos %>%filter(!is.na(`Rango policial`)), aes(x =`Rango policial`)) +geom_bar(fill ="brown", color ="black", alpha =0.8) +labs(title ="Distribución por Rango Policial", x ="Rango Policial", y ="Frecuencia") +theme_minimal()
# Diagrama de barras para la variable ordinal 'Tiempo de servicio'.cat("### Diagrama de Barras: Distribución por Tiempo de Servicio en la PNP\n")
### Diagrama de Barras: Distribución por Tiempo de Servicio en la PNP
ggplot(datos %>%filter(!is.na(`Tiempo de servicio`)), aes(x =`Tiempo de servicio`)) +geom_bar(fill ="salmon", color ="black", alpha =0.8) +labs(title ="Distribución por Tiempo de Servicio en la PNP", x ="Tiempo de Servicio", y ="Frecuencia") +theme_minimal() +theme(axis.text.x =element_text(angle =45, hjust =1)) # Rotar etiquetas si son largas
# Diagrama de barras para la variable categórica 'Tipo de casos que atiende frecuentemente'.cat("### Diagrama de Barras: Distribución por Tipo de Casos Frecuentes\n")
### Diagrama de Barras: Distribución por Tipo de Casos Frecuentes
ggplot(datos %>%filter(!is.na(`Tipo de casos que atiende frecuentemente`)), aes(x =`Tipo de casos que atiende frecuentemente`)) +geom_bar(fill ="cyan", color ="black", alpha =0.8) +labs(title ="Distribución por Tipo de Casos Frecuentes", x ="Tipo de Casos Frecuentes", y ="Frecuencia") +theme_minimal() +theme(axis.text.x =element_text(angle =45, hjust =1)) # Rotar etiquetas
# Diagrama de barras para la variable ordinal 'Recursos necesarios'.cat("### Diagrama de Barras: Distribución sobre Recursos Necesarios\n")
### Diagrama de Barras: Distribución sobre Recursos Necesarios
ggplot(datos %>%filter(!is.na(`Recursos necesarios`)), aes(x =`Recursos necesarios`)) +geom_bar(fill ="violet", color ="black", alpha =0.8) +labs(title ="Distribución sobre Recursos Necesarios", x ="¿Considera que tiene los recursos necesarios?", y ="Frecuencia") +theme_minimal() +theme(axis.text.x =element_text(angle =45, hjust =1)) # Rotar etiquetas
# Diagrama de barras para las variables de escala (tratadas como factores ordenados).cat("### Diagrama de Barras: Frecuencia de Puntuaciones en Agotamiento Emocional\n")
### Diagrama de Barras: Frecuencia de Puntuaciones en Agotamiento Emocional
ggplot(datos %>%filter(!is.na(`Trabajo agota emocionalmente`)), aes(x =`Trabajo agota emocionalmente`)) +geom_bar(fill ="gold", color ="black", alpha =0.8) +labs(title ="Frecuencia de Puntuaciones en Agotamiento Emocional", x ="Agotamiento Emocional (Escala 1-5)", y ="Frecuencia") +theme_minimal()
cat("### Diagrama de Barras: Frecuencia de Puntuaciones en Estrés Afecta Atención\n")
### Diagrama de Barras: Frecuencia de Puntuaciones en Estrés Afecta Atención
ggplot(datos %>%filter(!is.na(`Estrés laboral fecta la calidad de atención`)), aes(x =`Estrés laboral fecta la calidad de atención`)) +geom_bar(fill ="coral", color ="black", alpha =0.8) +labs(title ="Frecuencia de Puntuaciones en Estrés Afecta Atención", x ="Estrés Afecta Atención (Escala 1-5)", y ="Frecuencia") +theme_minimal()
cat("### Diagrama de Barras: Frecuencia de Puntuaciones en Calidad de Atención\n")
### Diagrama de Barras: Frecuencia de Puntuaciones en Calidad de Atención
ggplot(datos %>%filter(!is.na(`Calidad de atención`)), aes(x =`Calidad de atención`)) +geom_bar(fill ="purple", color ="black", alpha =0.8) +labs(title ="Frecuencia de Puntuaciones en Calidad de Atención", x ="Calidad de Atención (Escala 1-5)", y ="Frecuencia") +theme_minimal()
# Diagrama de barras para la variable Factores que limitan la calidad (ahora categórica simple)cat("### Diagrama de Barras: Factores que Limitan la Calidad de Atención\n")
### Diagrama de Barras: Factores que Limitan la Calidad de Atención
ggplot(datos %>%filter(!is.na(`Factores que limitan la calidad`)), aes(x =`Factores que limitan la calidad`)) +geom_bar(fill ="darkred", color ="black", alpha =0.8) +labs(title ="Factores que Limitan la Calidad de Atención", x ="Factor Limitante", y ="Frecuencia") +theme_minimal() +theme(axis.text.x =element_text(angle =45, hjust =1))
# Diagrama de barras para las variables Sí/Nocat("### Diagrama de Barras: Distribución de Capacitación sobre Salud Mental\n")
### Diagrama de Barras: Distribución de Capacitación sobre Salud Mental
ggplot(datos %>%filter(!is.na(`Capacitación en salud mental`)), aes(x =`Capacitación en salud mental`)) +geom_bar(fill ="lightyellow", color ="black", alpha =0.8) +labs(title ="Distribución de Capacitación sobre Salud Mental", x ="¿Ha recibido formación o capacitación sobre salud mental?", y ="Frecuencia") +theme_minimal()
cat("### Diagrama de Barras: Distribución de Acceso a Servicios Psicológicos\n")
### Diagrama de Barras: Distribución de Acceso a Servicios Psicológicos
ggplot(datos %>%filter(!is.na(`Acceso a servicios psicológicos`)), aes(x =`Acceso a servicios psicológicos`)) +geom_bar(fill ="lightblue", color ="black", alpha =0.8) +labs(title ="Distribución de Acceso a Servicios Psicológicos", x ="¿Cuenta con acceso a servicios psicológicos?", y ="Frecuencia") +theme_minimal()
cat("### Diagrama de Barras: Distribución sobre Recibir Información Personalizada\n")
### Diagrama de Barras: Distribución sobre Recibir Información Personalizada
ggplot(datos %>%filter(!is.na(`Recibir información personalizada`)), aes(x =`Recibir información personalizada`)) +geom_bar(fill ="lightcoral", color ="black", alpha =0.8) +labs(title ="Distribución sobre Recibir Información Personalizada", x ="¿Le gustaría recibir información personalizada?", y ="Frecuencia") +theme_minimal()
cat("### Diagrama de Barras: Distribución sobre Mayores Recursos Cognitivos\n")
### Diagrama de Barras: Distribución sobre Mayores Recursos Cognitivos
ggplot(datos %>%filter(!is.na(`Mayores recursos cognitivos`)), aes(x =`Mayores recursos cognitivos`)) +geom_bar(fill ="lightgreen", color ="black", alpha =0.8) +labs(title ="Distribución sobre Mayores Recursos Cognitivos", x ="¿Le gustaría contar con mayores recursos cognitivos?", y ="Frecuencia") +theme_minimal()
# Diagrama de barras para la variable 'Uso de red social'.cat("### Diagrama de Barras: Red Social Más Usada\n")
### Diagrama de Barras: Red Social Más Usada
ggplot(datos %>%filter(!is.na(`Uso de red social`)), aes(x =`Uso de red social`)) +geom_bar(fill ="skyblue", color ="black", alpha =0.8) +labs(title ="Red Social Más Usada", x ="Red Social", y ="Frecuencia") +theme_minimal() +theme(axis.text.x =element_text(angle =45, hjust =1)) # Rotar etiquetas
# Diagrama de barras para la variable 'Factores estresantes'.cat("### Diagrama de Barras: Factores Más Estresantes Reportados\n")
### Diagrama de Barras: Factores Más Estresantes Reportados
ggplot(datos %>%filter(!is.na(`Factores estresantes`)), aes(x =`Factores estresantes`)) +geom_bar(fill ="grey", color ="black", alpha =0.8) +labs(title ="Factores Más Estresantes Reportados", x ="Factor Estresante", y ="Frecuencia") +theme_minimal() +theme(axis.text.x =element_text(angle =45, hjust =1)) # Rotar etiquetas
# La variable 'Ubicación' es texto libre, no se grafica univariadamente a este nivel con un histograma o barras.# La variable 'Marca Temporal' es fecha/hora, los descriptivos relevantes serían min/max/rango (ya en summary) o un histograma de la hora del día, lo cual es menos relevante para análisis de alto nivel.# El gráfico para la variable de Múltiple Respuesta (Factores_Limitan_Calidad) ya NO es necesario# Ya que la variable fue simplificada a una sola respuesta categórica en la limpieza.
cat("\n--- Relación entre variables Categóricas ---\n")
--- Relación entre variables Categóricas ---
# *** NOTA: USAR COMILLAS INVERSAS `` ` `` PARA NOMBRES CON ESPACIOS O CARACTERES ESPECIALES ***# Tabla Cruzada: Sexo vs Capacitación en salud mental. Muestra el conteo de respuestas para cada combinación.cat("### Tabla Cruzada: Distribución de Capacitación en salud mental por Sexo\n")
### Tabla Cruzada: Distribución de Capacitación en salud mental por Sexo
tabla_sexo_formacion <-table(datos$Sexo, datos$`Capacitación en salud mental`)print(tabla_sexo_formacion)
a. Sí b. No
Varón 88 139
Mujer 41 63
# Tabla Cruzada con Proporciones por Fila: Muestra la distribución porcentual de la formación DENTRO de cada categoría de Sexo.cat("### Tabla Cruzada (Proporciones por Fila): Distribución de Capacitación en salud mental DENTRO de cada Sexo\n")
### Tabla Cruzada (Proporciones por Fila): Distribución de Capacitación en salud mental DENTRO de cada Sexo
tabla_sexo_formacion_prop_fila <-prop.table(tabla_sexo_formacion, 1) *100# El '1' indica calcular proporciones sobre el total de cada fila (Sexo)print(round(tabla_sexo_formacion_prop_fila, 1)) # Redondear a 1 decimal
a. Sí b. No
Varón 38.8 61.2
Mujer 39.4 60.6
# Tabla Cruzada: Tipo de comisaría vs Acceso a servicios psicológicos.cat("### Tabla Cruzada: Distribución de Acceso a servicios psicológicos por Tipo de comisaría\n")
### Tabla Cruzada: Distribución de Acceso a servicios psicológicos por Tipo de comisaría
tabla_comisaria_psico <-table(datos$`Tipo de comisaría`, datos$`Acceso a servicios psicológicos`)print(tabla_comisaria_psico)
a. Sí b. No
A. Comisaría básica 130 173
B. Comisaría de familia 17 14
# Gráfico de barras agrupado: Frecuencia de Capacitación en salud mental, separada por Sexo.cat("### Gráfico: Capacitación en salud mental por Sexo\n")
### Gráfico: Capacitación en salud mental por Sexo
ggplot(datos %>%filter(!is.na(Sexo), !is.na(`Capacitación en salud mental`)),aes(x = Sexo, fill =`Capacitación en salud mental`)) +geom_bar(position ="dodge", color ="black", alpha =0.8) +# position = "dodge" para barras agrupadas lado a ladolabs(title ="Distribución de Capacitación en salud mental por Sexo", x ="Sexo", y ="Frecuencia", fill ="¿Recibió Formación SM?") +theme_minimal()
# Gráfico de barras apilado: Proporción de Acceso a servicios psicológicos dentro de cada Rango policial.cat("### Gráfico: Proporción de Acceso a servicios psicológicos por Rango policial\n")
### Gráfico: Proporción de Acceso a servicios psicológicos por Rango policial
ggplot(datos %>%filter(!is.na(`Rango policial`), !is.na(`Acceso a servicios psicológicos`)),aes(x = forcats::fct_drop(`Rango policial`), fill =`Acceso a servicios psicológicos`)) +geom_bar(position ="fill", color ="black", alpha =0.8) +# position="fill" muestra proporciones relativas (suma 1 en cada barra)labs(title ="Proporción de Acceso a servicios psicológicos por Rango policial", x ="Rango Policial", y ="Proporción", fill ="¿Tiene Acceso SP?") +theme_minimal() +theme(axis.text.x =element_text(angle =45, hjust =1))
# Tabla Cruzada: Factores que limitan la calidad vs Rango policialcat("### Tabla Cruzada: Distribución de Factores que limitan la calidad por Rango policial\n")
### Tabla Cruzada: Distribución de Factores que limitan la calidad por Rango policial
tabla_limitantes_rango <-table(datos$`Factores que limitan la calidad`, datos$`Rango policial`)print(tabla_limitantes_rango)
A. Suboficial B. Oficial
c. Falta de logística 195 1
b. Falta de especialización 42 0
a. Sobrecarga laboral 36 2
d. Falta de sistemas de información 29 0
e. Salud mental deteriorada del personal 16 2
Otros 11 0
# Gráfico de barras apilado: Proporción de Factores que limitan la calidad dentro de cada Rango policialcat("### Gráfico: Proporción de Factores que limitan la calidad por Rango policial\n")
### Gráfico: Proporción de Factores que limitan la calidad por Rango policial
ggplot(datos %>%filter(!is.na(`Factores que limitan la calidad`), !is.na(`Rango policial`)),aes(x = forcats::fct_drop(`Rango policial`), fill =`Factores que limitan la calidad`)) +geom_bar(position ="fill", color ="black", alpha =0.8) +labs(title ="Proporción de Factores que limitan la calidad por Rango policial", x ="Rango Policial", y ="Proporción", fill ="Factor Limitante") +theme_minimal() +theme(axis.text.x =element_text(angle =45, hjust =1))
cat("\n--- Relación entre Variables Numéricas (Edad) y Variables Categóricas ---\n")
--- Relación entre Variables Numéricas (Edad) y Variables Categóricas ---
# *** NOTA: USAR COMILLAS INVERSAS `` ` `` PARA NOMBRES CON ESPACIOS O CARACTERES ESPECIALES ***# Estadísticas Descriptivas (Media, Desv. Est., Mediana) de la variable numérica (Edad) agrupada por una categórica (Sexo).cat("### Estadísticas Descriptivas de Edad agrupada por Sexo\n")
### Estadísticas Descriptivas de Edad agrupada por Sexo
stats_edad_por_sexo <- datos %>%filter(!is.na(Edad), !is.na(Sexo)) %>%# Filtrar NAs para el cálculogroup_by(Sexo) %>%summarise(N_Valido =n(), # Número de observaciones válidas en cada grupoMedia_Edad =mean(Edad), # na.rm = TRUE es el comportamiento por defecto en summarise de dplyr con columnas numéricas/enterasSD_Edad =sd(Edad),Mediana_Edad =median(Edad),.groups ='drop'# Desagrupar después de resumir )print(stats_edad_por_sexo)
# A tibble: 2 × 5
`Rango policial` N_Valido Media_Edad SD_Edad Mediana_Edad
<fct> <int> <dbl> <dbl> <dbl>
1 A. Suboficial 320 32.8 7.03 31
2 B. Oficial 5 36.8 8.93 34
# Diagrama de violín: Visualizar la distribución de Edad por Sexo (muestra la densidad de puntos).cat("### Diagrama de Violín: Distribución de Edad por Sexo\n")
### Diagrama de Violín: Distribución de Edad por Sexo
ggplot(datos %>%filter(!is.na(Edad), !is.na(Sexo)),aes(x = Sexo, y = Edad, fill = Sexo)) +geom_violin(trim =TRUE, alpha =0.7) +# trim=TRUE corta la densidad en los extremosgeom_boxplot(width =0.1, color ="black", alpha =0.8) +# Añadir un boxplot dentro del violínlabs(title ="Distribución de Edad por Sexo", x ="Sexo", y ="Edad") +theme_minimal() +guides(fill =FALSE)
# Diagrama de violín: Visualizar la distribución de Edad por Rango policial.cat("### Diagrama de Violín: Distribución de Edad por Rango policial\n")
### Diagrama de Violín: Distribución de Edad por Rango policial
ggplot(datos %>%filter(!is.na(Edad), !is.na(`Rango policial`)),aes(x = forcats::fct_drop(`Rango policial`), y = Edad, fill =`Rango policial`)) +geom_violin(trim =TRUE, alpha =0.7) +geom_boxplot(width =0.1, color ="black", alpha =0.8) +labs(title ="Distribución de Edad por Rango policial", x ="Rango Policial", y ="Edad") +theme_minimal() +theme(axis.text.x =element_text(angle =45, hjust =1)) +guides(fill =FALSE)
cat("\n--- Relación entre Variables Numéricas (Edad) ---\n")
--- Relación entre Variables Numéricas (Edad) ---
# *** NOTA: USAR COMILLAS INVERSAS `` ` `` PARA NOMBRES CON ESPACIOS O CARACTERES ESPECIALES ***# Dado que Edad es nuestra única variable continua principal, la correlación bivariada# entre dos variables puramente numéricas no es aplicable con solo una.# Podemos, sin embargo, visualizar Edad frente a variables de escala si se considera útil,# aunque la interpretación de la correlación de Pearson con ordinales debe ser cautelosa.# Ejemplo (Opcional y con precaución): Dispersión de Edad vs Trabajo agota emocionalmente# La correlación de Pearson no es ideal para ordinales, pero la visualización puede ser exploratoria.cat("### Gráfico de Dispersión Exploratorio: Edad vs Trabajo agota emocionalmente (con precaución)\n")
### Gráfico de Dispersión Exploratorio: Edad vs Trabajo agota emocionalmente (con precaución)
# Usar la variable de escala factor para los valores del eje Y en la visualizaciónggplot(datos %>%filter(!is.na(Edad), !is.na(`Trabajo agota emocionalmente`)),aes(x = Edad, y =`Trabajo agota emocionalmente`)) +# Usar la variable factor directamente en el eje Ygeom_point(alpha =0.6, size =2, position =position_jitter(width =0.5, height =0.1)) +# Jitter para separar puntos superpuestosgeom_smooth(method ="lm", se =FALSE, color ="blue") +# Añadir una línea de tendencia lineal sin intervalo de confianzalabs(title ="Edad vs Agotamiento Emocional Percibido (Exploratorio)",x ="Edad",y ="Escala Agotamiento (1-5)") +# La etiqueta del eje y debe reflejar la escalatheme_minimal()
# Se pueden añadir análisis similares para Edad vs Estrés laboral fecta la calidad de atención o Edad vs Calidad de atención.
cat("\n--- Relación entre Variables de Escala (Ordinales) ---\n")
--- Relación entre Variables de Escala (Ordinales) ---
# *** NOTA: USAR COMILLAS INVERSAS `` ` `` PARA NOMBRES CON ESPACIOS O CARACTERES ESPECIALES ***# Tabla Cruzada: Trabajo agota emocionalmente vs Estrés laboral fecta la calidad de atencióncat("### Tabla Cruzada: Trabajo agota emocionalmente vs Estrés laboral fecta la calidad de atención\n")
### Tabla Cruzada: Trabajo agota emocionalmente vs Estrés laboral fecta la calidad de atención
# Usar las variables factor directamente para la tablatabla_agotamiento_estres <-table(datos$`Trabajo agota emocionalmente`, datos$`Estrés laboral fecta la calidad de atención`)print(tabla_agotamiento_estres)
# Tabla Cruzada con Proporciones por Fila (Porcentaje de Estrés DENTRO de cada nivel de Agotamiento)cat("### Tabla Cruzada (Proporciones por Fila): Estrés laboral fecta la calidad de atención DENTRO de cada nivel de Trabajo agota emocionalmente\n")
### Tabla Cruzada (Proporciones por Fila): Estrés laboral fecta la calidad de atención DENTRO de cada nivel de Trabajo agota emocionalmente
tabla_agotamiento_estres_prop_fila <-prop.table(tabla_agotamiento_estres, 1) *100# Multiplicar por 100 para porcentajesprint(round(tabla_agotamiento_estres_prop_fila, 1)) # Redondear a 1 decimal
# Tabla Cruzada: Trabajo agota emocionalmente vs Calidad de atencióncat("### Tabla Cruzada: Trabajo agota emocionalmente vs Calidad de atención\n")
### Tabla Cruzada: Trabajo agota emocionalmente vs Calidad de atención
# Usar las variables factor directamente para la tablatabla_agotamiento_calidad <-table(datos$`Trabajo agota emocionalmente`, datos$`Calidad de atención`)print(tabla_agotamiento_calidad)
# Tabla Cruzada: Estrés laboral fecta la calidad de atención vs Calidad de atencióncat("### Tabla Cruzada: Estrés laboral fecta la calidad de atención vs Calidad de atención\n")
### Tabla Cruzada: Estrés laboral fecta la calidad de atención vs Calidad de atención
tabla_estres_calidad <-table(datos$`Estrés laboral fecta la calidad de atención`, datos$`Calidad de atención`)print(tabla_estres_calidad)
# Gráfico de barras apilado: Proporción de Estrés laboral fecta la calidad de atención dentro de cada nivel de Trabajo agota emocionalmentecat("### Gráfico: Proporción de Estrés laboral fecta la calidad de atención dentro de cada nivel de Trabajo agota emocionalmente\n")
### Gráfico: Proporción de Estrés laboral fecta la calidad de atención dentro de cada nivel de Trabajo agota emocionalmente
ggplot(datos %>%filter(!is.na(`Trabajo agota emocionalmente`), !is.na(`Estrés laboral fecta la calidad de atención`)),aes(x =`Trabajo agota emocionalmente`, fill =`Estrés laboral fecta la calidad de atención`)) +# Usar las variables factorgeom_bar(position ="fill", color ="black", alpha =0.8) +# position="fill" muestra proporciones relativas (suma 1 en cada barra)labs(title ="Proporción de Estrés Afecta Atención por Nivel de Agotamiento Emocional",x ="Agotamiento Emocional (Escala 1-5)",y ="Proporción",fill ="Estrés Afecta Atención (Escala 1-5)") +theme_minimal()
# Gráfico de barras apilado: Proporción de Calidad de atención dentro de cada nivel de Trabajo agota emocionalmentecat("### Gráfico: Proporción de Calidad de atención dentro de cada nivel de Trabajo agota emocionalmente\n")
### Gráfico: Proporción de Calidad de atención dentro de cada nivel de Trabajo agota emocionalmente
ggplot(datos %>%filter(!is.na(`Trabajo agota emocionalmente`), !is.na(`Calidad de atención`)),aes(x =`Trabajo agota emocionalmente`, fill =`Calidad de atención`)) +# Usar las variables factorgeom_bar(position ="fill", color ="black", alpha =0.8) +# position="fill" muestra proporciones relativas (suma 1 en cada barra)labs(title ="Proporción de Calidad de Atención por Nivel de Agotamiento Emocional",x ="Agotamiento Emocional (Escala 1-5)",y ="Proporción",fill ="Calidad de Atención (Escala 1-5)") +theme_minimal()
# Seleccionar solo la variable de Edad para la correlación.# Si tuvieras otras variables continuas (ej. tiempo en el puesto en días/años numéricos exactos), las añadirías aquí.variables_numericas_continuas <- datos %>%select(Edad) %>%na.omit() # Eliminar filas con NA en Edad# Verificar si quedan al menos dos variables y suficientes filas para calcular la correlación# (Se necesitan al menos 2 variables para una matriz de correlación, y al menos 2 filas válidas).if(ncol(variables_numericas_continuas) >=2&&nrow(variables_numericas_continuas) >1) {cat("### Matriz de Correlación de Pearson para Variables Numéricas Continuas\n") cor_matrix_extended <-cor(variables_numericas_continuas)print(round(cor_matrix_extended, 2))# Opcional: Matriz con p-valores si se desea (aunque es inferencial)# cat("### Matriz de Correlación con p-valores (Psych package - Exploratorio)\n")# print(psych::corr.test(variables_numericas_continuas, use = "pairwise", adjust="none")$r)} else {cat("No hay suficientes variables numéricas continuas (se necesitan al menos 2) o datos completos para calcular la matriz de correlación de Pearson en este momento.\n")# Opcionalmente, si quieres tratar las escalas 1-5 como pseudo-intervalo para una correlación exploratoria,# puedes incluirlas aquí con mucha precaución en la interpretación.# Para hacer esto, necesitaríamos convertir temporalmente las variables de escala a numérico (1-5).# Si decides hacer esto, descomenta el siguiente bloque y usa la función as.numeric()# *** NOTA: USAR COMILLAS INVERSAS `` ` `` PARA NOMBRES CON ESPACIOS O CARACTERES ESPECIALES ***# cat("### Matriz de Correlación de Pearson (Exploratoria, incluyendo Escalas 1-5 como pseudo-intervalo)\n")# vars_para_cor_exploratoria <- datos %>%# select(Edad, `Trabajo agota emocionalmente`, `Estrés laboral fecta la calidad de atención`, `Calidad de atención`) %>%# mutate(across(c(`Trabajo agota emocionalmente`, `Estrés laboral fecta la calidad de atención`, `Calidad de atención`), as.numeric)) %>% # Convertir a numérico 1-5# na.omit() # Eliminar NAs después de conversión# if(nrow(vars_para_cor_exploratoria) > 1 && ncol(vars_para_cor_exploratoria) >= 2) {# cor_matrix_exploratoria <- cor(vars_para_cor_exploratoria)# print(round(cor_matrix_exploratoria, 2))# } else {# cat("No hay suficientes datos completos para la matriz de correlación exploratoria incluyendo escalas.\n")# }}
No hay suficientes variables numéricas continuas (se necesitan al menos 2) o datos completos para calcular la matriz de correlación de Pearson en este momento.
cat("\n--- Estadísticas Descriptivas (Mediana, Moda) de Variables de Escala agrupadas por Múltiples Factores ---\n")
--- Estadísticas Descriptivas (Mediana, Moda) de Variables de Escala agrupadas por Múltiples Factores ---
# *** NOTA: USAR COMILLAS INVERSAS `` ` `` PARA NOMBRES CON ESPACIOS O CARACTERES ESPECIALES ***# Reutilizar la función get_mode definida previamente (asegúrate que está en un chunk anterior o global)# get_mode <- function(v) { ... }# Calcular la Mediana (sobre valores numéricos subyacentes) y Moda (usando el factor etiquetado)# de Trabajo agota emocionalmente, agrupado por Sexo y Rango policial.cat("### Mediana y Moda de Trabajo agota emocionalmente agrupado por Sexo y Rango policial\n")
### Mediana y Moda de Trabajo agota emocionalmente agrupado por Sexo y Rango policial
stats_agotamiento_sexo_rango <- datos %>%filter(!is.na(`Trabajo agota emocionalmente`), !is.na(Sexo), !is.na(`Rango policial`)) %>%# Filtrar NAs relevantesgroup_by(Sexo, `Rango policial`) %>%# Agrupar por la combinación de ambas variables categóricassummarise(N_Valido =n(), # Número de observaciones válidas en cada grupo para este grupo combinadoMediana_Agotamiento =median(as.numeric(`Trabajo agota emocionalmente`), na.rm =TRUE), # Mediana sobre valores numéricos (1-5)Moda_Agotamiento =get_mode(`Trabajo agota emocionalmente`), # Moda sobre el factor etiquetado.groups ='drop'# Desagrupar después de resumir ) %>%na.omit() # Eliminar combinaciones de grupos que resulten en NAs (ej. si una combinación no existe en los datos válidos)print(stats_agotamiento_sexo_rango)
# A tibble: 4 × 5
Sexo `Rango policial` N_Valido Mediana_Agotamiento Moda_Agotamiento
<fct> <fct> <int> <dbl> <chr>
1 Varón A. Suboficial 224 2 1 (nunca)
2 Varón B. Oficial 3 4 2 (raramente), 4 (frecuen…
3 Mujer A. Suboficial 102 2 2 (raramente)
4 Mujer B. Oficial 2 2 1 (nunca), 3 (a veces)
# Calcular la Mediana y Moda de Calidad de atención, agrupado por Tipo de comisaría y Capacitación en salud mental.cat("### Mediana y Moda de Calidad de atención agrupado por Tipo de comisaría y Capacitación en salud mental\n")
### Mediana y Moda de Calidad de atención agrupado por Tipo de comisaría y Capacitación en salud mental
stats_calidad_comisaria_formacion <- datos %>%filter(!is.na(`Calidad de atención`), !is.na(`Tipo de comisaría`), !is.na(`Capacitación en salud mental`)) %>%group_by(`Tipo de comisaría`, `Capacitación en salud mental`) %>%summarise(N_Valido =n(),Mediana_Calidad =median(as.numeric(`Calidad de atención`), na.rm =TRUE),Moda_Calidad =get_mode(`Calidad de atención`),.groups ='drop' ) %>%na.omit()print(stats_calidad_comisaria_formacion)
# A tibble: 4 × 5
`Tipo de comisaría` Capacitación en salud menta…¹ N_Valido Mediana_Calidad
<fct> <fct> <int> <dbl>
1 A. Comisaría básica a. Sí 109 5
2 A. Comisaría básica b. No 194 4
3 B. Comisaría de familia a. Sí 22 3
4 B. Comisaría de familia b. No 9 3
# ℹ abbreviated name: ¹`Capacitación en salud mental`
# ℹ 1 more variable: Moda_Calidad <chr>
# Tabla de Frecuencia Cruzada para tres variables categóricas: Capacitación en salud mental por Tipo de comisaría y Sexo.cat("\n### Tabla Cruzada de Frecuencia: Capacitación en salud mental por Tipo de comisaría y Sexo\n")
### Tabla Cruzada de Frecuencia: Capacitación en salud mental por Tipo de comisaría y Sexo
# ftable() es útil para visualizar tablas de contingencia de más de 2 dimensiones de forma compacta.tabla_3d_formacion <-table(datos$`Tipo de comisaría`, datos$Sexo, datos$`Capacitación en salud mental`)print(ftable(tabla_3d_formacion))
a. Sí b. No
A. Comisaría básica Varón 77 135
Mujer 30 59
B. Comisaría de familia Varón 11 4
Mujer 11 4
# *** NOTA: USAR COMILLAS INVERSAS `` ` `` PARA NOMBRES CON ESPACIOS O CARACTERES ESPECIALES EN AES() y otros argumentos ***# Diagramas de Caja de Trabajo agota emocionalmente (Ordinal) por Tiempo de servicio (Ordinal), separados por Sexo (Categórica).cat("### Trabajo agota emocionalmente por Tiempo de servicio, separado por Sexo\n")
### Trabajo agota emocionalmente por Tiempo de servicio, separado por Sexo
ggplot(datos %>%filter(!is.na(`Trabajo agota emocionalmente`), !is.na(`Tiempo de servicio`), !is.na(Sexo)),aes(x = forcats::fct_drop(`Tiempo de servicio`), y =`Trabajo agota emocionalmente`, fill =`Tiempo de servicio`)) +# Usar variable factor en el eje Ygeom_boxplot(alpha =0.8) +labs(title ="Agotamiento Emocional Percibido por Tiempo de Servicio, separado por Sexo",x ="Tiempo de Servicio en la PNP",y ="Escala Agotamiento (1-5)", # La etiqueta del eje usa el rango de la escalafill ="Tiempo de Servicio") +theme_minimal() +theme(axis.text.x =element_text(angle =45, hjust =1)) +# Rotar etiquetas del eje X# guides(fill = FALSE) + # Ocultar leyenda de relleno si no es necesaria (si fill se usa para la variable x)facet_wrap(~ Sexo) # Crea un panel separado para cada nivel de Sexo
# Diagrama de caja de Calidad de atención (Ordinal) por Rango policial (Categórica), separado por Tipo de comisaría (Categórica).cat("### Calidad de atención por Rango policial, separado por Tipo de comisaría\n")
### Calidad de atención por Rango policial, separado por Tipo de comisaría
ggplot(datos %>%filter(!is.na(`Calidad de atención`), !is.na(`Rango policial`), !is.na(`Tipo de comisaría`)),aes(x = forcats::fct_drop(`Rango policial`), y =`Calidad de atención`, fill =`Rango policial`)) +# Usar variable factor en el eje Ygeom_boxplot(alpha =0.8) +labs(title ="Calidad de Atención por Rango Policial, separado por Tipo de Comisaría",x ="Rango Policial",y ="Escala Calidad de Atención (1-5)",fill ="Rango Policial") +theme_minimal() +theme(axis.text.x =element_text(angle =45, hjust =1)) +# guides(fill = FALSE) +facet_wrap(~`Tipo de comisaría`)
# Gráfico de dispersión: Relación entre Edad (Numérica) y Trabajo agota emocionalmente (Ordinal), donde el color representa el Rango policial (Categórica).cat("### Edad vs Trabajo agota emocionalmente, coloreado por Rango policial (Exploratorio)\n")
### Edad vs Trabajo agota emocionalmente, coloreado por Rango policial (Exploratorio)
ggplot(datos %>%filter(!is.na(Edad), !is.na(`Trabajo agota emocionalmente`), !is.na(`Rango policial`)),aes(x = Edad, y =`Trabajo agota emocionalmente`, color =`Rango policial`)) +# Usar variable factor en el eje Y y variable categórica para colorgeom_point(alpha =0.6, size =2, position =position_jitter(width =0.5, height =0.1)) +# Jittering para separar puntos# Opcional: geom_smooth por grupo si se desea ver tendencias separadas (con precaución)# geom_smooth(method = "lm", se = FALSE, aes(color = `Rango policial`)) +labs(title ="Edad vs Agotamiento Emocional Percibido, coloreado por Rango Policial",x ="Edad",y ="Escala Agotamiento (1-5)",color ="Rango Policial") +theme_minimal()
# Diagrama de barras: Frecuencia de Uso de red social (Categórica), separado por Sexo (Categórica) y Capacitación en salud mental (Categórica) (Facetado bidimensional).cat("### Uso de red social por Sexo y Capacitación en salud mental (Facetado)\n")
### Uso de red social por Sexo y Capacitación en salud mental (Facetado)
ggplot(datos %>%filter(!is.na(`Uso de red social`), !is.na(Sexo), !is.na(`Capacitación en salud mental`)),aes(x =`Uso de red social`, fill = Sexo)) +geom_bar(position ="dodge", color ="black", alpha =0.8) +labs(title ="Uso de Red Social por Sexo y Capacitación en salud mental",x ="Red Social Más Usada",y ="Frecuencia",fill ="Sexo") +theme_minimal() +theme(axis.text.x =element_text(angle =45, hjust =1)) +# facet_grid crea una cuadrícula de paneles definida por dos variables: Filas ~ Columnasfacet_grid(`Capacitación en salud mental`~ Sexo)
# La variable 'Ubicación' es texto libre, su análisis multivariado descriptivo es complejo (ej. análisis de texto si hubiera muchos datos).# La variable 'Marca Temporal' no se usa típicamente en análisis multivariado descriptivo estándar.# La variable 'Factores estresantes' es categórica, se puede usar en tablas/gráficos cruzados multivariados similares a los ejemplos anteriores si es relevante.