---
title: "Análisis de Ocupación Hospitalaria"
author: "Diego Meza"
date: "2025-08-12"
output:
flexdashboard::flex_dashboard:
theme: flatly
social: menu
source_code: embed
orientation: rows
vertical_layout: fill
---
```{r setup, include=FALSE}
library(tidyverse)
library(lubridate)
library(plotly)
library(highcharter)
library(DT)
library(glue)
library(flexdashboard)
library(viridis)
library(shiny)
# Configuración global
options(scipen = 999)
# Carga y preparación de datos
camas <- readxl::read_excel("mapeo_camas_admision_base.xlsx", sheet = "base") %>%
mutate(
fecha = ymd(fecha),
semana = floor_date(fecha, "week"),
esalta = factor(esalta, levels = c("SÍ", "No"),
labels = c("Alta médica", "Paciente activo")),
viadealta = case_when(
viadealta == "No encontrado en listado" ~ "Registro inconsistente",
viadealta == "Sigue figurando en el sistema" ~ "Alta no procesada",
TRUE ~ viadealta
),
prioridad = ifelse(color_observacion == "rojo", "Alta prioridad", "Normal")
)
```
Filtros {.sidebar}
=====================================
```{r}
# Filtros interactivos
selectInput("servicio", "Seleccionar Servicio:",
choices = c("Todos", unique(camas$servicio)))
dateRangeInput("rango_fechas", "Rango de Fechas:",
start = min(camas$fecha),
end = max(camas$fecha))
checkboxGroupInput("tipo_alta", "Tipo de Alta:",
choices = c("Alta médica", "Paciente activo"),
selected = c("Alta médica", "Paciente activo"))
```
Tendencias Temporales
=====================================
Row
-----------------------------------------------------------------------
### Evolución diaria de registros
```{r}
renderHighchart({
req(input$rango_fechas)
df <- camas %>%
filter(fecha >= input$rango_fechas[1],
fecha <= input$rango_fechas[2],
esalta %in% input$tipo_alta)
if(input$servicio != "Todos") {
df <- df %>% filter(servicio == input$servicio)
}
df %>%
count(fecha, esalta) %>%
hchart("column", hcaes(x = fecha, y = n, group = esalta)) %>%
hc_title(text = "Registros Diarios por Estado") %>%
hc_colors(c("#FF6B6B", "#4ECDC4")) %>%
hc_xAxis(title = list(text = "Fecha")) %>%
hc_yAxis(title = list(text = "Número de Registros")) %>%
hc_exporting(enabled = TRUE)
})
```
### Proporción de altas médicas
```{r}
renderHighchart({
req(input$rango_fechas)
df <- camas %>%
filter(fecha >= input$rango_fechas[1],
fecha <= input$rango_fechas[2])
if(input$servicio != "Todos") {
df <- df %>% filter(servicio == input$servicio)
}
df %>%
count(fecha, esalta) %>%
group_by(fecha) %>%
mutate(prop = n/sum(n)*100) %>%
ungroup() %>%
filter(esalta == "Alta médica") %>%
hchart("line", hcaes(x = fecha, y = prop)) %>%
hc_title(text = "Porcentaje Diario de Altas Médicas") %>%
hc_colors("#1A535C") %>%
hc_yAxis(title = list(text = "% de Altas"), max = 100) %>%
hc_tooltip(valueSuffix = "%")
})
```
Análisis por Servicio
=====================================
Row
-----------------------------------------------------------------------
### Distribución por servicio médico
```{r}
renderPlotly({
req(input$rango_fechas)
df <- camas %>%
filter(fecha >= input$rango_fechas[1],
fecha <= input$rango_fechas[2],
esalta %in% input$tipo_alta)
if(input$servicio != "Todos") {
df <- df %>% filter(servicio == input$servicio)
}
df_sum <- df %>%
count(servicio, esalta) %>%
group_by(servicio) %>%
mutate(prop = n/sum(n)*100) %>%
ungroup() %>%
arrange(desc(n))
p <- ggplot(df_sum, aes(x = reorder(servicio, n),
y = n, fill = esalta,
text = paste0(servicio, "\n", n, " registros (", round(prop), "%)"))) +
geom_bar(stat = "identity") +
coord_flip() +
labs(title = "Distribución por Servicio Médico",
x = "Servicio",
y = "Número de Registros",
fill = "Estado") +
scale_fill_manual(values = c("#FF6B6B", "#4ECDC4")) +
theme_minimal()
ggplotly(p, tooltip = "text")
})
```
### Mapa de calor de actividad
```{r}
renderHighchart({
req(input$rango_fechas)
df <- camas %>%
filter(fecha >= input$rango_fechas[1],
fecha <= input$rango_fechas[2])
if(input$servicio != "Todos") {
df <- df %>% filter(servicio == input$servicio)
}
df %>%
count(fecha, servicio) %>%
hchart("heatmap", hcaes(x = fecha, y = servicio, value = n)) %>%
hc_title(text = "Actividad Hospitalaria por Día") %>%
hc_colorAxis(min = 0, stops = color_stops(colors = viridis(10))) %>%
hc_xAxis(title = list(text = "Fecha")) %>%
hc_yAxis(title = list(text = "Servicio"))
})
```
Tipos de Alta y Observaciones
=====================================
Row
-----------------------------------------------------------------------
### Distribución de vías de alta
```{r}
renderPlotly({
req(input$rango_fechas)
df <- camas %>%
filter(fecha >= input$rango_fechas[1],
fecha <= input$rango_fechas[2],
esalta == "Alta médica")
if(input$servicio != "Todos") {
df <- df %>% filter(servicio == input$servicio)
}
df_sum <- df %>%
count(viadealta) %>%
mutate(prop = n/sum(n)*100)
plot_ly(df_sum, labels = ~viadealta, values = ~n, type = "pie",
textinfo = "label+percent",
insidetextorientation = "radial",
marker = list(colors = RColorBrewer::brewer.pal(nrow(df_sum), "Set3"))) %>%
layout(title = "Distribución de Tipos de Alta Médica",
showlegend = FALSE)
})
```
### Registros prioritarios (rojos)
```{r}
renderDataTable({
req(input$rango_fechas)
df <- camas %>%
filter(color_observacion == "rojo",
fecha >= input$rango_fechas[1],
fecha <= input$rango_fechas[2])
if(input$servicio != "Todos") {
df <- df %>% filter(servicio == input$servicio)
}
datatable(
df %>% select(fecha, nombre_apellido, servicio, observacion, viadealta),
rownames = FALSE,
colnames = c("Fecha", "Paciente", "Servicio", "Observación", "Vía de Alta"),
options = list(
pageLength = 5,
dom = "tip",
language = list(
url = '//cdn.datatables.net/plug-ins/1.10.11/i18n/Spanish.json'
)
)
) %>%
formatStyle(columns = 1:5, backgroundColor = "#FFF3CD")
})
```
Datos Completos
=====================================
```{r}
renderDataTable({
req(input$rango_fechas)
df <- camas %>%
filter(fecha >= input$rango_fechas[1],
fecha <= input$rango_fechas[2])
if(input$servicio != "Todos") {
df <- df %>% filter(servicio == input$servicio)
}
datatable(
df,
extensions = "Buttons",
options = list(
dom = "Bfrtip",
buttons = c("copy", "csv", "excel"),
pageLength = 10,
autoWidth = TRUE,
language = list(
url = '//cdn.datatables.net/plug-ins/1.10.11/i18n/Spanish.json'
)
),
colnames = c("Fecha", "Paciente", "Sala", "Registro", "Servicio",
"Observación", "Es Alta", "Vía Alta", "Color Obs",
"Clasificación Obs", "Fuente", "Página")
)
})
```