The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
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.
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:
J189 en lugar de J18.9).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:
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)
#> ID_EGRESO PACIENTE_ID ANO DIAG1
#> 1 1 49 2018 J189
#> 2 2 37 2022 E119
#> 3 3 1 2021 E149
#> 4 4 25 2018 N390
#> 5 5 10 2022 I10X
#> 6 6 36 2021 C509cie_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 *).
# 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)
#> DIAG1 DIAG1_NORM
#> 1 J189 J18.9
#> 2 E119 E11.9
#> 3 E149 E14.9
#> 4 N390 N39.0
#> 5 I10X I10Con esto, I10X quedó como I10 y
J189 como J18.9: los códigos ya son
comparables con el catálogo oficial.
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:
# 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))
#> ID_EGRESO DIAG1
#> 1 1 J189
#> 2 2 E119
#> 3 3 E149
#> 4 4 N390
#> 5 5 I10X
#> 6 6 C509
#> descripcion
#> 1 Neumonía, no especificada
#> 2 Diabetes mellitus tipo 2 sin complicaciones
#> 3 Diabetes mellitus, no especificada, sin mención de complicación
#> 4 Infección de vías urinarias, sitio no especificado
#> 5 Hipertensión esencial (primaria)
#> 6 Tumor maligno de la mama, parte no especificadaSi 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():
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):
# 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
#> # A tibble: 100 × 4
#> codigo descripcion score categoria
#> <chr> <chr> <dbl> <chr>
#> 1 E10 Diabetes mellitus insulinodependiente 0.917 E10 DIAB…
#> 2 E10.0 Diabetes mellitus tipo 1 con coma 0.917 E10 DIAB…
#> 3 E10.1 Diabetes mellitus tipo 1 con cetoacidosis 0.917 E10 DIAB…
#> 4 E10.2 Diabetes mellitus tipo 1 con complicaciones renales 0.917 E10 DIAB…
#> 5 E10.3 Diabetes mellitus tipo 1 con complicaciones oftálmicas 0.917 E10 DIAB…
#> 6 E10.4 Diabetes mellitus tipo 1 con complicaciones neurológi… 0.917 E10 DIAB…
#> 7 E10.5 Diabetes mellitus tipo 1 con complicaciones circulat… 0.917 E10 DIAB…
#> 8 E10.6 Diabetes mellitus tipo 1 con otras complicaciones esp… 0.917 E10 DIAB…
#> 9 E10.7 Diabetes mellitus tipo 1 con complicaciones múltiples 0.917 E10 DIAB…
#> 10 E10.8 Diabetes mellitus tipo 1 con complicaciones no especi… 0.917 E10 DIAB…
#> # ℹ 90 more rowsCada 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:
# ¿Qué códigos de diabetes están realmente en mi base?
codigos_diabetes <- intersect(
resultados_busqueda$codigo,
unique(egresos$DIAG1_NORM)
)
codigos_diabetes
#> [1] "E11.9" "E14.9"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:
# Reporte final: egresos por diabetes, resumidos por tipo
egresos_full |>
filter(DIAG1_NORM %in% codigos_diabetes) |>
count(descripcion, sort = TRUE)
#> descripcion n
#> 1 Diabetes mellitus tipo 2 sin complicaciones 14
#> 2 Diabetes mellitus, no especificada, sin mención de complicación 12Con 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.
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:
cie_lookup("XYZ123")
#> ✖ Código no encontrado: "XYZ123"
#> # A tibble: 0 × 11
#> # ℹ 11 variables: codigo <chr>, descripcion <chr>, categoria <chr>,
#> # seccion <chr>, capitulo_nombre <chr>, inclusion <chr>, exclusion <chr>,
#> # capitulo <chr>, es_daga <lgl>, es_cruz <lgl>, uso_cl <chr>Si el umbral de cie_search() es demasiado estricto para
el término ingresado:
cie_search("zzzqwerty", threshold = 0.95)
#> ✖ Sin coincidencias >= threshold 0.95
#> # A tibble: 0 × 4
#> # ℹ 4 variables: codigo <chr>, descripcion <chr>, score <dbl>, categoria <chr>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():
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:
# 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)
#> # A tibble: 10 × 19
#> PACIENTE_ID mi chf pvd cevd dementia cpd rheumd pud mld diab
#> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
#> 1 1 0 0 0 0 0 0 0 0 0 1
#> 2 2 0 0 0 0 0 0 0 0 0 0
#> 3 3 0 0 0 0 0 0 0 0 0 1
#> 4 4 0 1 0 0 0 1 0 0 0 0
#> 5 5 0 1 0 0 0 0 0 0 0 1
#> 6 6 0 0 0 0 0 1 0 0 0 1
#> 7 7 0 0 0 0 0 0 0 0 0 0
#> 8 8 0 0 0 0 0 0 0 0 0 1
#> 9 9 0 0 0 0 0 1 0 0 0 0
#> 10 10 0 0 0 0 0 0 0 0 0 1
#> # ℹ 8 more variables: diabwc <int>, hp <int>, rend <int>, canc <int>,
#> # msld <int>, metacanc <int>, aids <int>, score_charlson <dbl>El recorrido de esta guía cubre el ciclo completo desde la base cruda hasta el insumo analítico:
cie_norm().cie_describe() y metadata con
cie_lookup().cie_search(), tolerante a errores y con comportamiento
predecible cuando no hay resultados.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.
cie10_sql() y tablas formateadas con
cie_table().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.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.