Exploración Analítica de Datos (EDA)

Carga de Datos y Estructura General

Este primer bloque carga las herramientas necesarias y la base de datos, mostrando cómo están organizadas las columnas y qué tipo de información (texto, números, fechas) contiene cada una.

# Cargar las librerías necesarias
library(readr)   # Para leer el archivo CSV
library(dplyr)   # Para manipular y explorar los datos
library(ggplot2) # Para crear gráficos
library(plotly)  # Para hacer los gráficos interactivos

# Cargar la base de datos (el archivo 'Appointments.csv' debe estar en la misma carpeta que tu archivo R Markdown)
datos_citas <- read_csv("Appointments.csv")

# Revisar la estructura interna de los datos (tipos de variables y primeros registros)
glimpse(datos_citas)
## Rows: 111,488
## Columns: 16
## $ appointment_id       <chr> "0000138", "0000146", "0000021", "0000233", "0000…
## $ slot_id              <chr> "0000001", "0000023", "0000024", "0000025", "0000…
## $ scheduling_date      <date> 2014-12-28, 2014-12-29, 2014-12-17, 2014-12-31, …
## $ appointment_date     <date> 2015-01-01, 2015-01-01, 2015-01-01, 2015-01-01, …
## $ appointment_time     <time> 08:00:00, 13:30:00, 13:45:00, 14:00:00, 14:15:00…
## $ scheduling_interval  <dbl> 4, 3, 15, 1, 6, 2, 2, 2, 4, 4, 4, 1, 1, 7, 3, 2, …
## $ status               <chr> "did not attend", "did not attend", "attended", "…
## $ check_in_time        <time>       NA,       NA, 13:36:45, 13:59:32,       NA…
## $ appointment_duration <dbl> NA, NA, 5.2, 28.9, NA, 7.7, 4.2, 27.1, NA, 1.2, 7…
## $ start_time           <time>       NA,       NA, 13:37:57, 14:00:40,       NA…
## $ end_time             <time>       NA,       NA, 13:43:09, 14:29:34,       NA…
## $ waiting_time         <dbl> NA, NA, 1.2, 1.1, NA, 21.7, 16.2, 1.0, NA, 8.5, 2…
## $ patient_id           <chr> "08285", "05972", "06472", "05376", "08028", "043…
## $ sex                  <chr> "Male", "Male", "Male", "Female", "Male", "Female…
## $ age                  <dbl> 37, 84, 77, 37, 72, 51, 28, 33, 29, 90, 66, 64, 3…
## $ age_group            <chr> "35-39", "80-84", "75-79", "35-39", "70-74", "50-…

Comentario analítico: La función glimpse permite verificar que RStudio haya interpretado correctamente variables como scheduling_date como fechas (Date) y appointment_duration como números decimales (Float/Double). Esto es vital en gestión sanitaria para evitar errores al cruzar tiempos de espera o duraciones de consulta.

Identificación de Datos Faltantes (Valores Nulos)

Antes de visualizar, es necesario saber si la base de datos está completa o si hay registros vacíos.

# Contar cuántos valores nulos (datos que faltan o están en blanco) hay en cada columna
colSums(is.na(datos_citas))
##       appointment_id              slot_id      scheduling_date 
##                    0                    0                    0 
##     appointment_date     appointment_time  scheduling_interval 
##                    0                    0                    0 
##               status        check_in_time appointment_duration 
##                    0                25456                25456 
##           start_time             end_time         waiting_time 
##                25456                25456                25456 
##           patient_id                  sex                  age 
##                    0                    0                    0 
##            age_group 
##                    0

Comentario analítico: En el agendamiento médico, identificar variables con alta cantidad de valores nulos (por ejemplo, check_in_time en citas que fueron canceladas) permite entender fallos en el registro de datos o confirmar el comportamiento lógico del sistema de citas (un paciente que no asiste no debería tener tiempo de llegada).

Verificación del estado de las citas con datos nulos

Este bloque de código filtra únicamente los registros que no tienen hora de llegada y cuenta en qué estado (status) se encuentran, lo que nos confirmará por qué están vacíos.

# Contar el estado de la cita (status) solo para aquellos registros donde la hora de llegada es nula
verificacion_nulos <- datos_citas %>%
  filter(is.na(check_in_time)) %>%
  count(status, name = "cantidad_citas")

# Mostrar el resultado en pantalla
print(verificacion_nulos)
## # A tibble: 4 × 2
##   status         cantidad_citas
##   <chr>                   <int>
## 1 cancelled               18254
## 2 did not attend           6615
## 3 scheduled                 141
## 4 unknown                   446

Comentario analítico para el documento: Al cruzar los valores nulos con la variable de estado, se comprueba que la ausencia de datos en los tiempos de atención obedece a factores operativos normales (cancelaciones e inasistencias) y no a un error en la captura de información del software del hospital. Esto garantiza que la base de datos es confiable para tomar decisiones sobre capacidad instalada.

Visualización Interactiva de Variables Clave

Gráfico A: Estado de las Citas Permite visualizar el volumen de citas según su desenlace (completadas, canceladas, no asistencias).

# Crear el gráfico base
grafico_estado <- ggplot(datos_citas, aes(x = status, fill = status)) +
  geom_bar() +
  theme_minimal() +
  labs(title = "Volumen de Citas por Estado",
       x = "Estado de la Cita",
       y = "Cantidad Total") +
  theme(legend.position = "none")

# Convertir el gráfico a formato interactivo
ggplotly(grafico_estado)

Comentario analítico: Al pasar el cursor sobre las barras, se observa la cantidad exacta de citas por categoría. Desde la perspectiva de gerencia de recursos, una alta proporción de estados ‘cancelled’ (canceladas) o ‘no-show’ (no asistencias) indica una pérdida de capacidad instalada que requiere intervención administrativa.

El gráfico evidencia que la gran mayoría de las citas programadas logran completarse exitosamente (attended), lo que refleja una base operativa sólida en la institución. Desde una perspectiva de gerencia sanitaria, la distribución de los datos revela patrones críticos sobre la eficiencia del sistema de reservas:

Alta efectividad del servicio: La barra de mayor volumen (attended) domina ampliamente la distribución, indicando que el flujo principal de pacientes asiste a su consulta. Esto asegura el retorno de inversión de la capacidad médica dispuesta.

Impacto operativo de las cancelaciones: La categoría cancelled es el segundo estado más frecuente. Aunque representa un reproceso administrativo, el hecho de que el paciente notifique la cancelación brinda a la institución la oportunidad de implementar estrategias de reasignación rápida (listas de espera dinámicas) para no perder el espacio en la agenda.

Costo de oportunidad por inasistencias: El grupo did not attend (no asistencias), aunque menor que las cancelaciones, es el indicador más crítico para la gerencia. Estas ausencias sin previo aviso se traducen directamente en capacidad instalada ociosa (médicos y consultorios inactivos) y pérdida financiera irrecuperable.

Naturaleza retrospectiva de los datos: Las categorías scheduled (citas futuras) y unknown (estado desconocido) tienen un volumen casi nulo en comparación con el resto. Esto confirma que la base de datos funciona principalmente como un registro histórico de eventos ya concluidos y depurados, ideal para analizar el comportamiento pasado del agendamiento.

Gráfico B: Distribución de Pacientes por Grupo de Edad y Sexo Muestra cómo se compone la demanda de los servicios sanitarios según las características demográficas de los pacientes.

# Filtrar posibles datos vacíos en sexo o grupo de edad y crear el gráfico
grafico_demografico <- datos_citas %>%
  filter(!is.na(sex) & !is.na(age_group)) %>%
  ggplot(aes(x = age_group, fill = sex)) +
  geom_bar(position = "dodge") +
  theme_minimal() +
  labs(title = "Demanda de Citas por Grupo de Edad y Sexo",
       x = "Grupo de Edad",
       y = "Número de Citas",
       fill = "Sexo") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Convertir el gráfico a formato interactivo
ggplotly(grafico_demografico)

Comentario analítico: Este gráfico de barras agrupadas permite comparar visualmente si ciertos grupos de edad (por ejemplo, adultos mayores) consumen más recursos médicos y si existe una predominancia de un género sobre otro en la solicitud de citas. Esto es útil para enfocar campañas de prevención en Seguridad y Salud.

El gráfico de barras muestra la distribución de la demanda de citas médicas segmentada por grupo de edad y sexo del paciente. El análisis de esta distribución revela varias dinámicas operativas relevantes para la gestión en salud: Predominancia femenina en etapas reproductivas y productivas: Se observa una brecha muy marcada entre el volumen de citas de mujeres (barras rojas) y hombres (barras azules) en los rangos de edad de 20 a 49 años. El pico máximo de demanda de toda la gráfica se encuentra en las mujeres de 30-34 años, seguido por las de 35-39 años. Esta alta frecuencia suele asociarse a programas de salud materno-infantil, controles ginecológicos y una mayor búsqueda temprana de atención médica preventiva por parte de las mujeres. Cierre de la brecha de género en la tercera edad: A partir de los 60 años, la diferencia en el volumen de consultas entre hombres y mujeres se reduce drásticamente, igualándose casi por completo en los grupos de 65-69 y posteriores. Esto indica que, en edades avanzadas, la carga de morbilidad (probablemente enfermedades crónicas no transmisibles) afecta de manera similar a ambos sexos, impulsando una alta demanda compartida de servicios de salud. Baja demanda en jóvenes: El volumen más bajo de citas (excluyendo a los mayores de 90 años) se encuentra en el rango de 15 a 19 años para ambos sexos. Desde la perspectiva de gerencia en Seguridad y Salud, esta información es útil para asignar recursos de manera eficiente; por ejemplo, asegurar mayor disponibilidad de especialistas y programas preventivos enfocados en la salud femenina en edades medias, y preparar una sólida capacidad instalada para el manejo de patologías crónicas en la población adulta mayor de ambos sexos.

Gráfico C: Frecuencia del Intervalo de Agendamiento Visualiza la variable scheduling_interval para entender con cuánta anticipación se programan las citas.

# Crear un histograma (gráfico que agrupa rangos numéricos continuos) para los intervalos de programación
grafico_intervalo <- ggplot(datos_citas, aes(x = scheduling_interval)) +
  geom_histogram(binwidth = 5, fill = "red", color = "black") +
  theme_minimal() +
  labs(title = "Días de Anticipación en el Agendamiento",
       x = "Días entre Programación y Cita",
       y = "Frecuencia (Número de Citas)")

# Convertir el gráfico a formato interactivo
ggplotly(grafico_intervalo)

Comentario analítico: Este gráfico revela el comportamiento temporal de los pacientes. Una concentración alta cerca del cero indica que las citas se programan el mismo día o con muy pocos días de anticipación, lo cual impacta directamente en la planificación del personal médico y administrativo.

El histograma ilustra la distribución del tiempo de anticipación con el que los pacientes reservan sus citas médicas en la institución. El análisis de este comportamiento revela dinámicas clave sobre cómo interactúa la demanda con la oferta de servicios: Concentración de agendamiento a corto plazo: La inmensa mayoría de las citas se programan con un margen menor a 10 días. El pico máximo de frecuencia, que supera las 40.000 citas, se ubica en el intervalo cercano a los 5 días de anticipación. Además, existe un volumen considerable (cerca de 28.000 citas) en el primer bloque del gráfico, lo que representa consultas agendadas para el mismo día o el día inmediatamente siguiente. Caída progresiva a mediano plazo: A medida que se incrementan los días de anticipación (15, 20, 30 días), la cantidad de citas disminuye de manera drástica. Las reservas con un mes de antelación son prácticamente nulas en comparación con el volumen total. Implicación para la Gerencia en Salud:Este comportamiento indica que el sistema opera principalmente bajo una dinámica de demanda inmediata. Esto puede obedecer a dos razones operativas: los pacientes buscan atención médica principalmente para resolver problemas de salud recientes (agudos) en lugar de programar controles preventivos a largo plazo, o bien, las agendas institucionales limitan la posibilidad de agendar con mucha antelación. Este escenario requiere una alta flexibilidad administrativa, ya que la gerencia debe ajustar la capacidad instalada (personal médico e infraestructura) de forma constante, dado que el volumen real de pacientes se concreta con muy poco tiempo de aviso.

Las 28.630 citas que se reflejan en la primera barra del histograma (en la zona del 0) corresponden a citas programadas el mismo día de la atención médica.

En términos operativos hospitalarios, esto significa que el paciente solicitó la cita (fecha de agendamiento) y fue atendido (fecha de la cita) exactamente en la misma fecha calendario, por lo que la diferencia en días entre ambos eventos es cero.

Desde la gerencia, este volumen tan alto de citas de “mismo día” suele asociarse a atenciones prioritarias, urgencias de baja complejidad, o pacientes que acuden presencialmente al centro de salud (“walk-ins”) y se les asigna el primer espacio disponible en la agenda del día.