author: “Leidy Gil y Mayra Bolivar” output: flexdashboard::flex_dashboard: orientation: rows vertical_layout: fill theme: flatly social: menu source_code: embed





---
title: "Análisis de citas para la gestión sanitaria"
output:
  flexdashboard::flex_dashboard:
    orientation: rows
    vertical_layout: fill
    theme: cosmo
---



``` r
library(dplyr)
library(ggplot2)
library(plotly)
library(flexdashboard)
library(ggrepel)
library(scales)

# Importar la base de datos
archivo <- readLines("Appointments.csv")

# Corregir las comillas externas
archivo <- sub('^"', '', archivo)
archivo <- sub('"$', '', archivo)

# Leer correctamente los datos
appointments <- read.csv(
  text = archivo,
  header = TRUE,
  sep = ",",
  stringsAsFactors = FALSE
)

# Preparar las variables
appointments$appointment_date <- as.Date(
  appointments$appointment_date
)

appointments$waiting_time <- as.numeric(
  appointments$waiting_time
)

appointments$age <- as.numeric(
  appointments$age
)

# Filtrar las citas atendidas
atendidas <- appointments %>%
  filter(status == "attended")

Gráfico 1. Comportamiento de las citas según su estado

estados <- appointments %>%
  count(status, name = "total") %>%
  arrange(desc(total))

ggplot(estados, aes(x = reorder(status, total),
                    y = total, fill = status)) +
  geom_col() +
  geom_text_repel(
    aes(label = comma(total)),
    size = 3.5
  ) +
  scale_fill_brewer(palette = "Set2") +
  coord_flip() +
  labs(
    title = "Estado de las citas médicas",
    subtitle = "Distribución de 111.488 registros",
    x = "Estado de la cita",
    y = "Número de citas",
    fill = "Estado"
  ) +
  theme_minimal() +
  theme(legend.position = "none")

Grafico 2: análisis del tiempo de espera por grupo de edad

espera_edad <- appointments %>%
  filter(
    status == "attended",
    !is.na(age_group),
    !is.na(waiting_time)
  ) %>%
  group_by(age_group) %>%
  summarise(
    espera_promedio = mean(waiting_time, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  arrange(espera_promedio)

# Mostrar resultados
print(espera_edad)
## # A tibble: 16 × 2
##    age_group espera_promedio
##    <chr>               <dbl>
##  1 65-69                43.0
##  2 15-19                43.1
##  3 20-24                43.4
##  4 70-74                43.4
##  5 80-84                43.4
##  6 60-64                43.5
##  7 45-49                44.2
##  8 40-44                44.3
##  9 30-34                44.3
## 10 55-59                44.4
## 11 75-79                44.5
## 12 25-29                44.5
## 13 35-39                44.6
## 14 90+                  44.7
## 15 50-54                44.9
## 16 85-89                45.4
# Construir gráfico
ggplot(
  espera_edad,
  aes(x = age_group, y = espera_promedio)
) +
  geom_col(fill = "#399A85") +
  geom_text(
    aes(label = round(espera_promedio, 1)),
    vjust = -0.5
  ) +
  labs(
    title = "Tiempo promedio de espera por grupo de edad",
    x = "Grupo de edad",
    y = "Tiempo de espera (minutos)"
  ) +
  theme_minimal()

Grafico 3: identificar los días de la semana con mayor volumen de citas

# Calcular las citas por día de la semana
citas_dia <- appointments %>%
  filter(!is.na(appointment_date)) %>%
  mutate(
    dia_semana = weekdays(appointment_date)
  ) %>%
  count(dia_semana, name = "numero_citas")

# Organizar los resultados
print(citas_dia)
##   dia_semana numero_citas
## 1     Friday        22350
## 2     Monday        22293
## 3   Thursday        22313
## 4    Tuesday        22342
## 5  Wednesday        22190
# Crear gráfico
ggplot(
  citas_dia,
  aes(x = dia_semana, y = numero_citas, fill = dia_semana)
) +
  geom_col() +
  geom_text(
    aes(label = numero_citas),
    vjust = -0.5,
    size = 3
  ) +
  scale_fill_brewer(palette = "Set2") +
  labs(
    title = "Distribución de citas por día de la semana",
    x = "Día de la semana",
    y = "Número de citas"
  ) +
  theme_minimal() +
  theme(legend.position = "none")

Grafico 4. identificar los grupos de edad con mayor tiempo de espera y volumen de citas

# Calcular tiempo promedio de espera por edad
espera_edad <- appointments %>%
  filter(
    status == "attended",
    !is.na(age_group),
    !is.na(waiting_time)
  ) %>%
  group_by(age_group) %>%
  summarise(
    espera_promedio = mean(waiting_time, na.rm = TRUE),
    total_citas = n(),
    .groups = "drop"
  ) %>%
  arrange(desc(espera_promedio))

# Mostrar resultados
print(espera_edad)
## # A tibble: 16 × 3
##    age_group espera_promedio total_citas
##    <chr>               <dbl>       <int>
##  1 85-89                45.4        4503
##  2 50-54                44.9        5830
##  3 90+                  44.7        2356
##  4 35-39                44.6        5708
##  5 25-29                44.5        4584
##  6 75-79                44.5        7659
##  7 55-59                44.4        6915
##  8 30-34                44.3        5810
##  9 40-44                44.3        4908
## 10 45-49                44.2        4718
## 11 60-64                43.5        7468
## 12 80-84                43.4        6265
## 13 70-74                43.4        7329
## 14 20-24                43.4        3024
## 15 15-19                43.1        1866
## 16 65-69                43.0        7089
# Gráfico
ggplot(
  espera_edad,
  aes(x = age_group, y = espera_promedio)
) +
  geom_col(fill = "#399A85") +
  geom_text(
    aes(label = round(espera_promedio, 1)),
    vjust = -0.5
  ) +
  labs(
    title = "Tiempo promedio de espera por grupo de edad",
    subtitle = "Análisis de citas atendidas",
    x = "Grupo de edad",
    y = "Tiempo promedio (minutos)"
  ) +
  theme_minimal()