--- title: "Primeros pasos con ciecl: un reporte de egresos hospitalarios" author: "Rodolfo Tasso Suazo" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Primeros pasos con ciecl: un reporte de egresos hospitalarios} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) library(ciecl) library(dplyr) ``` ## ¿Para quién es esta guía? Imagina que trabajas en la unidad de estadística de un hospital y cada mes eres la persona encargada de elaborar el **reporte de egresos por diabetes** para la dirección del servicio. Recibes la base de egresos hospitalarios, y tu objetivo es responder preguntas concretas: ¿cuántos egresos tuvieron como diagnóstico principal una diabetes?, ¿de qué tipo?, ¿qué tan complejos eran esos pacientes? El problema es que la base llega con códigos CIE-10 en formatos inconsistentes y sin descripciones: para interpretarlos tendrías que consultar a mano el catálogo oficial en PDF o Excel. `ciecl` elimina ese paso: incorpora el catálogo oficial CIE-10 de Chile (MINSAL/DEIS v2018) dentro de R y te permite normalizar, describir, buscar y analizar los códigos directamente sobre tu base. Esta guía recorre ese flujo completo, de lo básico a lo avanzado. Solo necesitas conocimientos básicos de R; si además usas `dplyr`, los ejemplos encajan directo en tus pipelines. ## Los datos: egresos hospitalarios del DEIS Las bases de **Egresos Hospitalarios** las publica el Departamento de Estadísticas e Información de Salud (DEIS) del Ministerio de Salud de Chile. Cada fila es un alta hospitalaria y la columna `DIAG1` contiene el diagnóstico principal codificado en CIE-10. En la práctica, estos archivos llegan con dos variaciones de formato muy comunes: 1. **Formatos compactos**: códigos sin punto decimal (ej: `J189` en lugar de `J18.9`). 2. **Sufijos de relleno**: una letra `X` para completar la longitud del campo en categorías de 3 dígitos (ej: `I10X` para hipertensión esencial). Generemos un conjunto de datos sintético que replica la estructura y las anomalías típicas de los archivos del DEIS: ```{r datos} set.seed(42) # Simulación de 200 registros con formatos típicos del DEIS Chile egresos <- data.frame( ID_EGRESO = 1:200, PACIENTE_ID = sample(1:50, 200, replace = TRUE), ANO = sample(2018:2022, 200, replace = TRUE), DIAG1 = sample( c( "J189", "O800", "Z380", "K359", "N390", "I10X", "J449", "E119", "O829", "J069", "K922", "N185", "I509", "C509", "A099", "N40X", "K800", "I259", "J180", "E149" ), size = 200, replace = TRUE ), stringsAsFactors = FALSE ) head(egresos) ``` ## Paso 1: Normalizar los códigos con `cie_norm()` Antes de cualquier análisis hay que estandarizar `DIAG1`. `cie_norm()` aplica las reglas de codificación oficial del MINSAL de forma vectorizada: elimina la `X` de relleno, inserta el punto decimal en la posición correcta y limpia espacios, guiones y símbolos especiales (como † o *). ```{r normalizacion} # Limpieza y estandarización de diagnósticos en el flujo de trabajo egresos <- egresos |> mutate( DIAG1_NORM = cie_norm(codes = DIAG1) ) # Comparación entre formato original y normalizado egresos |> select(DIAG1, DIAG1_NORM) |> distinct() |> head(5) ``` Con esto, `I10X` quedó como `I10` y `J189` como `J18.9`: los códigos ya son comparables con el catálogo oficial. ## Paso 2: Agregar las descripciones oficiales con `cie_describe()` Para el reporte necesitas las glosas clínicas, no solo los códigos. `cie_describe()` devuelve un vector de texto con una descripción por cada código, así que puedes agregarlo como una columna más de tu tabla con `mutate()`, sin pasos intermedios: ```{r describe} # Integración directa de descripciones al dataframe principal egresos_full <- egresos |> mutate( descripcion = cie_describe(DIAG1_NORM) ) head(egresos_full |> select(ID_EGRESO, DIAG1, descripcion)) ``` Si además de la glosa necesitas la metadata completa (capítulo, grupo, notas de inclusión/exclusión), usa `cie_lookup()`, que devuelve un `tibble` estructurado listo para un `left_join()`: ```{r lookup} # Obtención de metadata completa vía lookup + join metadata <- cie_lookup( code = unique(egresos$DIAG1_NORM), full_description = TRUE ) egresos_metadata <- egresos |> left_join(metadata, by = c("DIAG1_NORM" = "codigo")) ``` ## Paso 3: Encontrar códigos cuando no sabes el código con `cie_search()` Volvamos a tu reporte de diabetes: sospechas que en la base hay egresos por diabetes, pero ¿qué códigos exactos cubre el catálogo? En vez de hojear el PDF, buscas por texto. `cie_search()` usa similitud Jaro-Winkler, así que tolera errores tipográficos (aquí buscamos "diabetis" a propósito): ```{r busqueda} # Búsqueda tolerante: "diabetis" en lugar de "diabetes" # (por defecto se muestran los 50 resultados más parecidos; # ampliamos el límite porque el catálogo tiene muchos códigos de diabetes) resultados_busqueda <- cie_search(text = "diabetis", threshold = 0.7, max_results = 100) resultados_busqueda ``` Cada resultado incluye un `score` de similitud para evaluar la confiabilidad de la coincidencia. Pero la tabla anterior lista todos los códigos de diabetes del catálogo, y no todos necesariamente están en tu base. Para saber cuáles sí, basta con cruzar los resultados de la búsqueda con los códigos que realmente aparecen en tus datos: ```{r cruce} # ¿Qué códigos de diabetes están realmente en mi base? codigos_diabetes <- intersect( resultados_busqueda$codigo, unique(egresos$DIAG1_NORM) ) codigos_diabetes ``` Como se ve en el resultado, de todos los códigos de diabetes del catálogo solo dos están presentes en la columna `DIAG1` de tu base: `E11.9` y `E14.9`. El cruce identifica qué códigos contienen realmente tus datos, sin tener que revisar la tabla completa a mano. Con esa lista ya puedes filtrar los egresos y cerrar el reporte: ```{r reporte-diabetes} # Reporte final: egresos por diabetes, resumidos por tipo egresos_full |> filter(DIAG1_NORM %in% codigos_diabetes) |> count(descripcion, sort = TRUE) ``` Con esto tu reporte mensual de egresos por diabetes queda listo: sabes cuántos hubo y de qué tipo, con las glosas oficiales del catálogo. ## Cuando la búsqueda no entrega resultados Es normal que algunas consultas no encuentren nada, y conviene saber cómo se comporta el paquete en esos casos: **las funciones nunca fallan con un error por ausencia de resultados; devuelven un `tibble` vacío con la estructura de columnas correcta** y un mensaje informativo. Si buscas un código que no existe en el catálogo: ```{r sin-resultados-lookup} cie_lookup("XYZ123") ``` Si el umbral de `cie_search()` es demasiado estricto para el término ingresado: ```{r sin-resultados-search} cie_search("zzzqwerty", threshold = 0.95) ``` En ambos casos el flujo no se interrumpe: puedes verificar `nrow(resultado) == 0` y reaccionar (bajar el `threshold`, revisar la ortografía o validar el código). Para chequear rápidamente qué códigos de un vector son válidos según el catálogo, usa `cie_validate_vector()`: ```{r validacion} cie_validate_vector(c("E11.0", "XYZ123", "I10X")) ``` ## Paso 4: Estratificar riesgo con `cie_comorbid()` El último nivel del reporte es la complejidad de los pacientes. `cie_comorbid()` mapea los diagnósticos a los índices de Charlson o Elixhauser y devuelve una matriz de comorbilidades por paciente, lista para modelos estadísticos: ```{r comorbilidad, eval=rlang::is_installed("comorbidity")} # Requiere el paquete 'comorbidity' instalado # Cálculo del Índice de Charlson consolidado por paciente comorbilidades <- cie_comorbid( data = egresos, id = "PACIENTE_ID", code = "DIAG1", map = "charlson" ) head(comorbilidades, 10) ``` ## Resumen del flujo El recorrido de esta guía cubre el ciclo completo desde la base cruda hasta el insumo analítico: 1. **Estandarización**: corrección de formatos con `cie_norm()`. 2. **Contextualización**: glosas oficiales con `cie_describe()` y metadata con `cie_lookup()`. 3. **Exploración**: búsqueda de códigos por texto con `cie_search()`, tolerante a errores y con comportamiento predecible cuando no hay resultados. 4. **Agregación**: índices de comorbilidad con `cie_comorbid()`. ¿No sabes cuál función usar en otro escenario? Ejecuta `cie_guide()` para ver una tabla comparativa con la función recomendada y un ejemplo por caso. ## Para seguir aprendiendo - [Guía de instalación y configuración](instalacion.html): instalación y credenciales para la API CIE-11 de la OMS. - [Introducción a ciecl: CIE-10 Chile en R](ciecl-es.html): recorrido por función, incluyendo consultas SQL directas con `cie10_sql()` y tablas formateadas con `cie_table()`. - [Idiomas y normalización](idiomas.html): búsqueda en español e inglés y manejo de tildes. --- **Fuente de datos:** Esta herramienta utiliza el catálogo CIE-10 oficial para Chile, gestionado por el DEIS del Ministerio de Salud. Más detalles en [deis.minsal.cl](https://deis.minsal.cl).