Noviembre 8 de 2019
Shiny es un paquete de R que permite construir aplicaciones web interactivas directamente desde R. Este curso, basado en los Tutoriales Escritos de shiny disponibles en RStudio, le permitirá comenzar a construir aplicaciones Shiny de forma inmediata.
Para seguir el tutorial se deben tener instalados algunos paquetes de R. Para ello en una sesión de R y estando conectado a internet ejecute:
install.packages(c("shiny", "maps", "mapproj", "quantmod", "ggplot2"))
El paquete Shiny tiene once ejemplos incorporados que demuestran como funciona.
El primer y más sencillo de los ejemplos es Hello Shiny, el cual grafica un histograma del conjunto de datos de R faithful con un número de intervalos configurable. El usuario puede cambiar el número de intervalos con una barra deslizante y la aplicación inmediatamente responderá a la entrada. Se usará esta aplicación para explorar la estructura de una aplicación Shiny y para crear nuevas aplicaciones.
Para ejecutar Hello Shiny, escriba:
library(shiny)
runExample("01_hello")
Las aplicaciones Shiny se escriben en un script simple con nombre app.R, el cual está dentro de una carpeta, digamos app-dir y la aplicación se puede ejecutar con runApp("app-dir").
El script app.R tiene tres componentes:
uiservershinyApp.El objeto ui controla el diseño y la apariencia de la aplicación, mientras que la función server contiene las instrucciones que el computador necesita para construir la aplicación. Finalmente, la función shinyApp crea los objetos de la aplicación Shiny desde el par ui/server.
Una ventaja de las aplicaciones de archivo simple es que son fáciles de compartir. Por ejemplo, si se copia y se pega el código de Hello Shiny en la consola se iniciará la aplicación.
Observe que la función server en Hello Shiny es muy simple. El script hace algunos cálculos y luego grafica un histograma con el número de intervalos requerido.
Sin embargo, note que la mayoría del código está relacionado con el uso de la función renderPlot. El comentario sobre esta función trata de explicarla, pero puede ser confuso, este concepto se cubrirá con mayor detalle más adelante.
Se puede experimentar con la aplicación Hello Shiny, revisar su código fuente e intentar entender como funciona. Pero antes de hacer eso, note que un archivo app.R necesita cargar el paquete Shiny al inicio y llamar a la función shinyApp al final:
library(shiny) # See above for the definitions of ui and server ui <- ... server <- ... shinyApp(ui = ui, server = server)
Mientras que la aplicación Hello Shiny este activa la sesión de R estará ocupada, por lo que no se podrá ejecutar ningún comando R, ya que éste estará monitoreando la aplicación y ejecutando las reacciones de la aplicación. Para recuperar la sesión de R, presione Esc o haga clic en el icono de señal de alto (que se encuentra en la esquina superior derecha del panel de la consola en RStudio).
Toda aplicación Shiny tiene la misma estructura: un archivo app.R que contiene el objeto ui, la función server y la llamada a la función shinyApp.
Se puede crear una aplicación Shiny creando una nueva carpeta y guardando un archivo app.R en ella. Se recomienda que cada aplicación este alojada dentro de una única carpeta propia.
Se puede ejecutar una aplicación Shiny usando el nombre de la carpeta como parámetro de la función runApp. Por ejemplo, si una aplicación Shiny está en una carpeta llamada my_app, se ejecuta el siguiente código:
library(shiny)
runApp("my_app")
El primer argumento de runApp es la ruta desde el directorio de trabajo a la carpeta de la aplicación.
Cree una nueva carpeta llamada App-1 en el directorio de trabajo. Luego, copie y pegue el código de Hello Shiny en un archivo app.R dentro de la carpeta creada.
Inicie la aplicación ejecutando:
runApp("App-1")
cuyo resultado es App-1.
Luego, haga clic en Esc y realice algunos cambios en su aplicación:
Cambie el título de “Hello Shiny!” A “Hello World!”.
Establezca el valor mínimo de la barra deslizante en 5.
Cambie el color del borde de las barras del histograma de "white" a "orange".
Cuando termine, inicie su aplicación nuevamente. El resultado del ejercicio es App-1-final.
Por defecto, las aplicaciones Shiny se muestran en modo “normal”, como la aplicación anterior. Hello Shiny y los otros ejemplos integrados se muestran en modo “showcase”, que muestra el script app.R junto con la aplicación.
Si se desea mostrar una aplicación en modo “showcase”, se puede ejecutar:
runApp("App-1", display.mode = "showcase")
Para relanzar una aplicación Shiny:
runApp("App-1"), oapp.R en el editor de RStudio. RStudio reconocerá el script Shiny y proporcionará un botón Run App (en la parte superior derecha del editor). Haga clic en este botón para iniciar su aplicación o use el método abreviado de teclado: Ctrl + Mayús + Entrar (Comando + Mayús + Entrar en sistemas Mac).Para crear su propia aplicación Shiny:
myapp para su aplicación.app.R dentro de la carpeta.runApp o usando los métodos abreviados de teclado de RStudio.Esc.Se pueden crear aplicaciones Shiny copiando y modificando otras aplicaciones Shiny existentes. La galería de Shiny proporciona algunos buenos ejemplos o se pueden usar los once ejemplos incorporados que se muestran a continuación.
runExample("01_hello") # a histogram
runExample("02_text") # tables and data frames
runExample("03_reactivity") # a reactive expression
runExample("04_mpg") # global variables
runExample("05_sliders") # slider bars
runExample("06_tabsets") # tabbed panels
runExample("07_widgets") # help text and submit buttons
runExample("08_html") # Shiny app built from HTML
runExample("09_upload") # file upload wizard
runExample("10_download") # file download wizard
runExample("11_timer") # an automated timer
Cada uno demuestra una característica de Shiny y se abren en el modo “showcase”, esto es, mostrando el código app.R.
uiuiEsta sección muestra cómo crear una interfaz de usuario para su aplicación.
Se usará una de las aplicaciones usadas en la sección anterior. Abra el archivo app.R y edítelo para que coincida con:
library(shiny)
# Define UI ----
ui <- fluidPage(
)
# Define server logic ----
server <- function(input, output){
}
# Run the app ----
shinyApp(ui = ui, server = server)
Este es el mínimo de código necesario para crear una aplicación Shiny, cuyo resultado es minimal.
Shiny usa la función fluidPage para crear una pantalla que se ajusta automáticamente a las dimensiones de la ventana del navegador. El diseño de la interfaz de usuario consiste en colocar elementos en la función fluidPage.
Por ejemplo, la función ui que se muestra a continuación crea una interfaz de usuario que tiene un panel de título y un diseño de barra lateral, que incluye un panel de barra lateral y un panel principal.
ui <- fluidPage(
titlePanel("title panel"),
sidebarLayout(
sidebarPanel("sidebar panel"),
mainPanel("main panel")
)
)
cuyo resultado es ej1.
Los dos elementos más populares que se adicionan a fluidPage son titlePanel y sidebarLayout, creando una aplicación Shiny con una barra lateral.
sidebarLayout tiene dos argumentos output:
sidebarPanel.mainPanel.Estas funciones colocan contenido en el panel de la barra lateral o en el panel principal. El panel de la barra lateral aparecerá por defecto en el lado izquierdo de la aplicación. Se puede mover hacia el lado derecho dando el argumento opcional position = "right" en sidebarLayout.
ui <- fluidPage(
titlePanel("title panel"),
sidebarLayout(position = "right",
sidebarPanel("sidebar panel"),
mainPanel("main panel")
)
)
cuyo resultado es ej2.
titlePanel y sidebarLayout crean un diseño básico para la aplicación Shiny, pero también se pueden crear diseños más avanzados.
Se puede usar navbarPage para proporcionarle a la aplicación una interfaz de usuario de varias páginas que incluya una barra de navegación. También se puede usar fluidRow y column para crear un diseño desde un sistema de cuadrícula.
Si desea obtener más información sobre estas opciones avanzadas, lea la Guía de diseño de aplicaciones Shiny. En este curso se usará sidebarLayout.
Se puede agregar contenido a la aplicación Shiny simplemente colocándolo dentro de una función *Panel. Por ejemplo, la aplicación ej2 muestra una cadena de caracteres en cada uno de sus paneles.
Para agregar contenido más avanzado, se usan las funciones etiqueta HTML de Shiny. Estas funciones son paralelas a las funciones etiqueta HTML5 comunes. Veamos algunas de ellas.
| shiny function | HTML5 equivalent | creates |
|---|---|---|
| p | <p> |
A paragraph of text |
| h1 | <h1> |
A first level header |
| h2 | <h2> |
A second level header |
| h3 | <h3> |
A third level header |
| h4 | <h4> |
A fourth level header |
| h5 | <h5> |
A fifth level header |
| h6 | <h6> |
A sixth level header |
| shiny function | HTML5 equivalent | creates |
|---|---|---|
| a | <a> |
A hyper link |
| br | <br> |
A line break (e.g. a blank line) |
| div | <div> |
A division of text with a uniform style |
| span | <span> |
An in-line division of text with a uniform style |
| pre | <pre> |
Text ‘as is’ in a fixed width font |
| code | <code> |
A formatted block of code |
| img | <img> |
An image |
| strong | <strong> |
Bold text |
| em | <em> |
Italicized text |
| HTML | Directly passes a character string as HTML code |
Para crear un elemento de encabezado:
Por ejemplo, puede crear un encabezado de primer nivel que diga “My title” con h1("My title").
Para colocar el comando en la aplicación:
h1("My title") como argumento en titlePanel, sidebarPanel o mainPanel.El texto aparecerá en el panel correspondiente de la aplicación.
Se pueden colocar varios elementos en el mismo panel si los separa con una coma. Por ejemplo, el código que se muestra a continuación utiliza los seis niveles de encabezados.
ui <- fluidPage(
titlePanel("My Shiny App"),
sidebarLayout(
sidebarPanel(),
mainPanel(
h1("First level title"),
h2("Second level title"),
h3("Third level title"),
h4("Fourth level title"),
h5("Fifth level title"),
h6("Sixth level title")
)
)
)
cuyo resultado es ej3.
Se pueden crear efectos en las etiquetas HTML, por ejemplo, si se quiere centrar un título se puede usar el argumento align = "center" en el correspondiente encabezado, digamos h1(“First level title”, align = “center”).
En general, se puee usar cualquier atributo de etiqueta HTML como argumento en una función de etiqueta Shiny. Si no está familiarizado con los atributos de etiqueta HTML, puede consultarlos en w3schools. A continuación se muestra un código para el objeto ui inspirado en Star Wars:
ui <- fluidPage(
titlePanel("My Star Wars App"),
sidebarLayout(
sidebarPanel(),
mainPanel(
h6("Episode IV", align = "center"),
h6("A NEW HOPE", align = "center"),
h5("It is a period of civil war.", align = "center"),
h4("Rebel spaceships, striking", align = "center"),
h3("from a hidden base, have won", align = "center"),
h2("their first victory against the", align = "center"),
h1("evil Galactic Empire.", align = "center")
)
)
)
cuyo resultado es ej4.
Shiny ofrece muchas funciones etiqueta para formatear texto. Para ilustrar esto, pegue el siguiente objeto ui en su archivo app.R.
ui <- fluidPage(
titlePanel("My Shiny App"),
sidebarLayout(
sidebarPanel(),
mainPanel(
p("p creates a paragraph of text."),
p("A new p() command starts a new paragraph. Supply a style attribute to change
the entire paragraph format.", style = "font-family: 'times'; font-si16pt"),
strong("strong() makes bold text."), em("em() creates italicized text."), br(),
code("code displays your text similar to computer code"),
div("div creates segments of text with a similar style. This division of text
is all blue because I passed the argument 'style = color:blue' to div",
style = "color:blue"), br(),
p("span does the same thing as div, but it works with",
span("groups of words", style = "color:blue"),
"that appear inside a paragraph.")
)
)
)
El resultado es ej5.
Las imágenes pueden mejorar la apariencia de una aplicación y ayudar a los usuarios a comprender el contenido. Shiny usa la función img para colocar archivos de imagen en su aplicación.
Para insertar una imagen, use la función img dando como argumento src el nombre del archivo de imagen, por ejemplo, img(src = "my_image.png").
También se pueden incluir otros parámetros compatibles con HTML, tales como height y width, cuyos valores se dan en píxeles. Por ejemplo:
img(src = "my_image.png", height = 72, width = 72)
La función img busca el archivo de imagen en una carpeta de nombre www en el mismo directorio que el archivo app.R.
Ejemplo:
www en el directorio de la aplicación, yapp.R para que incluya el siguiente objeto ui:ui <- fluidPage(
titlePanel("My Shiny App"),
sidebarLayout(
sidebarPanel(),
mainPanel(
img(src = "R_day.png", height = 140, width = 140)
)
)
)
El resultado es ej6.
Para obtener mayor información sobre las funciones etiquetas adicionales consulte Personalice su IU con HTML y Glosario de etiquetas HTML de Shiny.
Con las habilidades presentadas, puede:
fluidPage, titlePanel y sidebarLayout.titlePanel, sidebarPanel o mainPanel.www dentro del directorio de la aplicación Shiny y luego llamando a la función img.Es un elemento web con el que un usuario pueden interactuar, proporcionándole una forma para enviar valores a la aplicación Shiny. Cuando el usuario cambia un widget, su valor también lo hace.
Shiny viene con una familia de widgets incorporados, cada uno creado con una función R. Por ejemplo, Shiny proporciona una función llamada actionButton que crea un Botón de acción y una función llamada sliderInput que crea una barra deslizante.
Los widgets Shiny estándar son:
| Función | Widget |
|---|---|
actionButton |
Botón de acción |
checkboxGroupInput |
Un grupo de casillas de verificación |
checkboxInput |
Una sola casilla de verificación |
| Función | Widget |
|---|---|
dateInput |
Un calendario para selección de una fecha |
dateRangeInput |
Un par de calendarios para seleccionar un rango de fechas |
fileInput |
Un asistente de control para la carga de archivos |
helpText |
Texto de ayuda que se puede agregar a un formulario de entrada |
numericInput |
Un campo para ingresar números |
radioButtons |
Un conjunto de botones para selección múltiple de única respuesta |
selectInput |
Un cuadro con opciones para seleccionar |
sliderInput |
Una barra deslizante |
submitButton |
Un botón de enviar |
textInput |
Un campo para ingresar texto |
Se hace de la misma manera que se agregaron otros tipos de contenido HTML. Para agregar un widget a la aplicación, coloque una función widget en sidebarPanel o mainPanel dentro del objeto ui.
Cada función widget requiere varios argumentos. Los primeros dos argumentos para cada widget son:
"".Por ejemplo, para crear un botón de acción cuyo nombre es “action” y su etiqueta es “Action” se usa el código: actionButton("action", label = "Action")
Los argumentos restantes varían de un widget a otro. Éstos pueden ser valores iniciales, rangos o incrementos. Se pueden consultar los argumentos de un widget usando el comando de ayuda ?selectInput.
La aplicación widgets muestra los diferentes widgets disponibles.
Una buena manera de tener una idea del funcionamiento de cada widget es experimentar cambiando los valores de las funciones widget y observar los efectos.
Para mayores detalles sobre el diseño de esta aplicación Shiny, puede consultar la Guía de diseño de la aplicación.
La Galería de Widgets de Shiny proporciona plantillas en donde se muestra cada uno de los widgets de Shiny y cómo cambian los valores de éstos en respuesta a la entrada.
Seleccione el widget que desee y haga clic en el botón “See code” debajo del widget. La galería lo llevará a una aplicación de ejemplo que describe el widget. Para usarlo, copie y pegue el código desde el archivo de ejemplo en su archivo app.R.
En la siguiente sección, aprenderá cómo conectar widgets con una salida reactiva, que son objetos que se actualizan cada vez que el usuario cambia un widget.
Esta sección muestra cómo construir una salida reactiva para ser mostrada en una aplicación Shiny. Una salida reactiva responde automáticamente cuando un usuario cambia el valor de un widget.
Se pueden crear resultados reactivos en un proceso de dos pasos.
server. El objeto será reactivo si el código que lo construye usa el valor de un widget.Shiny proporciona una familia de funciones que convierten los objetos R en salida para la interfaz de usuario. Cada función crea un tipo específico de salida.
| Función Output | Crea |
|---|---|
| dataTableOutput | Tabla de datos |
| htmlOutput | HTML sin formato |
| imageOutput | Imagen |
| plotOutput | Gráfico |
| tableOutput | Tabla |
| textOutput | Texto |
| uiOutput | HTML sin formato |
| verbatimTextOutput | Texto |
Se pueden agregar resultados a la ui de la misma manera que se agregaron elementos HTML y widgets, esto es, dentro de sidebarPanel o mainPanel.
Por ejemplo, el siguiente código usa textOutput para agregar texto reactivo al panel principal de la aplicación.
ui <- fluidPage(
titlePanel("censusVis"),
sidebarLayout(
sidebarPanel(
helpText("Create demographic maps with information from the 2010 US Census."),
selectInput("var", label = "Choose a variable to display",
choices = c("Percent White", "Percent Black",
"Percent Hispanic", "Percent Asian"),
selected = "Percent White"),
sliderInput("range", label = "Range of interest:",
min = 0, max = 100, value = c(0, 100))
),
mainPanel(
textOutput("selected_var")
)
)
)
Esto se debe hacer en la función server, la cual crea un objeto tipo lista de nombre output que contiene todo el código necesario para actualizar los objetos R de la aplicación.
Cada objeto R necesita tener su propia entrada en la lista, cuyo nombre debe coincidir con el elemento reactivo que se creó en la ui.
En la siguiente función server, el objeto output$selected_var coincide con textOutput("selected_var") en la iu.
server <- function(input, output){
output$selected_var <- renderText({
"You have selected this"
})
}
Una aplicación con el ui y server antes definidos se muestra en census-app.
Cada entrada en el objeto output debe ser el resultado de una función render* de Shiny, la cual captura y procesa una expresión R. Se debe usar la función render* que corresponde al tipo de objeto reactivo que se está creando.
| Función render | crea |
|---|---|
renderDataTable |
Tabla de datos |
RenderImage |
Imágenes (guardadas como un enlace a un archivo fuente) |
renderPlot |
Gráfica |
renderPrint |
Cualquier salida impresa |
renderTable |
Marco de datos, matriz u otras estructuras similares a tablas |
renderText |
Cadenas de caracteres |
renderUI |
Un objeto etiqueta de Shiny o HTML |
Cada función render* tiene un solo argumento: una expresión R entre llaves, {}, que puede ser una simple línea de texto, o muchas líneas de código.
La expresión R es un conjunto de instrucciones que se guardan en Shiny y se ejecutan la primera vez que se inicie la aplicación, y se vuelven a ejecutar cada vez que se necesite actualizar el objeto.
Tal expresión debe devolver el objeto pensado (un texto, un gráfico, una tabla, etc.). Si esto no ocurre o si se devuelve un tipo de objeto incorrecto, se genera un error.
Al ejecutar la aplicación census-app, se muestra el texto “You have selected this” en el panel principal, que no es reactivo. Para que lo sea se debe usar un valor de un widget cuando se construye el texto.
Note que la función server menciona dos argumentos, input y output.
output es un objeto tipo lista que almacena las instrucciones para construir los objetos R de la aplicación.input también es un objeto tipo lista que almacena los valores actuales de los widgets de la aplicación.En la aplicación census-app se tienen dos widgets en la ui, var y range, cuyos valores se guardan en el objeto input como input$var e input$range.
Note que el control deslizante tiene dos valores (un mínimo y un máximo), por tanto el objeto input$range contendrá un vector de longitud dos.
Un objeto automáticamente se hace reactivo si usa un valor de un objeto input. Por ejemplo, la siguiente función server crea un texto reactivo, ya que usa el valor del widget del cuadro de selección.
server <- function(input, output) {
output$selected_var <- renderText({
paste("You have selected", input$var)
})
}
cuyo resultado es census-app2.
Shiny monitorea que salidas dependen de cuales widgets. Cuando un usuario cambia un widget, Shiny reconstruirá todas las salidas que dependen de éste. Como resultado, los objetos reconstruidos estarán completamente actualizados.
Así es como se crea la reactividad en Shiny, conectando los valores de objetos input a los objetos output.
Agregue una segunda línea de texto reactivo al panel principal de la aplicación Shiny, que muestre “You have chosen a range that goes from … to …”, y los “…” deben mostrar los valores mínimo (min) y máximo (max) actual del widget de barra deslizante.
No olvide que debe actualizar tanto el objeto ui como la función server.
Una solución al problema es census-app3.
*Output en la ui para colocar objetos reactivos en la aplicación Shiny.render* en el server para indicarle a Shiny cómo construir los objetos.{}, en cada función render*.render* en la lista output, con una entrada para cada objeto reactivo en la aplicación.input en una expresión render*.Shiny hará que los objetos sean reactivos automáticamente.
En la siguiente sección se creará una aplicación reactiva más sofisticada que se basa en scripts de R y datos externos.
Hemos recorrido el proceso básico de desarrollo de Shiny, de forma que podemos crear una aplicación reactiva.
El siguiente paso es avanzar a la Parte II del curso donde podrás crear una aplicación sofisticada, implementarla y compartirla con otros.