Arquitectura y Modularización

De un Archivo a una Aplicación: Estructurando el Código para Crecer.

El Problema del Archivo Monolítico

Cuando empezamos con Shiny, el archivo app.R es nuestro mejor amigo. Es simple, directo y contiene todo lo que necesitamos. Sin embargo, a medida que nuestra aplicación crece, este amigo se convierte en un monstruo. Un único archivo con miles de líneas de código, mezclando la lógica de la interfaz, los cálculos del servidor, la carga de datos y los estilos, se vuelve increíblemente difícil de leer, depurar y mantener.

Intentar encontrar un error en un app.R masivo es como buscar una aguja en un pajar. La colaboración se vuelve una pesadilla, con múltiples personas intentando editar el mismo archivo. Para construir aplicaciones robustas y escalables, debemos abandonar el monolito y adoptar una arquitectura modular.

La Estructura Profesional: Separación de Responsabilidades

La clave de una buena arquitectura es la "separación de responsabilidades". Cada parte del código debe hacer una sola cosa y hacerla bien. En Shiny, esto se traduce en una estructura de tres archivos principales que reemplazan a app.R:

global.R: El Preparador

Responsabilidad: Preparar el entorno. Este script se ejecuta una sola vez cuando la aplicación se inicia. Es el lugar perfecto para todo el código que no necesita cambiar mientras la app está en uso, como:

  • Cargar todas las librerías necesarias (library(shiny), library(dplyr), etc.).
  • Cargar los datos desde archivos (ej. read_delim()).
  • Definir funciones personalizadas que se usarán en el servidor.
  • Establecer conexiones a bases de datos.

ui.R: El Arquitecto Visual

Responsabilidad: Definir la interfaz de usuario. Este archivo debe contener únicamente el objeto de la UI (ej. ui <- fluidPage(...)). Su única misión es describir qué ve el usuario: los paneles, los botones, los sliders y los espacios para los outputs. No debe contener ninguna lógica de cálculo.

server.R: El Cerebro Lógico

Responsabilidad: Contener toda la lógica reactiva. Este archivo debe definir únicamente la función del servidor (server <- function(input, output, session) { ... }). Aquí es donde viven los conductores reactivos, los observadores y los renderizadores de outputs. Es el motor que responde a las interacciones del usuario.

Taller Práctico: Refactorizando a una Arquitectura Modular

Vamos a tomar nuestra aplicación y a transformarla, pasando de un solo app.R a la estructura profesional de tres archivos.

Paso 1: Crear global.R

En la raíz de tu proyecto, crea un nuevo archivo llamado global.R. Corta y pega todo el código de configuración que está al inicio de tu app.R en este nuevo archivo.

# Contenido de global.R

# 1. Cargar todas las librerías
library(shiny)
library(readr)
library(dplyr)
library(ggplot2)
library(plotly)
library(bslib)

# 2. Cargar y preparar datos (se hace una sola vez)
datos_saber <- read_delim("data/raw/Examen_Saber_11_20242.txt", delim = ";", show_col_types = FALSE) %>%
  na.omit()

# 3. Crear objetos globales que la UI o el Server puedan necesitar
puntajes_choices <- datos_saber %>%
  select(starts_with("punt_")) %>%
  names()

Paso 2: Crear ui.R

Crea un archivo ui.R. Corta la definición completa del objeto ui de tu app.R y pégala aquí.

# Contenido de ui.R

# El archivo solo debe contener esto:
ui <- fluidPage(
  theme = bs_theme(bootswatch = "darkly"),
  titlePanel("Dashboard Exploratorio Pruebas Saber 11"),
  
  # ... todo el resto del contenido de la UI ...
  
)

Paso 3: Crear server.R

Finalmente, crea un archivo server.R. Corta la definición completa de la función server de tu app.R y pégala en este archivo.

# Contenido de server.R

# El archivo solo debe contener esto:
server <- function(input, output, session) {

  # ... toda tu lógica reactiva (eventReactive, observeEvent, renderPlotly, etc.) ...
  
}

Paso 4: Eliminar app.R y Verificar

Ahora que todo el código ha sido movido a su lugar correcto, el archivo app.R está vacío y ya no es necesario. Puedes eliminarlo de forma segura.

Shiny está diseñado para detectar esta estructura. Si no encuentra un archivo app.R, buscará automáticamente un ui.R y un server.R. Ejecuta tu aplicación de la manera habitual (con el botón "Run App" o shiny::runApp()). Debería funcionar exactamente igual que antes, ¡pero ahora tu código está limpio, organizado y listo para escalar!

Tu Nueva Estructura Profesional

La raíz de tu proyecto ahora refleja un estándar de la industria, fácil de entender para cualquier desarrollador de R.

/mi-proyecto/
|-- data/
|-- R/
|-- .gitignore
|-- global.R   # Carga y preparación
|-- server.R   # Lógica reactiva
|-- ui.R       # Interfaz de usuario
`-- README.md

Paso 5: Versionar la Refactorización

Este es un cambio estructural masivo y un hito en la madurez de tu proyecto. Es fundamental registrarlo adecuadamente en Git.

# Git detectará la eliminación de app.R y la creación de los nuevos archivos.
git add .

# Un commit que describe claramente la refactorización arquitectónica.
git commit -m "refactor(core): Modulariza la app en la estructura global/ui/server"

# Sube los cambios al repositorio remoto.
git push