7 Cuadros de mando (dashboards)

Fecha última actualización: 2025-07-16

Instalación/carga librerías/datos utilizados

if (!require(shiny)) install.packages('shiny') 
library(shiny) 
if (!require(flexdashboard)) install.packages('flexdashboard') 
library(flexdashboard)
if (!require(plotly)) install.packages('plotly') 
library(plotly)
if (!require(ggplot2)) install.packages('ggplot2') 
library(ggplot2)
if (!require(tidyverse)) install.packages('tidyverse') 
library(tidyverse)
source("utilidades.R")

Los cuadros de mando (dashboards) son aplicaciones web que presentan de forma organizada un conjunto de gráficos. Pueden ser estáticas, donde los gráficos presentan siempre los mismos datos o dinámicas, donde el usuario, a través de menús, puede elegir que datos observar en los gráficos. En este curso vamos a usar la librería shiny para crear cuadros de mando dinámicos. Además usaremos la librería flexdashboard como una interfaz para crear aplicaciones Shiny.

El paquete shiny fue lanzado en 2012 por RStudio para R. Su objetivo principal es permitir, a los usuarios de R, desarrollar aplicaciones web interactivas sin necesidad de usar JavaScript, HTML, o CSS. La principal ventaja de Shiny es que permite que las aplicaciones se actualicen automáticamente en función de la interacción del usuario, gracias a un modelo de programación reactivo, lo cual requiere la ejecución de R en tiempo real mientras se visualiza el cuadro de mandos. Por ello, para visualizar (desplegar), un cuadro de mandos a través de un servidor web, dicho servidor debe ser configurado, usando la aplicación Shiny Server, como un servidor Shiny que permita la ejecución en tiempo real de R. Es decir, no es tan simple como visualizar un fichero html que podemos alojar en cualquier servidor web.

flexdashboard es una interfaz que permite crear fácilmente cuadros de mando usando un fichero R Markdown. Este paquete convierte el documento en un cuadro de mandos estructurado en filas y columnas, lo que facilita la presentación de gráficos, tablas y contenido de texto en un formato amigable y visualmente atractivo. Puede integrarse con Shiny para añadir reactividad y generar una aplicación Shiny.

Una vez instaladas las librerías se puede crear el esqueleto de un cuadro de mando usando las instrucciones que se detallan en flexdashboard. También se puede utilizar cualquiera de los ficheros Rmd de ejemplos de cuadros de mandos que se suministran en este curso.

Para tener una primera idea de como funciona un cuadro de mandos dinámico vamos a presentar un primer ejemplo de cuadro de mandos organizado en 2 columnas. En la primera columna ponemos un menú desplegable para que el usuario elija un continente. En la segunda columna, simplemente imprimimos la selección realizada por el usuario. Un imagen estática de la salida de este cuadro de mandos sería la siguiente (para obtener la versión dinámica copiar el código que figura debajo en un fichero Rmd y ejecutar Run document en el menú superior (opción que reemplaza al knit en este tipo de ficheros Rmd)):

El código del fichero Rmd asociado a este cuadro de mandos es el siguiente:

---
title: "Ejemplo código básico de organización de un cuadro de mandos"
output: flexdashboard::flex_dashboard
runtime: shiny
---

Column {.sidebar data-width=230}
--------------------------------------------------
```{r}
shiny::selectInput(
  "continente",
  label = "Selección de continente",
  choices = c("Africa","Asia","Europe"),
  selected = "Europe"
)
```

Column
-----------------------------------------------------------------------
### Segunda columna del cuadro de mandos

```{r}
shiny::renderText({
  paste("El continente elegido por el usuario es : ",input$continente)
})
```

Observamos que en la cabecera declaramos que la salida es un cuadro de mandos usando la interfaz flexdashboard que se ejecuta usando shiny. La primera columna es una barra lateral de ancho 230 pixels donde declaramos un menú desplegable para seleccionar el valor de una variable usando la función selectInput. Esta función tiene 4 parámetros : El nombre de la variable (en este caso continente), el texto que se va a poner encima del desplegable (en este caso “Selección del continente”), los valores posibles de la variable (en este caso el vector que contiene a los continentes Africa, Asia y Europe), y el valor asignado a variable por defecto (en este caso Europe). Se declara a continuación una segunda columna donde simplemente llamamos a una función shiny que imprime el valor elegido por el usuario para la variable. Aquí hay dos cosas muy importantes a tener en cuenta: la primera es que para acceder en otras partes del código a la variable continente del desplegable utizamos la notación input$continente y la segunda es que solo se puede acceder al valor de input$continente dentro de una función shiny. En este caso, la función shiny es renderText. Es decir, que el chunk :

```{r}
  paste("El continente elegido por el usuario es : ",input$continente)
```

nos hubiese generado un error dado que estamos intentando acceder a una variable dinámica del cuadro de mandos fuera de una función shiny. Esto hay que tenerlo muy en cuenta porque es un error muy habitual al construir los cuadros de mando.

En general, la lectura y el procesado inicial de datos que no depende de los inputs del usuario se realiza al principio en un chunk normal. El procesado de datos que requiere el uso de los inputs del usuario se realiza dentro de las funciones reactive que son bloques de código que se recalculan automáticamente cada vez que cambian las entradas de las que dependen. Estas funciones almacenan su valor de salida y sólo lo recalcularán si cambian sus dependencias. Con frecuencia, una función reactive necesita devolver (a través de un return) varios objetos creados por ella (por ejemplo varias tablas), en ese caso, lo que haremos es devolver una lista que contiene todos los objetos. Es decir, una función reactive de este tipo, que calcula y devuelve dos objetos data1 y data2 tendrá un código como el que sigue:

inputs.processing <- shiny::reactive({
  
 # código que calcula data1 y data2
 ................
  
 return(list(data1,data2))
  
})

posteriormente, cuando se necesite acceder a data1 y/o data2 dentro de una función shiny hará lo siguiente:

FunciónShiny({
  
  data1 <- inputs.processing()[[1]] 
  data2 <- inputs.processing()[[2]] 
  
  # código de la función 
  
})

nótese que cualquier función shiny comienza por ({ y termina con }). Se recomienda analizar los códigos de los cuadros de mando que figuran a continuación para familiarizarse con las funciones reactive y en general con el diseño e implementación de cuadros de mando.

7.1 Cuadro de mandos con hchart

Vamos a estudiar el ejemplo de cuadro de mando dinámico que se encuentra en Dashboard1.Rmd, cuya ejecución se visualiza a continuación (para poder interactuar con el gráfico hay que ejecutar el fichero Rmd desde Rstudio) :

Cuadro de mando asociado al fichero Dashboard1.Rmd
Cuadro de mando asociado al fichero Dashboard1.Rmd

En este cuadro de mando se presentan 4 gráficos comparativos, realizados con hchart, de la evolución de la población en 4 países o regiones del mundo. A la izquierda aparece menús desplegables para elegir el país/región de cada gráfico y los años de inicio y final para generar el gráfico. Para generar este cuadro de mando localmente, hay que cargar el fichero Dashboard1.Rmd en Rstudio y ejecutar run document. Observamos que este cuadro de mando se organiza en 3 columnas: en la primera columna aparecen los menús desplegables en la segunda columna aparecen dos gráficos generados con hchart y en la tercera columna otros 2 gráficos similares. Usando flexdashboard este cuadro de mando se organiza de la siguiente forma :

  • Lectura de los datos que usa el cuadro de mandos y creación de las etiquetas que utilizarán los menús desplegables

  • Creación de una primera columna para poner los menús desplegables. La columna se crea usando el código:

Column {.sidebar data-width=230}
--------------------------------------------------

cada menú desplegable se crea usando la función selectInput. Esta función asocia un nombre al campo de este menú desplegable, por ejemplo country1, en el interior de las funciones que dibujan, se accede al valor de este campo a través de input$country1.

  • Creación de una segunda columna para poner 2 gráficos apilados de la población de dos países/regiones. La columna la creamos de nuevo usando la instrucción
Column
--------------------------------------------------

Cada gráfico lo creamos con la función renderHighchart. Es decir para que aparezcan los dos gráficos el código seguiría el siguiente estilo

###

renderHighchart({
  .....
  código creación gráfico hchart con datos input$country1
  ....
})

###

renderHighchart({
  .....
  código creación gráfico hchart con datos input$country2
  ....
})
  • Creación de una tercera columna de forma idéntica a la segunda, pero usando los datos de input$country3 y input$country4

La función renderHighchart se usa porque es un gráfico generado con hchart. Si fuera un gráfico generado con plotly habría que usar la función renderPlotly, y si fuese un gráfico de datos geográficos de Leaflet habría que usar la función renderLeaflet. Es decir, cada tipo de gráfico tiene asociado una función diferente en flexdashboard. Para un gráfico estándar se utiliza la función renderPlot.

7.2 Cuadro de mandos con Leaflet

El segundo cuadro de mando que vamos a estudiar se encuentra en el fichero Dashboard2.Rmd, cuya ejecución se visualiza a continuación:

Cuadro de mando asociado al fichero Dashboard2.Rmd
Cuadro de mando asociado al fichero Dashboard2.Rmd

En este caso, el cuadro de mandos tiene dos columnas. En la primera columna aparece un menú desplegable para elegir el indicador de los países que vamos a usar y aparece también una tabla con los datos del indicador en orden descendente. Las tablas en flexdashboard, se generan usando la función renderTable. A la derecha aparece una columna con un mapa coroplético con los valores del indicador (para interactuar con el gráfico hay que ejecutar el fichero Rmd desde Rstudio)

7.3 Cuadro de mandos con Plotly

El tercer cuadro de mando que vamos a estudiar se encuentra en el fichero Dashboard3.Rmd, cuya ejecución se visualiza a continuación:

Cuadro de mando asociado al fichero Dashboard3.Rmd Este cuadro de mando se organiza en 3 columnas. En la primera columna se muestran algunos menús desplegables y una tabla de resultados, en la segunda columna un diagrama de dispersión usando plotly y en la tercera columna una tabla con datos.

El objetivo de este cuadro de mando es estudiar la relación entre cualquier par de indicadores sobre los países publicados por la OWID y utilizados en el cuadro de mandos anterior. Al primer indicador lo llamaremos x y al segundo y. Por ejemplo, en la imagen anterior se muestra la comparación entre x=life_expectancy e y=gdp_per_capita. El modelo que usaremos es la conocida regresión lineal, es decir, buscamos una relación lineal entre x, y, dada por

y=ax+b

donde a es la pendiente (slope) y b es el término independiente (independent). Para mejorar el ajuste de las dos variables por la recta de regresión se permite al usuario escalar las variables antes de hacer la comparación. Escalar x significa que sustituimos x por sx(x), donde sx() es la transformada utilizada, en nuestro caso, damos como opciones sx(x)=sgn(x)log(|x|), o sx(x)=sgn(x)sqrt(|x|). Este tipo de escalado ya lo hemos usado en ggplot a efectos de visualización. De la misma forma, opcionalmente, escalamos y con sy(y), permitiendo elegir sy(y)=sgn(y)log(|y|) o sy(y) dada por la transformada de Yeo-Johnson (ver [YeJo00]), que, depende de un parámetro λ y se define como:

sy(y;λ)={(y+1)λ1λsiy0,λ0log(y+1)siy0,λ=0(y+1)2λ12λsiy0,λ2log(y+1)siy0,λ2

A continuación presentamos la gráfica de esta transformada para diferentes valores del parámetro λ

Figure 7.1: Gráfica de la transformada de Yeo-Johnson para diferentes valores del parámetro lambda

En el cuadro de mandos, cuando se selecciona la opción YeoJohnson, se calcula automáticamente el valor de λ que suministra un mejor ajuste lineal entre las variables y se imprime su valor en la primera columna. Para valorar la calidad del ajuste obtenido, en la primera columna del cuadro de mando se imprimen los siguientes valores :

  • correlation: el factor de correlation, que se explicará en más detalle en el próximo tema. Cuanto más cerca de 1 esté este valor, mejor es el ajuste.

  • sd(residuos): la desviación típica de los residuos, es decir las diferencias entre los valores reales de y y los valores en la recta de regresión en función del valor del x asociado. Cuanto más pequeño es este valor mejor es el ajuste.

  • R2: el coeficiente de determinación, cuanto más cerca de 1, mejor es el ajuste. El criterio utilizado para calcular λ en la transformada de Yeo-Johnson es maximar este valor.

En el ejemplo que se visualiza en la imagen anterior, no se escaló la variable x y para y se utilizó la opción YeoJohnson obteniendo λ=5.1e3. Por tanto, a la vista de los resultados, la relación que se establece entre las variables sería:

sy(y,5.1e3)=1.271e1x2.151e1

Podríamos, a partir de esta fórmula, despejar la y utilizando la inversa de la transformada de Yeo-Johnson. Visualmente, en el diagrama de dispersión del cuadro de mandos, cuanto mejor se ajuste la nube puntos a la recta de regresión, mejor explicará el modelo la relación entre los dos indicadores.

7.4 Opciones configuración

Existen múltiples opciones de configuración para la salida de un cuadro de mandos. Para ilustrar algunas de ellas vamos a usar el cuadro de mandos de ejemplo Dashboard4.Rmd. Este cuadro de mandos tiene un menú en la parte superior para acceder a 3 páginas. En la primera página vemos un ejemplo de renderizado de código html:

En la segunda página vemos algunos ejemplos de formato de entrada para diferentes tipos de variables:

En la tercera página se muestra una página con 2 pestañas que nos permite acceder a dos subpáginas diferentes:

7.5 Publicar un cuadro de mando

Para publicar un cuadro de mando realizado por flexdashboard hay diversas formas (ver shiny.rstudio.com). Lo más sencillo es usar el servidor de shinyapps.io. Para ello hay que darse de alta en el citado sitio web y seguir las siguientes instrucciones. La versión gratuita de uso del servidor permite 5 aplicaciones y 25 horas mensuales de ejecución. Otra opción más compleja, pero también gratuita, es alojar en un servidor LINUX propio el software completo.

Referencias

[BoCo64] Box, G. E., and D. R. Cox.. An analysis of transformations, Journal of the Royal Statistical Society. Series B (Methodological), 211–52, 1964.

[YeJo00] Yeo, I. K., and Johnson, R. A., A new family of power transformations to improve normality or symmetry. Biometrika, 87(4), 954–959, (2000).

[Shinyapps] Shinyapps

[SIAB23] Sievert, Carson, Richard Iannone, JJ Allaire, and Barbara Borges. 2023. flexdashboard: R Markdown Format for Flexible Dashboards, 2023.