#ANÁLISIS DEL AUSENTISMO EN CITAS MÉDICAS ## Base: Medical Appointment No-Show (Brasil) ##Enfoque: MODELO EXPLICATIVO

#Introducción#

##El ausentismo a citas médicas (“no-show”) es un fenómeno que afecta la eficiencia operativa, la asignación de recursos y los costos del sistema sanitario. La base de datos Medical Appointment No-Show (Brasil) contiene información de 110.526 citas,incluyendo características del paciente, fechas relacionadas con la cita, envío de recordatorios SMS y si el paciente asistió.El propósito de este análisis es comprender cuáles factores influyen en el ausentismo mediante modelosde regresión logística.

#Pregunta de investigación

##¿Cuáles son los factores socioeconómicos, demográficos y clínicos que determinan la probabilidad de inasistencia a las citas médicas en la población usuaria del sistema de salud de Brasil?

#Cargue de librerias requeridas para el análisis y exploración de datos
library(readxl)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
library(janitor)
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
library(skimr)
library(tidyr)
library(plotly)
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
library(lmtest)
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
library(sandwich)
library(car)
## Loading required package: carData
## 
## Attaching package: 'car'
## The following object is masked from 'package:dplyr':
## 
##     recode
library(pscl)
## Classes and Methods for R originally developed in the
## Political Science Computational Laboratory
## Department of Political Science
## Stanford University (2002-2015),
## by and under the direction of Simon Jackman.
## hurdle and zeroinfl functions by Achim Zeileis.
library(pROC)
## Type 'citation("pROC")' for a citation.
## 
## Attaching package: 'pROC'
## The following objects are masked from 'package:stats':
## 
##     cov, smooth, var

#1.Exploración Analítica de Datos

#Carga de Base de Ausentismo
library(readxl)
BASE_AUSENTISMO <- read_excel("C:/Users/lizet/Documents/BASE AUSENTISMO.xlsx")
## New names:
## • `` -> `...6`
View(BASE_AUSENTISMO)

datos<- BASE_AUSENTISMO
str(datos)
## tibble [110,526 × 15] (S3: tbl_df/tbl/data.frame)
##  $ ID del paciente                                         : num [1:110526] 2.99e+13 5.59e+14 4.26e+12 8.68e+11 8.84e+12 ...
##  $ ID de la cita médica                                    : num [1:110526] 5642903 5642503 5642549 5642828 5642494 ...
##  $ Género                                                  : chr [1:110526] "F" "M" "F" "F" ...
##  $ Fecha en que se agendó la cita                          : chr [1:110526] "2016-04-29" "2016-04-29" "2016-04-29" "2016-04-29" ...
##  $ Fecha de la cita                                        : chr [1:110526] "2016-04-29" "2016-04-29" "2016-04-29" "2016-04-29" ...
##  $ ...6                                                    : num [1:110526] 0 0 0 0 0 -2 -2 -2 0 -2 ...
##  $ Edad                                                    : num [1:110526] 62 56 62 8 56 76 23 39 21 19 ...
##  $ Barrio / localidad                                      : chr [1:110526] "JARDIM DA PENHA" "JARDIM DA PENHA" "MATA DA PRAIA" "PONTAL DE CAMBURI" ...
##  $ Subsidio / beca social (bolsa familia)                  : num [1:110526] 0 0 0 0 0 0 0 0 0 0 ...
##  $ Hipertensión                                            : num [1:110526] 1 0 0 0 1 1 0 0 0 0 ...
##  $ Diabetes                                                : num [1:110526] 0 0 0 0 1 0 0 0 0 0 ...
##  $ Alcoholismo                                             : num [1:110526] 0 0 0 0 0 0 0 0 0 0 ...
##  $ Discapacidad                                            : num [1:110526] 0 0 0 0 0 0 0 0 0 0 ...
##  $ SMS recibido (0 = no, 1 = sí)                           : num [1:110526] 0 0 0 0 0 0 0 0 0 0 ...
##  $ No asistencia a la cita (Yes = no asistió, No = asistió): chr [1:110526] "No" "No" "No" "No" ...
summary(datos)
##  ID del paciente     ID de la cita médica    Género         
##  Min.   :3.922e+04   Min.   :5030230      Length:110526     
##  1st Qu.:4.173e+12   1st Qu.:5640285      Class :character  
##  Median :3.173e+13   Median :5680572      Mode  :character  
##  Mean   :1.475e+14   Mean   :5675304                        
##  3rd Qu.:9.439e+13   3rd Qu.:5725523                        
##  Max.   :1.000e+15   Max.   :5790484                        
##  Fecha en que se agendó la cita Fecha de la cita        ...6        
##  Length:110526                  Length:110526      Min.   :-179.00  
##  Class :character               Class :character   1st Qu.: -15.00  
##  Mode  :character               Mode  :character   Median :  -4.00  
##                                                    Mean   : -10.18  
##                                                    3rd Qu.:   0.00  
##                                                    Max.   :   6.00  
##       Edad        Barrio / localidad Subsidio / beca social (bolsa familia)
##  Min.   :  0.00   Length:110526      Min.   :0.00000                       
##  1st Qu.: 18.00   Class :character   1st Qu.:0.00000                       
##  Median : 37.00   Mode  :character   Median :0.00000                       
##  Mean   : 37.09                      Mean   :0.09827                       
##  3rd Qu.: 55.00                      3rd Qu.:0.00000                       
##  Max.   :115.00                      Max.   :1.00000                       
##   Hipertensión       Diabetes        Alcoholismo      Discapacidad    
##  Min.   :0.0000   Min.   :0.00000   Min.   :0.0000   Min.   :0.00000  
##  1st Qu.:0.0000   1st Qu.:0.00000   1st Qu.:0.0000   1st Qu.:0.00000  
##  Median :0.0000   Median :0.00000   Median :0.0000   Median :0.00000  
##  Mean   :0.1972   Mean   :0.07187   Mean   :0.0304   Mean   :0.02225  
##  3rd Qu.:0.0000   3rd Qu.:0.00000   3rd Qu.:0.0000   3rd Qu.:0.00000  
##  Max.   :1.0000   Max.   :1.00000   Max.   :1.0000   Max.   :4.00000  
##  SMS recibido (0 = no, 1 = sí)
##  Min.   :0.000                
##  1st Qu.:0.000                
##  Median :0.000                
##  Mean   :0.321                
##  3rd Qu.:1.000                
##  Max.   :1.000                
##  No asistencia a la cita (Yes = no asistió, No = asistió)
##  Length:110526                                           
##  Class :character                                        
##  Mode  :character                                        
##                                                          
##                                                          
## 
dim(datos)
## [1] 110526     15
colSums(is.na(datos))
##                                          ID del paciente 
##                                                        0 
##                                     ID de la cita médica 
##                                                        0 
##                                                   Género 
##                                                        0 
##                           Fecha en que se agendó la cita 
##                                                        0 
##                                         Fecha de la cita 
##                                                        0 
##                                                     ...6 
##                                                        0 
##                                                     Edad 
##                                                        0 
##                                       Barrio / localidad 
##                                                        0 
##                   Subsidio / beca social (bolsa familia) 
##                                                        0 
##                                             Hipertensión 
##                                                        0 
##                                                 Diabetes 
##                                                        0 
##                                              Alcoholismo 
##                                                        0 
##                                             Discapacidad 
##                                                        0 
##                            SMS recibido (0 = no, 1 = sí) 
##                                                        0 
## No asistencia a la cita (Yes = no asistió, No = asistió) 
##                                                        0

Se identifican variables categoricas y numericas, lo que permite un análisis descriptivo e inferencial ##Análisis Estadístico Descriptivo

summary(datos$Edad)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    0.00   18.00   37.00   37.09   55.00  115.00
mean(datos$Edad)
## [1] 37.08922
median(datos$Edad)
## [1] 37
sd(datos$Edad)
## [1] 23.11003
table(datos$Género)
## 
##     F     M 
## 71839 38687
prop.table(table(datos$Género))
## 
##         F         M 
## 0.6499738 0.3500262
table(datos$`No asistencia a la cita (Yes = no asistió, No = asistió)`)
## 
##    No   Yes 
## 88207 22319
prop.table(table(datos$`No asistencia a la cita (Yes = no asistió, No = asistió)`))
## 
##        No       Yes 
## 0.7980656 0.2019344
table(datos$`SMS recibido (0 = no, 1 = sí)`)
## 
##     0     1 
## 75044 35482
prop.table(table(datos$`SMS recibido (0 = no, 1 = sí)`))
## 
##         0         1 
## 0.6789715 0.3210285

La población en su mayoria es adulta, con una media y mediana de distribución simétricas, con una desviación estándar que indica alta heterogenidad etaria. Además hay una distribución del sexo equilibrada.Respecto a la consultas la mayoria de pacientes asistió, no obstante hay una proporción relevante de inasistencia. Así mismo es importante que el 67% de los pacientes no recibieron confirmación vía SMS.

#TABLA DE FRECUENCIAS PARA AUSENTISMO
tabla_abs <- table(datos$`No asistencia a la cita (Yes = no asistió, No = asistió)`)      
tabla_rel <- prop.table(tabla_abs)               
tabla_acum <- cumsum(tabla_rel)

# Unir todo en una sola tabla#
tabla_frecuencias <- data.frame(
  Categoria = names(tabla_abs),
  Frecuencia_Absoluta   = as.vector(tabla_abs),
  Frecuencia_Relativa   = round(as.vector(tabla_rel), 4),
  Frecuencia_Acumulada  = round(as.vector(tabla_acum), 4)
)
View(tabla_frecuencias)

##Visualización Gráfica de datos

# 6.1 Histograma dinámico de Edad#
g1 <- ggplot(datos, aes(x = Edad)) +
  geom_histogram(binwidth = 5, fill = "steelblue", color = "black") +
  labs(title = "Distribución de la edad",
       x = "edad",
       y = "Frecuencia")

ggplotly(g1)
#Ausentismo por Género
g2 <-  ggplot(datos, aes(x = Género, fill = `No asistencia a la cita (Yes = no asistió, No = asistió)`)) +
  geom_bar(position = "dodge") +
  labs(title = "Ausentismo por Género",
       x = "Género",
       y = "Conteo")

ggplotly(g2)
#Días de espera vs Ausentismo
#Creación Variable#
fecha_programada <-datos$`Fecha en que se agendó la cita`
fecha_cita <- datos$`Fecha de la cita`

datos <- datos %>%
  mutate( dias_espera = as.numeric(difftime(fecha_cita, fecha_programada, units = "days")),
  ausentismo_bin = ifelse(`No asistencia a la cita (Yes = no asistió, No = asistió)` == "Yes", 1, 0),
  genero_f = ifelse(Género == "F", 1, 0)) %>% filter(!is.na(dias_espera), Edad >= 0)

g3 <- ggplot(datos, aes(x =`No asistencia a la cita (Yes = no asistió, No = asistió)` , y = dias_espera, fill = `No asistencia a la cita (Yes = no asistió, No = asistió)`)) +
  geom_boxplot() +
  labs(title = "Días de Espera según Ausentismo",
       x = "Ausentismo",
       y = "Días de espera")

ggplotly(g3)
# Condiciones de salud y ausentismo 
variables_salud <- datos %>%
  select(`No asistencia a la cita (Yes = no asistió, No = asistió)`, Hipertensión, Diabetes, Alcoholismo, Discapacidad) %>%
  pivot_longer(cols = -`No asistencia a la cita (Yes = no asistió, No = asistió)`,
               names_to = "condicion",
               values_to = "valor")

g4 <- ggplot(variables_salud, aes(x = valor, fill = `No asistencia a la cita (Yes = no asistió, No = asistió)`)) +
  geom_bar(position = "dodge") +
  facet_wrap(~ condicion, scales = "free") +
  labs(title = "Condiciones de Salud y Ausentismo",
       x = "Condición",
       y = "Frecuencia")

ggplotly(g4)
#SMS RECIBIDO VS NO ASISTENCIA#
tabla_sms <- table(datos$`SMS recibido (0 = no, 1 = sí)`,
                   datos$`No asistencia a la cita (Yes = no asistió, No = asistió)`)

prop.table(tabla_sms, margin = 1)
##    
##            No       Yes
##   0 0.8329647 0.1670353
##   1 0.7242546 0.2757454
#Los pacientes que recibieron SMS presentaron menor porcentaje de inasistencia, es decir que el SMS funciona como medio preventivo#

g5<-barplot(tabla_sms,
        beside = TRUE,
        col = c("orange", "darkgreen"),
        legend = TRUE,
        main = "SMS recibido vs No asistencia",
        ylab = "Cantidad")

Los pacientes que recibieron SMS presentaron menor porcentaje de inasistencia, es decir que el SMS funciona como medio preventivo.

#MODELO EXPLICATIVO DE REGRESIÓN LOGÍSTICA

# Convertir variable dependiente a binaria
datos$inasistencia <- ifelse(
  datos$`No asistencia a la cita (Yes = no asistió, No = asistió)` == "Yes", 1, 0
)
modelo_explicativo <- glm(
  inasistencia ~ dias_espera + `SMS recibido (0 = no, 1 = sí)` +
    `Subsidio / beca social (bolsa familia)` + Edad + genero_f + Hipertensión,
  data = datos,
  family = binomial(link = "logit")
)

summary(modelo_explicativo)
## 
## Call:
## glm(formula = inasistencia ~ dias_espera + `SMS recibido (0 = no, 1 = sí)` + 
##     `Subsidio / beca social (bolsa familia)` + Edad + genero_f + 
##     Hipertensión, family = binomial(link = "logit"), data = datos)
## 
## Coefficients:
##                                            Estimate Std. Error z value Pr(>|z|)
## (Intercept)                              -1.5309923  0.0182608 -83.840   <2e-16
## dias_espera                               0.0228563  0.0004855  47.082   <2e-16
## `SMS recibido (0 = no, 1 = sí)`           0.3513343  0.0168532  20.847   <2e-16
## `Subsidio / beca social (bolsa familia)`  0.2344195  0.0246949   9.493   <2e-16
## Edad                                     -0.0074695  0.0003939 -18.964   <2e-16
## genero_f                                  0.0050418  0.0163610   0.308    0.758
## Hipertensión                             -0.0009852  0.0233303  -0.042    0.966
##                                             
## (Intercept)                              ***
## dias_espera                              ***
## `SMS recibido (0 = no, 1 = sí)`          ***
## `Subsidio / beca social (bolsa familia)` ***
## Edad                                     ***
## genero_f                                    
## Hipertensión                                
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 111205  on 110525  degrees of freedom
## Residual deviance: 106801  on 110519  degrees of freedom
## AIC: 106815
## 
## Number of Fisher Scoring iterations: 4

#Interpretación del modelo

Para este modelo, se realizó una regresión logística para explicar la probabilidad de ausentismo a las citas médicas,esto en función de variables socioeconómicas, demográficas y de acceso a sus servicios. En cuanto a los valores de los interceptos, este modelo nos dice que: Cada día adicional de espera para asistir a la cita, incrementa la probabilidad de no asistir a la misma.Para la variable de mensajería, es importante resaltar que esta no se relaciona de forma directa, es decir no puede decirse si incrementa o disminuye el ausentismo. De esto se puede concluir que , el mensaje podría estar dirigido a usuarios con mayor riesgo de ausentismo (efecto de selección), O bien, el mensaje no es suficiente para reducir el ausentismo y se asocia a contextos de mayor incumplimiento. Las personas que reciben subsidio presentan mayor probabilidad de ausentismo frente a quienes no lo reciben. Para la variable de subsidio, el modelo sugiere que condiciones socioeconómicas más vulnerables pueden estar asociadas a mayores dificultades para cumplir con la asistencia (transporte, trabajo informal, cuidados familiares, etc.).Para la variable edad, esta tiene un efecto negativo y significativo, es decir que a medida que aumenta la edad, disminuye ligeramente la probabilidad de ausentismo, lo que indica que los usuarios más jóvenes tienden a ausentarse más que los de mayor edad. Para las variables de género e hipertensión estas no son significativas y no explican el ausentismo. En conclusión, las variables que logran explicar el ausentismo son los dias de espera, la mensajería, el subsidio y la edad, lo que puede indicar que el ausentismo está más relacionado con factores operativos y socioeconómicos que con condiciones clínicas.

#Diagnóstico del Modelo

coeftest(
  modelo_explicativo,
  vcov = vcovHC(modelo_explicativo, type = "HC1")
)
## 
## z test of coefficients:
## 
##                                             Estimate  Std. Error  z value
## (Intercept)                              -1.53099226  0.01775466 -86.2304
## dias_espera                               0.02285625  0.00053389  42.8108
## `SMS recibido (0 = no, 1 = sí)`           0.35133432  0.01775491  19.7880
## `Subsidio / beca social (bolsa familia)`  0.23441948  0.02451763   9.5613
## Edad                                     -0.00746947  0.00038559 -19.3715
## genero_f                                  0.00504176  0.01640472   0.3073
## Hipertensión                             -0.00098516  0.02341706  -0.0421
##                                          Pr(>|z|)    
## (Intercept)                                <2e-16 ***
## dias_espera                                <2e-16 ***
## `SMS recibido (0 = no, 1 = sí)`            <2e-16 ***
## `Subsidio / beca social (bolsa familia)`   <2e-16 ***
## Edad                                       <2e-16 ***
## genero_f                                   0.7586    
## Hipertensión                               0.9664    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Interpretación: como se realiza un modelo LOGIT,no se aume supuestos como la homocedasticidad, por lo que se usan los errores robustos del modelo, lo anterior para saber si las conclusiones hechas previamente son validas o no. Al realizar este nuevo modelo, se observa que efectivamente las variables que fueron significativas en el modelo anterior, siguen siendo significativas, por lo que si se pueden tomar como variables explicativas del modelo.

# Multicolinealidad
vif(modelo_explicativo)
##                              dias_espera 
##                                 1.170017 
##          `SMS recibido (0 = no, 1 = sí)` 
##                                 1.161033 
## `Subsidio / beca social (bolsa familia)` 
##                                 1.027793 
##                                     Edad 
##                                 1.370382 
##                                 genero_f 
##                                 1.033796 
##                             Hipertensión 
##                                 1.336360

Se corre la prueba vif para revisar si hay presencia de multicolinealidad en el modelo, los resultados del test VIF nos arroja valores cercanos a 1, lo que indica que hay ausencia de este problema.

# Pseudo R² de McFadden
pR2(modelo_explicativo)["McFadden"]
## fitting null model for pseudo-r2
##   McFadden 
## 0.03960274

Al evaluar cuanto mejora el modelo con predictores que uno sin predictores, se interpreta el Pseudo R2, que nos quiere decir que El modelo mejora en aproximadamente un 4% la credibilidad respecto al modelo nulo, lo cual es razonable y esperado en modelos explicativos con datos de salud.

# Curva ROC y AUC
roc_obj <- roc(datos$ausentismo_bin, fitted(modelo_explicativo))
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
auc(roc_obj)
## Area under the curve: 0.6607
g6<-plot.roc(roc_obj,print.auc=T,print.thres = "best",
         col="blue",xlab="1-ESpecificidad",ylab="Sensibilidad")

También se evalua la capacidad predictiva del modelo usando la curva ROC y el AUC, si bien el modelo es de carácter explicativo, es importante saber si el modelo si discrimina de forma correcta entre casos con ausentismo y casos de no ausentismo.Los resultados muestran que el AUC obtenido fue de 0.661, lo que indica que el modelo discrimina mejor que el azar, aunque con una capacidad moderada. Esto se espera dado que el objetivo del modelo es explicativo y no predictivo, y que el ausentismo es un fenómeno influido por múltiples factores no observados.

#Conclusiones Finales Respecto al modelo de regresión logística, este permitió identificar los principales factores socioeconómicos y operativos asociados a la inasistencia a las citas médicas en la población usuaria del sistema de salud de Brasil. Los resultados muestran que un mayor número de días de espera incrementa la probabilidad de ausentismo, al igual que la pertenencia a programas de subsidio social, lo que sugiere la presencia de barreras estructurales que dificultan la asistencia. Asimismo, la recepción de mensajes SMS se asocia al ausentismo, lo cual indica que los recordatorios no tienen un efecto homogéneo en todos los grupos poblacionales. En conjunto, estos hallazgos evidencian que el ausentismo no depende únicamente de factores clínicos, sino que está fuertemente influenciado por condiciones socioeconómicas y de gestión del servicio.

Como proceso de inferencia se podrían hacer algunas recomendaciones enfocadas en acciones que ayuden a reducir los factores que incrementan el ausentismo. En particular, es fundamental optimizar los tiempos de espera mediante procesos de agendamiento más ágiles y flexibles. Adicionalmente, se sugiere fortalecer los sistemas de recordatorio mediante el uso combinado de SMS, WhatsApp y llamadas telefónicas, priorizando a los usuarios con mayor riesgo de inasistencia. Finalmente, se recomienda establecer alertas tempranas que permitan identificar patrones de ausentismo y desarrollar estrategias educativas que promuevan la importancia de asistir a las citas médicas, contribuyendo a mejorar la eficiencia del sistema de salud, al reducir la pérdida de recursos asociados a citas no atendidas y fortalecer la continuidad en la atención de los usuarios.