El presente apartado describe el proceso metodológico de delimitación, identificación y depuración de la cohorte de estudio a partir de la Base Pública de Grupos Relacionados por el Diagnóstico (GRD) del año 2024. Para garantizar la validez del análisis, la sección se articula en dos etapas clave: primero, la caracterización clínica e inclusión de la Catarata Senil (H25) mediante la codificación normalizada CIE-10; y segundo, el seguimiento detallado de trazabilidad y atrición, el cual documenta la selección de los episodios hospitalarios mediante filtros sucesivos y exclusiones de calidad.
Se analiza la Catarata Senil, correspondiente a la categoría H25 de la Clasificación Internacional de Enfermedades (CIE-10, versión 2013). Esta patología es relevante por constituir una de las principales causas de pérdida visual reversible en la población adulta mayor y generar una alta demanda de intervenciones quirúrgicas en la red hospitalaria pública.
Tabla 1: Delimitación de códigos CIE-10 para la construcción de la cohorte.
| Código CIE-10 | Descripción Oficial | Criterio de Inclusión | Fuente de Clasificación |
|---|---|---|---|
| H25 | Catarata senil | Categoría principal | CIE-10 (v2013) / OMS |
| H25.0 | Catarata senil incipiente | Subcódigo | CIE-10 (v2013) / OMS |
| H25.1 | Catarata senil nuclear | Subcódigo | CIE-10 (v2013) / OMS |
| H25.2 | Catarata senil, tipo morgagnian | Subcódigo | CIE-10 (v2013) / OMS |
| H25.8 | Otras cataratas seniles | Subcódigo | CIE-10 (v2013) / OMS |
| H25.9 | Catarata senil, no especificada | Subcódigo | CIE-10 (v2013) / OMS |
# 1. Carga de la base completa (Ruta estrictamente relativa y codificación UTF-8)
ruta_base <- "GRD_PUBLICO_2024.txt"
grd_base <- fread(ruta_base, sep = "|", encoding = "UTF-8")
n_01_base_completa <- nrow(grd_base)
# 2. Exclusión de CMA (Cirugía Mayor Ambulatoria)
grd_egresos <- grd_base %>%
filter(!grepl("CMA|AMBULATORI", TIPO_ACTIVIDAD, ignore.case = TRUE))
n_02_egresos <- nrow(grd_egresos)
# 3. Filtros de Exclusión por Calidad de Datos (Edades o estancias inválidas)
grd_depurada <- grd_egresos %>%
mutate(
fecha_ing = as.Date(FECHA_INGRESO),
f_alta = as.Date(FECHAALTA),
f_nac = as.Date(FECHA_NACIMIENTO),
edad = floor(as.numeric(fecha_ing - f_nac) / 365.25),
estancia = as.numeric(f_alta - fecha_ing)
) %>%
filter(
!is.na(estancia) & estancia >= 0,
!is.na(edad) & edad >= 0 & edad <= 110
)
n_03_depurados <- nrow(grd_depurada)
# 4. Identificación de códigos H25 en Diagnóstico Principal
cohorte_diag_principal <- grd_depurada %>%
filter(grepl("^H25", trimws(DIAGNOSTICO1), ignore.case = TRUE))
n_04_principal <- nrow(cohorte_diag_principal)
# 5. Identificación de códigos H25 en Diagnósticos Secundarios (DIAGNOSTICO2 al 35)
cols_secundarias <- paste0("DIAGNOSTICO", 2:35)
cohorte_diag_secundario <- grd_depurada %>%
filter(
!grepl("^H25", trimws(DIAGNOSTICO1), ignore.case = TRUE) &
if_any(all_of(cols_secundarias), ~ grepl("^H25", trimws(.x), ignore.case = TRUE))
)
n_05_secundario <- nrow(cohorte_diag_secundario)
# Total cohorte H25 final
n_06_total_h25 <- n_04_principal + n_05_secundario
# Construcción de la tabla resumen de trazabilidad
tabla_trazabilidad <- data.frame(
Etapa = c(
"1. Base completa GRD 2024",
"2. Egresos Hospitalarios (Exclusión CMA)",
"3. Base depurada (Exclusión edades/estancias inválidas)",
"4. Diagnóstico Principal H25",
"5. Diagnóstico Secundario H25",
"6. Cohorte Total Final de Episodios H25"
),
Episodios = c(n_01_base_completa, n_02_egresos, n_03_depurados, n_04_principal, n_05_secundario, n_06_total_h25),
Porcentaje = c(
"-",
"100%",
paste0(round((n_03_depurados / n_02_egresos) * 100, 2), "%"),
paste0(round((n_04_principal / n_03_depurados) * 100, 3), "%"),
paste0(round((n_05_secundario / n_03_depurados) * 100, 3), "%"),
paste0(round((n_06_total_h25 / n_03_depurados) * 100, 3), "%")
)
)
kable(tabla_trazabilidad, caption = "Tabla 2: Trazabilidad y atrición de la cohorte GRD 2024")
| Etapa | Episodios | Porcentaje |
|---|---|---|
| 1. Base completa GRD 2024 | 1085813 | - |
| 2. Egresos Hospitalarios (Exclusión CMA) | 873772 | 100% |
| 3. Base depurada (Exclusión edades/estancias inválidas) | 873719 | 99.99% |
| 4. Diagnóstico Principal H25 | 108 | 0.012% |
| 5. Diagnóstico Secundario H25 | 281 | 0.032% |
| 6. Cohorte Total Final de Episodios H25 | 389 | 0.045% |
La atrición de la cohorte (Tabla 2) revela que los episodios
asociados a Catarata Senil (H25) representan un 0.045% (389) del total
de egresos hospitalarios depurados en el sistema público (873719).
Del total de la cohorte identificada, la enfermedad se presenta
predominantemente como un diagnóstico secundario (72.2% de la cohorte,
equivalente al 0.032% de los egresos globales) por sobre el diagnóstico
principal (27.8% de la cohorte).
Este patrón confirma que en la red
hospitalaria cerrada, la Catarata Senil actúa de manera prevalente como
una comorbilidad concomitante en adultos mayores ingresados por
patologías de mayor complejidad. Asimismo, la baja proporción de
ingresos con H25 como diagnóstico principal refleja que la resolución
quirúrgica de esta patología se realiza de forma mayoritaria en la
modalidad de Cirugía Mayor Ambulatoria (CMA), reservando la cama de
hospitalización para casos seleccionados de alta fragilidad
sistémica.
En esta sección se cuantifica el volumen total de la enfermedad dentro de la base hospitalaria, su participación según el rol diagnóstico y su comportamiento temporal a lo largo del año.
# 1. Tabla de Volumen y Participación Relativa
# (Se utilizan las variables calculadas en el chunk de 'trazabilidad' del paso anterior)
tabla_volumen <- data.frame(
`Clasificación Diagnóstica` = c("Diagnóstico Principal", "Diagnóstico Secundario", "Total Cohorte H25"),
`Episodios (N)` = c(n_04_principal, n_05_secundario, n_06_total_h25),
`% dentro de la Cohorte H25` = c(
round((n_04_principal / n_06_total_h25) * 100, 1),
round((n_05_secundario / n_06_total_h25) * 100, 1),
100.0
),
`% respecto a Egresos Totales` = c(
round((n_04_principal / n_03_depurados) * 100, 3),
round((n_05_secundario / n_03_depurados) * 100, 3),
round((n_06_total_h25 / n_03_depurados) * 100, 3)
)
)
kable(tabla_volumen, caption = "Tabla 3: Dimensionamiento y participación de H25 en egresos hospitalarios")
| Clasificación.Diagnóstica | Episodios..N. | X..dentro.de.la.Cohorte.H25 | X..respecto.a.Egresos.Totales |
|---|---|---|---|
| Diagnóstico Principal | 108 | 27.8 | 0.012 |
| Diagnóstico Secundario | 281 | 72.2 | 0.032 |
| Total Cohorte H25 | 389 | 100.0 | 0.045 |
# 2. Cálculo de distribución trimestral
cohorte_total <- bind_rows(
cohorte_diag_principal %>% mutate(Tipo_Diag = "Principal"),
cohorte_diag_secundario %>% mutate(Tipo_Diag = "Secundario")
) %>%
mutate(
fecha_ing = as.Date(FECHA_INGRESO),
trimestre = paste0("T", quarter(fecha_ing))
)
dist_trimestral <- cohorte_total %>%
group_by(trimestre) %>%
summarise(
Episodios = n(),
Porcentaje = round((n() / nrow(cohorte_total)) * 100, 2)
) %>%
mutate(
Var_Absoluta = Episodios - lag(Episodios),
Var_Relativa = round(((Episodios - lag(Episodios)) / lag(Episodios)) * 100, 2)
)
kable(dist_trimestral, caption = "Tabla 4: Distribución trimestral y variaciones de episodios H25")
| trimestre | Episodios | Porcentaje | Var_Absoluta | Var_Relativa |
|---|---|---|---|---|
| T1 | 58 | 14.91 | NA | NA |
| T2 | 103 | 26.48 | 45 | 77.59 |
| T3 | 99 | 25.45 | -4 | -3.88 |
| T4 | 129 | 33.16 | 30 | 30.30 |
# 3. Extracción de variables dinámicas para automatizar el texto (Cero errores manuales)
t_max <- dist_trimestral$trimestre[which.max(dist_trimestral$Episodios)]
ep_max <- max(dist_trimestral$Episodios)
pct_max <- dist_trimestral$Porcentaje[which.max(dist_trimestral$Episodios)]
t_min <- dist_trimestral$trimestre[which.min(dist_trimestral$Episodios)]
ep_min <- min(dist_trimestral$Episodios)
pct_min <- dist_trimestral$Porcentaje[which.min(dist_trimestral$Episodios)]
# Capturar datos específicos de T2 para el ejemplo de variación
var_abs_t2 <- dist_trimestral$Var_Absoluta[dist_trimestral$trimestre == "T2"]
var_rel_t2 <- dist_trimestral$Var_Relativa[dist_trimestral$trimestre == "T2"]
var_abs_t3 <- dist_trimestral$Var_Absoluta[dist_trimestral$trimestre == "T3"]
La evaluación temporal de la cohorte H25 evidencia una
mayor actividad durante el T4 con 129 episodios (33.16% del total
anual), concentrando la mayor presión física sobre la red hospitalaria
en dicho periodo. Por el contrario, el año inicia con un volumen menor
en T1 (58 casos; 14.91%). Esta distribución muestra un comportamiento
dinámico a lo largo de los meses.
Explicación de Métricas de Variación
Variación Absoluta: Cuantifica el cambio neto en volumen físico de atención. Por ejemplo, T2 suma 45 casos respecto a T1, mientras que T3 disminuye en 4 casos respecto a T2.
Variación Relativa: Mide la velocidad porcentual del cambio. Por ejemplo, T2 presenta la mayor aceleración proporcional con un aumento del 77.59% respecto al trimestre anterior.
Mientras la variación relativa destaca los momentos de mayor aceleración en el ritmo de internaciones, la variación absoluta identifica dónde se concentra el máximo volumen de ocupación de camas.
En esta sección se construye el perfil clínico-demográfico de los
episodios asociados a Catarata Senil (H25), analizando la
distribución por sexo, edad, duración de la estancia hospitalaria y
condición al egreso.
# 1. Procesamiento de variables clínicas y demográficas
cohorte_analisis <- cohorte_total %>%
mutate(
f_nac = as.Date(FECHA_NACIMIENTO),
f_alta = as.Date(FECHAALTA),
edad = floor(as.numeric(fecha_ing - f_nac) / 365.25),
estancia = as.numeric(f_alta - fecha_ing),
# Recodificación legible de Sexo
sexo_label = case_when(
SEXO %in% c("1", "H", "HOMBRE") ~ "Hombre",
SEXO %in% c("2", "M", "MUJER") ~ "Mujer",
TRUE ~ "Indeterminado / Sin Registro"
),
# Recodificación legible de Condición de Egreso (TIPOALTA)
condicion_egreso = case_when(
grepl("1|ALTA|DOMICILIO", TIPOALTA, ignore.case = TRUE) ~ "Alta Domiciliaria / Regular",
grepl("FALLE|MUERTE|3", TIPOALTA, ignore.case = TRUE) ~ "Fallecido",
grepl("TRASLADO|DERIV|2", TIPOALTA, ignore.case = TRUE) ~ "Traslado a otro centro",
TRUE ~ "Otro / Sin Clasificar"
)
)
# Gráfico de Barras: Distribución por Sexo
ggplot(cohorte_analisis, aes(x = sexo_label, fill = sexo_label)) +
geom_bar(color = "white", alpha = 0.85) +
scale_fill_manual(values = c("Hombre" = "#2b5c8f", "Mujer" = "#e06d53", "Indeterminado / Sin Registro" = "gray")) +
theme_minimal() +
labs(
title = "Figura 1: Distribución de episodios hospitalarios según Sexo",
x = "Sexo", y = "Cantidad de Episodios", fill = "Sexo"
) +
geom_text(stat = 'count', aes(label = after_stat(count)), vjust = -0.5, fontface = "bold")
# Gráfico de Histograma: Edad por Tipo de Diagnóstico
ggplot(cohorte_analisis, aes(x = edad, fill = Tipo_Diag)) +
geom_histogram(binwidth = 5, position = "dodge", color = "white", alpha = 0.85) +
scale_fill_manual(values = c("Principal" = "#2b5c8f", "Secundario" = "#e69f00")) +
theme_minimal() +
labs(
title = "Figura 2: Distribución de edad de los episodios por tipo de diagnóstico",
x = "Edad (Años)", y = "Cantidad de Episodios", fill = "Tipo de Diagnóstico"
)
# Variables dinámicas para el texto
pct_mujeres <- round(mean(cohorte_analisis$sexo_label == "Mujer", na.rm = TRUE) * 100, 1)
pct_mayores_60 <- round(mean(cohorte_analisis$edad > 60, na.rm = TRUE) * 100, 1)
Figura 1 y 2: La distribución por sexo evidencia una mayor participación de mujeres, representando el 51.7% de los casos analizados (Figura 1). En cuanto a la edad, se observa una alta concentración de episodios en adultos mayores, donde el 85.1% de los pacientes supera los 60 años, lo cual concuerda con la etiología senil de la enfermedad (Figura 2).
Debido a que la estancia hospitalaria en días es una variable cuantitativa continua fuertemente asimétrica (con concentración de casos de corta estadía y algunos casos complejos de larga estadía), el análisis prioriza la Mediana y el Rango Intercuartílico (RIC) por sobre el promedio.
# Cálculos de estadísticos de estancia agrupados por Tipo de Diagnóstico
tabla_estancia_summary <- cohorte_analisis %>%
group_by(Tipo_Diag) %>%
summarise(
Casos = n(),
Mediana_Dias = median(estancia, na.rm = TRUE),
Q1 = quantile(estancia, 0.25, na.rm = TRUE),
Q3 = quantile(estancia, 0.75, na.rm = TRUE),
RIC = IQR(estancia, na.rm = TRUE),
Promedio = round(mean(estancia, na.rm = TRUE), 2),
.groups = "drop"
)
kable(tabla_estancia_summary, caption = "Tabla 5: Resumen estadístico de la estancia hospitalaria (días) según diagnóstico")
| Tipo_Diag | Casos | Mediana_Dias | Q1 | Q3 | RIC | Promedio |
|---|---|---|---|---|---|---|
| Principal | 108 | 1.5 | 1 | 2 | 1 | 2.49 |
| Secundario | 281 | 7.0 | 3 | 12 | 9 | 12.79 |
# Variables dinámicas para el texto
mediana_gral <- median(cohorte_analisis$estancia, na.rm = TRUE)
ric_gral <- IQR(cohorte_analisis$estancia, na.rm = TRUE)
casos_prin <- tabla_estancia_summary$Casos[tabla_estancia_summary$Tipo_Diag == "Principal"]
med_prin <- tabla_estancia_summary$Mediana_Dias[tabla_estancia_summary$Tipo_Diag == "Principal"]
casos_sec <- tabla_estancia_summary$Casos[tabla_estancia_summary$Tipo_Diag == "Secundario"]
med_sec <- tabla_estancia_summary$Mediana_Dias[tabla_estancia_summary$Tipo_Diag == "Secundario"]
# Boxplot de Estancia por Tipo de Diagnóstico
ggplot(cohorte_analisis, aes(x = Tipo_Diag, y = estancia, fill = Tipo_Diag)) +
geom_boxplot(outlier.colour = "red", outlier.shape = 1, alpha = 0.7) +
scale_fill_manual(values = c("Principal" = "#2b5c8f", "Secundario" = "#e69f00")) +
theme_minimal() +
labs(
title = "Figura 3: Distribución de la estancia hospitalaria por tipo de diagnóstico",
x = "Tipo de Diagnóstico", y = "Días de Estancia", fill = "Diagnóstico"
)
La variable estancia presenta una distribución asimétrica. A nivel global, la mediana de la estancia es de 4 días (RIC: 8 días). Los episodios donde la catarata senil es el diagnóstico principal (108 casos) presentan estancias breves y homogéneas con una mediana de 1.5 días, compatibles con cirugías programadas; mientras que cuando es un diagnóstico secundario (281 casos), la estancia se prolonga significativamente a una mediana de 7 días debido a la patología médica o quirúrgica de base que motivó el ingreso.
# Tabla de Complejidad y Severidad
# Se utiliza IR_29301_peso y se transforman comas a puntos (formato decimal chileno)
tabla_complejidad <- cohorte_analisis %>%
group_by(Tipo_Diag) %>%
summarise(
`Peso_Mediano` = round(median(as.numeric(gsub(",", ".", IR_29301_PESO)), na.rm = TRUE), 3),
`Peso_RIC` = round(IQR(as.numeric(gsub(",", ".", IR_29301_PESO)), na.rm = TRUE), 3),
`Nivel_Severidad_Frecuente` = names(sort(table(IR_29301_SEVERIDAD), decreasing = TRUE))[1],
.groups = "drop"
)
kable(tabla_complejidad, caption = "Tabla 6: Peso relativo GRD y Nivel de Severidad predominante según rol diagnóstico")
| Tipo_Diag | Peso_Mediano | Peso_RIC | Nivel_Severidad_Frecuente |
|---|---|---|---|
| Principal | 0.675 | 0.282 | 1 |
| Secundario | 1.008 | 0.808 | 2 |
# Variables dinámicas para texto
peso_med_prin <- tabla_complejidad$Peso_Mediano[tabla_complejidad$Tipo_Diag == "Principal"]
peso_med_sec <- tabla_complejidad$Peso_Mediano[tabla_complejidad$Tipo_Diag == "Secundario"]
sev_prin <- tabla_complejidad$Nivel_Severidad_Frecuente[tabla_complejidad$Tipo_Diag == "Principal"]
El Peso GRD mediano para episodios con H25 como diagnóstico principal es de 0.675, sustancialmente menor que el peso mediano de 1.008 observado cuando actúa como comorbilidad secundaria. Esto refleja un menor consumo relativo de recursos en internaciones oftalmológicas exclusivas. Además, la mayoría de los casos donde la catarata es la afección principal se sitúan en un nivel de severidad 1.
# Tabla de Frecuencias de Condición de Egreso
tabla_egreso <- cohorte_analisis %>%
count(condicion_egreso, name = "Episodios") %>%
mutate(Porcentaje = round((Episodios / sum(Episodios)) * 100, 2))
kable(tabla_egreso, caption = "Tabla 7: Distribución de episodios según condición al egreso")
| condicion_egreso | Episodios | Porcentaje |
|---|---|---|
| Alta Domiciliaria / Regular | 335 | 86.12 |
| Fallecido | 16 | 4.11 |
| Otro / Sin Clasificar | 26 | 6.68 |
| Traslado a otro centro | 12 | 3.08 |
# Variables dinámicas para el texto
pct_alta <- tabla_egreso$Porcentaje[tabla_egreso$condicion_egreso == "Alta Domiciliaria / Regular"]
# Gráfico de Barras de Condición de Egreso
ggplot(tabla_egreso, aes(x = reorder(condicion_egreso, -Episodios), y = Episodios, fill = condicion_egreso)) +
geom_bar(stat = "identity", color = "white", alpha = 0.85) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 15, hjust = 1)) +
labs(
title = "Figura 4: Distribución de episodios por condición al egreso",
x = "Condición de Egreso", y = "Cantidad de Episodios", fill = "Estado"
) +
geom_text(aes(label = paste0(Porcentaje, "%")), vjust = -0.5, fontface = "bold")
La abrumadora mayoría de los episodios finaliza con una condición de Alta Domiciliaria / Regular (86.12%), demostrando el carácter electivo y curativo del abordaje quirúrgico de la catarata. Los escasos eventos de mortalidad o traslado documentados se concentran predominantemente en aquellos episodios donde la catarata es apenas un diagnóstico secundario frente a admisiones de alta severidad sistémica.
En esta sección se analiza la distribución geográfica y por prestador
de los episodios hospitalarios asociados a Catarata Senil
(H25).
Se identifican los Servicios de Salud que concentran la mayor demanda hospitalaria absoluta de la cohorte.
# 1. Corrección de codificación y mapeo de nombres
cohorte_analisis <- cohorte_analisis %>%
mutate(
# Corrección de caracteres rotos
SERVICIO_SALUD = gsub("CONCEPCI N", "CONCEPCIÓN", SERVICIO_SALUD),
SERVICIO_SALUD = gsub("VALPARA SO", "VALPARAÍSO", SERVICIO_SALUD),
# Asignación de Región completa para todo Chile
Region_Asignada = case_when(
grepl("ARICA", SERVICIO_SALUD) ~ "Arica y Parinacota",
grepl("IQUIQUE", SERVICIO_SALUD) ~ "Tarapacá",
grepl("ANTOFAGASTA", SERVICIO_SALUD) ~ "Antofagasta",
grepl("ATACAMA", SERVICIO_SALUD) ~ "Atacama",
grepl("COQUIMBO", SERVICIO_SALUD) ~ "Coquimbo",
grepl("VALPARAÍSO|VIÑA|ACONCAGUA", SERVICIO_SALUD) ~ "Valparaíso",
grepl("METROPOLITANO", SERVICIO_SALUD) ~ "Metropolitana",
grepl("O'HIGGINS|LIBERTADOR", SERVICIO_SALUD) ~ "O'Higgins",
grepl("MAULE", SERVICIO_SALUD) ~ "Maule",
grepl("ÑUBLE", SERVICIO_SALUD) ~ "Ñuble",
grepl("CONCEPCIÓN|TALCAHUANO|BIOBÍO|ARAUCO", SERVICIO_SALUD) ~ "Biobío",
grepl("ARAUCANÍA", SERVICIO_SALUD) ~ "La Araucanía",
grepl("VALDIVIA|RÍOS", SERVICIO_SALUD) ~ "Los Ríos",
grepl("OSORNO|RELONCAVÍ|CHILOÉ", SERVICIO_SALUD) ~ "Los Lagos",
grepl("AYSÉN", SERVICIO_SALUD) ~ "Aysén",
grepl("MAGALLANES", SERVICIO_SALUD) ~ "Magallanes",
TRUE ~ "Sin Registro"
),
# Traducción de Códigos a Nombres Reales (Top prestadores detectados)
Nombre_Hospital = case_when(
COD_HOSPITAL == 118100 ~ "Hosp. Las Higueras (Talcahuano)",
COD_HOSPITAL == 123100 ~ "Hosp. Base San José (Osorno)",
COD_HOSPITAL == 109100 ~ "Hosp. San José (Metropolitano)",
COD_HOSPITAL == 116100 ~ "Hosp. Guillermo Grant Benavente",
COD_HOSPITAL == 116105 ~ "Hosp. Traumatológico de Concepción",
COD_HOSPITAL == 119101 ~ "Hosp. Regional de Temuco",
TRUE ~ paste0("Hospital Cód. ", COD_HOSPITAL)
)
)
# Distribución por Región
tabla_regiones <- cohorte_analisis %>%
count(Region_Asignada, name = "Episodios_H25", sort = TRUE) %>%
mutate(Porcentaje = round((Episodios_H25 / sum(Episodios_H25)) * 100, 2))
kable(tabla_regiones, caption = "Tabla 6: Distribución de episodios H25 por Región")
| Region_Asignada | Episodios_H25 | Porcentaje |
|---|---|---|
| Biobío | 99 | 25.45 |
| Metropolitana | 85 | 21.85 |
| Sin Registro | 67 | 17.22 |
| Maule | 55 | 14.14 |
| Los Lagos | 46 | 11.83 |
| Los Ríos | 14 | 3.60 |
| Tarapacá | 8 | 2.06 |
| O’Higgins | 6 | 1.54 |
| Arica y Parinacota | 5 | 1.29 |
| Antofagasta | 1 | 0.26 |
| Coquimbo | 1 | 0.26 |
| Magallanes | 1 | 0.26 |
| Valparaíso | 1 | 0.26 |
# Distribución por Servicio de Salud
top_servicios <- cohorte_analisis %>%
count(SERVICIO_SALUD, name = "Episodios_H25", sort = TRUE) %>%
mutate(Porcentaje_del_Total_H25 = round((Episodios_H25 / sum(Episodios_H25)) * 100, 2)) %>%
head(5)
kable(top_servicios, caption = "Tabla 7: Top 5 Servicios de Salud con mayor volumen absoluto de episodios H25")
| SERVICIO_SALUD | Episodios_H25 | Porcentaje_del_Total_H25 |
|---|---|---|
| CONCEPCIÓN | 64 | 16.45 |
| DEL MAULE | 55 | 14.14 |
| OSORNO | 46 | 11.83 |
| METROPOLITANO NORTE | 40 | 10.28 |
| TALCAHUANO | 26 | 6.68 |
# Variables dinámicas para el texto
reg_top <- tabla_regiones$Region_Asignada[1]
reg_pct <- tabla_regiones$Porcentaje[1]
ss_top <- top_servicios$SERVICIO_SALUD[1]
ss_ep <- top_servicios$Episodios_H25[1]
ss_pct <- top_servicios$Porcentaje_del_Total_H25[1]
La actividad asistencial asociada a la cohorte presenta una distribución territorial focalizada. A nivel macro, la región de Biobío concentra la mayor proporción de casos con el 25.45% del volumen nacional. Específicamente, a nivel de redes asistenciales, el Servicio de Salud CONCEPCIÓN registra el volumen máximo con 64 episodios, lo que equivale al 16.45% del total de la cohorte.
Los datos muestran una clara concentración de la actividad en los Servicios de Salud de mayor complejidad poblacional y resolutividad oftalmológica. El Servicio de Salud CONCEPCIÓN lidera el volumen nacional con 64 episodios, representando el 16.45% del total de la cohorte analizada.
La caracterización institucional contrasta el volumen absoluto de casos en los principales centros con el peso relativo de la patología dentro de la actividad global de cada establecimiento, aplicando un filtro metodológico de estabilidad (mínimo 50 egresos anuales).
# Top 5 Servicios de Salud con mayor volumen de episodios H25
top_servicios <- cohorte_analisis %>%
count(SERVICIO_SALUD, name = "Episodios_H25", sort = TRUE) %>%
mutate(Porcentaje_del_Total_H25 = round((Episodios_H25 / sum(Episodios_H25)) * 100, 2)) %>%
head(5)
kable(top_servicios, caption = "Tabla 6: Top 5 Servicios de Salud con mayor volumen absoluto de episodios H25")
| SERVICIO_SALUD | Episodios_H25 | Porcentaje_del_Total_H25 |
|---|---|---|
| CONCEPCIÓN | 64 | 16.45 |
| DEL MAULE | 55 | 14.14 |
| OSORNO | 46 | 11.83 |
| METROPOLITANO NORTE | 40 | 10.28 |
| TALCAHUANO | 26 | 6.68 |
# Top 5 Hospitales por número absoluto (usando nombres)
top_hosp_absoluto <- cohorte_analisis %>%
count(Nombre_Hospital, name = "Episodios_H25", sort = TRUE) %>%
mutate(Porcentaje_del_Total_H25 = round((Episodios_H25 / nrow(cohorte_analisis)) * 100, 2)) %>%
head(5)
kable(top_hosp_absoluto, caption = "Tabla 8: Top 5 Establecimientos con mayor volumen absoluto de casos H25")
| Nombre_Hospital | Episodios_H25 | Porcentaje_del_Total_H25 |
|---|---|---|
| Hosp. Las Higueras (Talcahuano) | 83 | 21.34 |
| Hosp. Base San José (Osorno) | 47 | 12.08 |
| Hosp. San José (Metropolitano) | 40 | 10.28 |
| Hosp. Guillermo Grant Benavente | 29 | 7.46 |
| Hosp. Traumatológico de Concepción | 22 | 5.66 |
# Cálculo de la proporción con filtro de estabilidad
total_egresos_hospital <- grd_egresos %>%
# Se mapean los nombres también a la base general para el cruce
mutate(Nombre_Hospital = case_when(
COD_HOSPITAL == 118100 ~ "Hosp. Las Higueras (Talcahuano)",
COD_HOSPITAL == 123100 ~ "Hosp. Base San José (Osorno)",
COD_HOSPITAL == 109100 ~ "Hosp. San José (Metropolitano)",
COD_HOSPITAL == 116100 ~ "Hosp. Guillermo Grant Benavente",
COD_HOSPITAL == 116105 ~ "Hosp. Traumatológico de Concepción",
COD_HOSPITAL == 119101 ~ "Hosp. Regional de Temuco",
TRUE ~ paste0("Hospital Cód. ", COD_HOSPITAL)
)) %>%
count(Nombre_Hospital, name = "Total_Egresos_Hospital")
peso_relativo_hospitales <- total_egresos_hospital %>%
left_join(top_hosp_absoluto %>% select(Nombre_Hospital, Episodios_H25), by = "Nombre_Hospital") %>%
mutate(
Episodios_H25 = ifelse(is.na(Episodios_H25), 0, Episodios_H25),
Proporcion_H25_Pct = round((Episodios_H25 / Total_Egresos_Hospital) * 100, 2)
) %>%
filter(Total_Egresos_Hospital >= 50) %>%
arrange(desc(Proporcion_H25_Pct)) %>%
head(5)
kable(peso_relativo_hospitales, caption = "Tabla 9: Top 5 Establecimientos según mayor peso relativo (% sobre su propia actividad)")
| Nombre_Hospital | Total_Egresos_Hospital | Episodios_H25 | Proporcion_H25_Pct |
|---|---|---|---|
| Hosp. Base San José (Osorno) | 17187 | 47 | 0.27 |
| Hosp. Las Higueras (Talcahuano) | 30480 | 83 | 0.27 |
| Hosp. San José (Metropolitano) | 20554 | 40 | 0.19 |
| Hosp. Guillermo Grant Benavente | 15721 | 29 | 0.18 |
| Hosp. Traumatológico de Concepción | 27728 | 22 | 0.08 |
# Variables dinámicas
hosp_vol <- top_hosp_absoluto$Nombre_Hospital[1]
hosp_vol_ep <- top_hosp_absoluto$Episodios_H25[1]
hosp_pct <- peso_relativo_hospitales$Nombre_Hospital[1]
hosp_pct_val <- peso_relativo_hospitales$Proporcion_H25_Pct[1]
La tabla comparativa permite distinguir entre la magnitud operativa y el peso institucional de la enfermedad:
El establecimiento con mayor volumen absoluto es el Hosp. Las Higueras (Talcahuano), acumulando un total de 83 casos.
En contraste, al analizar el impacto relativo, el hospital donde esta enfermedad representa la mayor proporción respecto a su actividad total es el Hosp. Base San José (Osorno), con un 0.27% de sus egresos anuales asociados a esta condición.
# Se obtienen los nombres del Top 5
nombres_top_5 <- top_hosp_absoluto$Nombre_Hospital
comparativo_hospitales <- cohorte_analisis %>%
filter(Nombre_Hospital %in% nombres_top_5) %>%
group_by(Nombre_Hospital) %>%
summarise(
Casos = n(),
Mediana_Estancia = median(estancia, na.rm = TRUE),
RIC_Estancia = IQR(estancia, na.rm = TRUE),
Moda_Severidad = names(sort(table(IR_29301_SEVERIDAD), decreasing = TRUE))[1]
) %>%
arrange(desc(Casos))
kable(comparativo_hospitales, caption = "Tabla 10: Comparativo de estancia y nivel de severidad en los principales prestadores")
| Nombre_Hospital | Casos | Mediana_Estancia | RIC_Estancia | Moda_Severidad |
|---|---|---|---|---|
| Hosp. Las Higueras (Talcahuano) | 83 | 3.0 | 6.00 | 2 |
| Hosp. Base San José (Osorno) | 47 | 2.0 | 1.00 | 1 |
| Hosp. San José (Metropolitano) | 40 | 7.0 | 6.25 | 3 |
| Hosp. Guillermo Grant Benavente | 29 | 7.0 | 18.00 | 3 |
| Hosp. Traumatológico de Concepción | 22 | 6.5 | 7.50 | 3 |
Al examinar la distribución de la gestión clínica en los cinco prestadores con mayor carga asistencial, se observan medianas de estancia hospitalaria que oscilan entre los 2 y 7 días, con episodios registrados predominantemente en niveles de severidad GRD 2 y 1 y 3.
En esta sección se audita la integridad, consistencia y completitud
de la información en las variables utilizadas para el análisis de la
cohorte de Catarata Senil (H25), cuantificando los
registros descartados y el impacto final de estas exclusiones sobre el
tamaño muestral.
library(dplyr)
library(knitr)
library(tidyr)
# 1. Conteo de Valores Faltantes en la base completa para variables clave
evaluacion_faltantes <- grd_base %>%
summarise(
`FECHA_INGRESO (NA/Vacío)` = sum(is.na(FECHA_INGRESO) | trimws(FECHA_INGRESO) == ""),
`FECHAALTA (NA/Vacío)` = sum(is.na(FECHAALTA) | trimws(FECHAALTA) == ""),
`FECHA_NACIMIENTO (NA/Vacío)` = sum(is.na(FECHA_NACIMIENTO) | trimws(FECHA_NACIMIENTO) == ""),
`SEXO (Sin registrar/NA)` = sum(is.na(SEXO) | trimws(SEXO) %in% c("", "9", "0", "DESCONOCIDO")),
`COD_HOSPITAL (NA/Vacío)` = sum(is.na(COD_HOSPITAL) | trimws(COD_HOSPITAL) == ""),
`SERVICIO_SALUD (NA/Vacío)` = sum(is.na(SERVICIO_SALUD) | trimws(SERVICIO_SALUD) == ""),
`DIAGNOSTICO1 (NA/Vacío)` = sum(is.na(DIAGNOSTICO1) | trimws(DIAGNOSTICO1) == "")
) %>%
pivot_longer(cols = everything(), names_to = "Variable", values_to = "Registros_Faltantes") %>%
mutate(Porcentaje = round((Registros_Faltantes / nrow(grd_base)) * 100, 3))
kable(evaluacion_faltantes, caption = "Tabla 11: Auditoría de valores faltantes y no clasificados en la base original")
| Variable | Registros_Faltantes | Porcentaje |
|---|---|---|
| FECHA_INGRESO (NA/Vacío) | 0 | 0.000 |
| FECHAALTA (NA/Vacío) | 0 | 0.000 |
| FECHA_NACIMIENTO (NA/Vacío) | 0 | 0.000 |
| SEXO (Sin registrar/NA) | 116 | 0.011 |
| COD_HOSPITAL (NA/Vacío) | 0 | 0.000 |
| SERVICIO_SALUD (NA/Vacío) | 0 | 0.000 |
| DIAGNOSTICO1 (NA/Vacío) | 0 | 0.000 |
Como se observa en la auditoría inicial de los registros, las variables estructurales del mecanismo GRD presentan altos estándares de completitud obligatoria, garantizando la viabilidad del análisis territorial y clínico posterior.
Se aplican reglas de validación lógica sobre las variables derivadas (tiempo y edad) y se rastrean registros repetidos directamente sobre la totalidad de la base original:
Duplicidad de Registros: Se auditan duplicados exactos integrales en todas las columnas de la fila.
Estancias Incompatibles: Valores calculados de estancia hospitalaria menores a 0 días.
Edades Incompatibles: Edades negativas o pacientes registrados con más de 110 años de edad.
# Auditoría en la base bruta completa para evidenciar las anomalías reales
grd_auditoria <- grd_base %>%
mutate(
fecha_ing_temp = as.Date(FECHA_INGRESO),
f_alta_temp = as.Date(FECHAALTA),
f_nac_temp = as.Date(FECHA_NACIMIENTO),
edad_temp = floor(as.numeric(fecha_ing_temp - f_nac_temp) / 365.25),
estancia_temp = as.numeric(f_alta_temp - fecha_ing_temp)
)
duplicados_conteo <- sum(duplicated(grd_base))
estancias_negativas <- sum(grd_auditoria$estancia_temp < 0, na.rm = TRUE)
# CORRECCIÓN: Se cambió \vert{} por la barra vertical |
edades_incompatibles <- sum(grd_auditoria$edad_temp < 0, na.rm = TRUE) + sum(grd_auditoria$edad_temp > 110, na.rm = TRUE)
tabla_inconsistencias <- data.frame(
Tipo_de_Inconsistencia = c(
"Registros Duplicados Exactos (filas idénticas)",
"Estancias Imposibles/Incompatibles (< 0 días)",
"Edades Fuera de Rango Biológico (< 0 o > 110 años)"
),
Casos_Detectados = c(duplicados_conteo, estancias_negativas, edades_incompatibles),
Porcentaje_del_Total = c(
round((duplicados_conteo / nrow(grd_base)) * 100, 3),
round((estancias_negativas / nrow(grd_base)) * 100, 3),
round((edades_incompatibles / nrow(grd_base)) * 100, 3)
)
)
kable(tabla_inconsistencias, caption = "Tabla 12: Frecuencia de valores extremos e inconsistencias en la base total")
| Tipo_de_Inconsistencia | Casos_Detectados | Porcentaje_del_Total |
|---|---|---|
| Registros Duplicados Exactos (filas idénticas) | 330 | 0.03 |
| Estancias Imposibles/Incompatibles (< 0 días) | 0 | 0.00 |
| Edades Fuera de Rango Biológico (< 0 o > 110 años) | 0 | 0.00 |
Para garantizar un análisis estadístico libre de sesgos provocados
por errores de digitación en los sistemas hospitalarios, se adoptó la
decisión de excluir los registros con edades y estancias inconsistentes.
Este filtro de calidad se ejecutó de forma temprana sobre la base global
(previo a la selección de la cohorte específica de Catarata Senil).
La tabla de atrición general detalla el impacto cuantitativo de esta
decisión de calidad:
# Balance de retención de la base general
tabla_depuracion_impacto <- data.frame(
Criterio_de_Exclusión = c(
"1. Base Bruta Total GRD 2024",
"2. Base Restante tras Exclusión de CMA",
"3. Exclusión por Estancia Nula/Negativa o Edad Incompatible",
"4. Base Analítica Consolidada (Pool de búsqueda)"
),
Episodios = c(
nrow(grd_base),
n_02_egresos,
-(nrow(grd_egresos) - n_03_depurados),
n_03_depurados
),
Retención_Porcentual = c(
"100.0%",
paste0(round((n_02_egresos / nrow(grd_base)) * 100, 2), "%"),
paste0("-", round(((nrow(grd_egresos) - n_03_depurados) / nrow(grd_base)) * 100, 3), "%"),
paste0(round((n_03_depurados / nrow(grd_base)) * 100, 2), "%")
)
)
kable(tabla_depuracion_impacto, caption = "Tabla 13: Balance de depuración de la muestra por criterios de calidad")
| Criterio_de_Exclusión | Episodios | Retención_Porcentual |
|---|---|---|
| 1. Base Bruta Total GRD 2024 | 1085813 | 100.0% |
| 2. Base Restante tras Exclusión de CMA | 873772 | 80.47% |
| 3. Exclusión por Estancia Nula/Negativa o Edad Incompatible | -53 | -0.005% |
| 4. Base Analítica Consolidada (Pool de búsqueda) | 873719 | 80.47% |
Las exclusiones realizadas responden estrictamente a criterios de coherencia biológico-asistencial. Como se documenta en la tabla, la pérdida total de datos atribuible a registros de mala calidad representa una fracción sumamente marginal del total de la información recabada, garantizando así la solidez estadística y la representatividad nacional de las conclusiones emitidas en este informe.
En esta sección final se presenta el cierre consolidado del estudio, estructurado en tres componentes fundamentales: la síntesis cuantitativa de los cinco hallazgos principales derivados de la cohorte GRD 2024, el análisis de las tres limitaciones metodológicas del estudio y la propuesta de un análisis posterior avanzado ejecutable sobre esta misma base de datos.
H25) registrada como diagnóstico principal,
mientras que el 72.2% restante ingresó por otra patología base y
presentó la catarata como un diagnóstico secundario concomitante.Ausencia de Identificador Único de Paciente (RUT Anónimo): La imposibilidad de rastrear a los individuos en el tiempo (RUT anonimizado por episodio) impide diferenciar si los registros representan a personas distintas o a un mismo paciente que reingresó posteriormente para la cirugía bilateral del segundo ojo.
Sesgo de Selección por Subregistro de Atención Ambulatoria (CMA): Al excluir la actividad de Cirugía Mayor Ambulatoria (CMA) sin pernoctación de la base de hospitalización cerrada, se subestima drásticamente el volumen real de resolución quirúrgica de cataratas que el país gestiona en modalidad abierta.
Variabilidad en la Calidad del Llenado de Diagnósticos Secundarios: La codificación CIE-10 de diagnósticos secundarios (comorbilidades) depende fuertemente del criterio y exhaustividad clínica del profesional que firma el alta, lo que puede generar diferencias de registro entre establecimientos de similar complejidad.
IR_29301_PESO), Severidad
(IR_29301_SEVERIDAD) y Días de Estancia. El objetivo
descriptivo será identificar perfiles institucionales para clasificar
los centros de salud en tipologías de eficiencia hospitalaria,
permitiendo detectar aquellos recintos que, ante el mismo nivel de
severidad en pacientes con H25, incurren en estancias prolongadas
atípicas.En el desarrollo de este informe se utilizó Gemini AI con el propósito de optimizar el código en R para el procesamiento eficiente de macrodatos, la parametrización de variables dinámicas y la maquetación estructural en RMarkdown.
Verificación de resultados: Todo el código generado fue ejecutado y auditado localmente por el autor, verificando paso a paso que la lógica de filtrado y los cálculos estadísticos coincidieran estrictamente con el diccionario oficial del GRD 2024 de FONASA y que los conteos de la cohorte concordaran algebraicamente.
Base de datos principal: Base Pública de Grupos Relacionados por el Diagnóstico (GRD) 2024, Fondo Nacional de Salud (FONASA), Gobierno de Chile.
Fecha de extracción de los datos: 11 de Septiembre de 2026.
Tablas auxiliares y diccionarios: Diccionario de Variables GRD 2024 y Clasificación Internacional de Enfermedades, Décima Revisión (CIE-10) de la Organización Mundial de la Salud (OMS).