14 Introducción a Shiny
Erick Cuevas-Fernández
12 de agosto de 2021
Este material esta basado en:
- https://shiny.rstudio.com/tutorial/written-tutorial/lesson1/
- https://bookdown.org/weicheng/shinyTutorial/
- https://mastering-shiny.org/index.html
14.1 ¿Qué es y para qué me sirve Shiny?
Este paquete fue creado en 2012 por RStudio para desarrollar aplicaciones Web con el uso de R. Shiny es un paquete de R que nos permite generar módulos de mando web interactivos, crear interfaces para algoritmos o bien manipular en tiempo real tablas de datos y gráficos a través de controles de HTML.
Para instalarlo puedes usar los siguientes códigos:
install.packages("shiny")
if (!require("devtools"))
install.packages("devtools")
::install_github("shiny", "rstudio") devtools
Mediante esta paquetería podemos personalizar nuestra creación de forma sencilla con sintaxis HTML, CSS o Javascript. Pero aún así solo se requieren conocimientos de R para emplear Shiny.
Toda Shiny app es mantenida por una computadora que se encuentra corriendo R.
ANTES DE EMPEZAR RECUERDA:
- Tener descargada la paquetería de Shiny
- Tener R y RStudio actualizado
- PACIENCIA Y MUCHO ENTUSIASMO
14.2 Los alcances de Shiny!!!
Desde el 2019 se celebra el Shiny Contest. En el primer certamén se sometieron a competencia 136 apps desarrolladas con Shiny!!!
Entre las apps que más se han destacado desde entonces están:
Y también puedes ver toda la galería de Shiny Apps.
OJO
LO MEJOR ES QUE TODAS LAS SHINY APPS COMPARTEN SU CÓDIGO EN GITHUB
RECUERDA VER LOS EJEMPLOS DE CÓDIGO. TENER PACIENCIA. PRACTICAR Y PRACTICAR…APRENDER… VOLVER A EQUIVOCARSE… EUREKA!
DESCARGA LA CHEAT SHEET DE SHINY
14.3 Primeros pasos: La estructura canónica de Shiny
Toda aplicación web de Shiny tendrá la misma estructura, dos bloques de códigos de R:
- ui: genera una interfaz de usuario
- server: contiene las instrucciones que la computadora necesita para crear la app.
La estructura de código de una app Shiny se vería del siguiente modo:
library(shiny)
<- fluidPage(
ui xxxxInput(),
xxxxOutput()
)
<- function(input, output)
server
{
Codigo de R
}
shinyApp(ui = ui, server = server)
En RStudio puedes generar una nueva app con este molde de código mediante los siguientes pasos:
- Crea un nuevo directorio y un archivo app.R que contenga una aplicación básica en un solo paso haciendo clic en Archivo | Nuevo proyecto, luego selecciona Nuevo directorio y Shiny Web Application.
- Si ya has creado el archivo app.R, puedes agregar rápidamente el texto estándar de la aplicación escribiendo “shinyapp” y presionando
Shift + Tab
. - También puedes hacer dos scripts por separado, ui.R y server.R y ejecutar ambos en la app.R con
shinyApp(ui = ui.R, server = server.R)
.
Para que la app esté completa necesitas solo 4 cosas en tu app.R:
- Cargar la paquetería de Shiny con
library(shiny)
- Definir la interfaz de usuario, la web HTML con la que interactúan quienes ocuparán la app. Es decir, definir la
ui
.
- Especificar el comportamiento de nuestra aplicación definiendo una función de
server
. - Ejecutar
shinyApp(ui, server)
para construir e iniciar una Shiny app.
14.3.1 Actividad
Genera un archivo app.R listo para hacer una Shiny app. Puedes generar solo un app.R y posteriormente escribir en la consola “shinyapp” y presionar Shift + Tab
14.4 La Interfaz de Usuario (UI)
Shiny por default usa bootstrap (lo cual no tiene nada que ver con el método estadístico bootstrap). Esto es un marco de trabajo de HTML, CSS y Javascript más popular para desarrollar sitios web receptivos.
OJO: si sabes usar HTML puedes usar todos los tags en Shiny. Puedes consultar estos tags con la siguiente función:
::tags
shinynames(shiny::tags)
Shiny fomenta la separación del código que genera su interfaz de usuario (el front-end) del código que impulsa el comportamiento de su aplicación (el back-end).
Existe una comunidad rica y vibrante de paquetes de extensión, como shinyWidgets, colorpicker y sorttable. Puede encontrar una lista completa y mantenida activamente de otros paquetes en https://github.com/nanxstats/awesome-shiny-extensions, mantenida por Nan Xiao.
Para iniciar a entender como funciona la Interfaz de Usuario, en un archivo
app.R
realiza lo siguiente:
library(shiny)
<- fluidPage(
ui "¡Hola mundo!"
)<- function(input, output, session) {
server
}shinyApp(ui, server)
Corre la app con el botón Run App
o simplemente ejecuta la línea de shinyApp(ui, server)
.
Dentro de la Interfaz de Usuario podemos tener:
- Funciones de Layout
- Controles de input
- Controles de output
14.4.1 Los Layouts más comunes
Veamos un poco las funciones de Layout. A la misma app que tenemos arriba ahora vamos a agregarle lo siguiente:
library(shiny)
<- fluidPage(
ui titlePanel("Mi app de hola mundo"),
"¡Hola Mundo!"
)<- function(input, output, session) {
server
}shinyApp(ui, server)
Ahora intentemos lo siguiente, si usamos la función sidebarLayout
.
library(shiny)
<- fluidPage(
ui titlePanel("Mi app de hola mundo"),
sidebarLayout(
sidebarPanel("Este es el sidebar panel de mi app hola mundo, y aqui van mis controles de INPUT"),
mainPanel("este es el main panel de mi app hola mundo, y aqui van mis controles de OUTPUT")
),"Hola Mundo"
)<- function(input, output, session) {
server
}shinyApp(ui, server)
Así se vería la distribución ahora de nuestro Layout
A medida que su aplicación crece en complejidad, puede resultar imposible ajustar todo en una sola página. En esta sección, aprenderás varios usos de tabPanel()
que crean la ilusión de múltiples páginas. Esto es una ilusión porque todavía tendrá una sola aplicación con un solo archivo HTML subyacente, pero ahora está dividida en pedazos y solo se puede ver una pieza a la vez.
library(shiny)
<- fluidPage(
ui tabsetPanel(
tabPanel("Pestaña 1", "Aqui hay un hola mundo, y se ponen los inputs"),
tabPanel("Pestaña 2", "lo mismo que en la pestaña 1"),
tabPanel("Pestaña 3", "Vamos a jugar con más")
)
)<- function(input, output, session) {
server
}shinyApp(ui, server)
Otro layout son las listas de navegación o las barras de navegación. Debido a que las pestañas se muestran horizontalmente, existe un límite fundamental en la cantidad de pestañas que puede usar, especialmente si tienen títulos largos. navbarPage()
y navbarMenu()
proporcionan dos diseños alternativos que les permiten usar más pestañas con títulos más largos. navlistPanel()
es similar a tabsetPanel()
pero en lugar de ejecutar los títulos de las pestañas horizontalmente, los muestra verticalmente en una barra lateral.
library(shiny)
<- fluidPage(
ui navlistPanel(
tabPanel("Pestaña 1", "Aqui hay un hola mundo, y se ponen los inputs"),
tabPanel("Pestaña 2", "lo mismo que en la pestaña 1"),
tabPanel("Pestaña 3", "Vamos a jugar con más")
)
)<- function(input, output, session) {
server
}shinyApp(ui, server)
Otra alternativa es usar:
library(shiny)
<- navbarPage(
ui "ESTO ES UN TITULO DE MI APP HOLA MUNDO",
tabPanel("Pestaña 1", "Aqui hay un hola mundo, y se ponen los inputs"),
tabPanel("Pestaña 2", "lo mismo que en la pestaña 1"),
tabPanel("Pestaña 3", "Vamos a jugar con más"),
navbarMenu("Estos podrian ser subpaneles",
tabPanel("Lo viste?? es genial", "y esto es??.."))
)<- function(input, output, session) {
server
}shinyApp(ui, server)
Dentro de Shiny puedes modificar los paneles con alguna de estas funciones en la UI:
absolutePanel()
conditionalPanel()
fixedPanel()
headerPanel()
inputPanel()
mainPanel()
navlistPanel()
sidebarPanel()
tabPanel()
tabsetPanel()
titlePanel()
wellPanel()
Más adelante date la oportunidad de probarlos todos!!
Y además puedes puedes probar estos Layouts
14.4.2 Controles de Input
Dentro de los controles de Input tenemos los siguientes como más comunes:
Funcion | widget |
---|---|
actionButton | boton de accion |
checkboxGroupInput | Grupo de cajas para checar |
checkboxInput | una sola caja para checar |
dateInput | Un calendario para seleccionar fecha |
dateRangeInput | Par de calendarios para seleccionar un rango de fecha |
fileInput | Asistente de control de carga de archivos |
helpText | Texto de ayuda que se puede agregar a un formulario de entrada |
numericInput | Un campo para ingresar numeros |
radioButtons | Un conjunto de botones de radio |
selectInput | Un cuadro con opciones para elegir |
sliderInput | Una barra lateral |
submitButton | Un boton de enviar |
textInput | Un campo para ingresar texto |
Ahora agreguemos algunos controles de input a nuestra app de Hola Mundo
library(shiny)
<- fluidPage(
ui titlePanel("Mi app hola mundo!"),
sidebarLayout(
sidebarPanel(
numericInput("numInput", "Un input numerico:", value = 7, min = 1, max = 30)
),mainPanel(
"este es el main panel de mi app hola mundo, y aqui van mis controles de OUTPUT"
)
),"Hola MUNDO"
)<- function(input, output, session) {
server
}shinyApp(ui, server)
14.4.3 Actividad
Modifica la tu app de “HOLA MUNDO” agregando tres pestañas de navegador de barras y agrega un control de input de Texto
14.4.4 Controles de Output
Los outputs van a tener efecto directo con la renderización de nuestros resultados, en los outputs tenemos que especificar el nombre o ID de nuestras salidas y el tipo de salida que será.
library(shiny)
<- fluidPage(
ui titlePanel("Mi app hola mundo!"),
sidebarLayout(
sidebarPanel(
sliderInput(inputId = "num",
label = "Selecciona un numero",
value = 14, min = 1, max = 200),
plotOutput("identificador_de_mi_output")
),mainPanel(
"este es el main panel de mi app hola mundo, y aqui van mis controles de OUTPUT"
)
),"Hola MUNDO"
)<- function(input, output, session) {
server
}shinyApp(ui, server)
14.5 El Servidor (Server)
El servidor servirá para especificar como ensamblar los inputs en los outputs.
Hay 3 reglas para escribir código en el Server:
- Especifica con
output$
+ID output
cada objeto dentro deserver
. - Cada objeto se mostrará con un
render()
, ejemplorenderPlot({})
- Accesa a los valores de los inputs con
input$
+ID input
Ahora agreguemos reactividad a nuestra app de Hola Mundo
library(shiny)
<- fluidPage(
ui titlePanel("Mi app hola mundo!"),
sidebarLayout(
sidebarPanel(
sliderInput(inputId = "num",
label = "Selecciona un numero",
value = 14, min = 1, max = 200)
),mainPanel(
"este es el main panel de mi app hola mundo, y aqui van mis controles de OUTPUT",
plotOutput("identificador_de_mi_output")
)
),"Hola MUNDO"
)<- function(input, output, session) {
server $identificador_de_mi_output <- renderPlot({
outputlibrary(ggplot2)
<- rnorm(input$num)
var_1 <- data.frame(norma = var_1)
var_2
ggplot(var_2, aes(x = norma)) +
geom_density() + theme_classic()
})
}shinyApp(ui, server)
La reactuvidad funciona de la siguiente manera:
14.5.1 Actividad
Modifica la tu app de “HOLA MUNDO” para que pida un dataset al usuario del paquete datasets. Con el dataset seleccionado haz un grafico en el server.