For many users of Shiny, it is simply a tool for building interactive web content with R. Where a user knows a little more about how Shiny works; it is a reactive programming model that allows interactions to be communicated back and forth between a browser (the client or the ui.R file) and a server running R (via the function defined within the server.R file).
This tutorial introduces you to the basics of “reactive expressions”, and uses the following Shiny app embedded below as a tutorial. To access the code for the Shiny app click the “Fork me on Github” ribbon in the top-right.
The Shiny app generates random data and visualises it in a histogram using, essentially, the following code:
user_selected_mean <- 3
user_typed_title <- "Hello World"
hist(rnorm(100, mean = 3, sd = 1),
main = user_typed_title)
In the ui.R there are two different plots shown::
renderPlot
(and the new data is generated whenever you type)eventReactive
(typing does not generate new random data)column(
"Uncontrolled updating",
plotOutput("histogram_renderPlot"),
width = 6
),
column(
"Controlled updating",
plotOutput("histogram_eventReactive"),
width = 6
)
The server.R file contains the following code for generating the “histogram_renderPlot” output:
output$histogram_renderPlot <- renderPlot({
hist_data <- rnorm(100, mean = input$mean, sd = 4)
hist(hist_data,
main = input$plot_label)
})
All render*
functions behave in the same way; they watch for any changes to input$*
variables and invalidate themselves. Once invalidated, the entire expression re-evaluates. Meaning that any time input$plot_label
is changed, new hist_data
values will be computed.
There are many options available for controlling the reactivity if a Shiny app (RStudio provides a wonderful overview of reactivity). This template makes use of the simplest available option to us: eventReactive
hist_data_eventReactive <- eventReactive(c(input$mean),
{
rnorm(100, mean = input$mean, sd = 4)
})
The arguments of eventReactive
are as follows:
input$*
variables that should be watchedinput$*
variables in the first argument is changed.eventReactive
creates a “reactive expression object” that, when called, will return the output of its second argument. This can be seen in the template app as follows:
output$histogram_eventReactive <- renderPlot({
hist_data <- hist_data_eventReactive()
hist(hist_data,
main = input$plot_label)
})
The renderPlot
expression retains its reactivity to input$plot_label
, but now the hist_data
will only update when the “reactive expression object” hist_data_eventReactive()
changes.
render*
functions are sensitive to every input$*
change, unless you write additional codeeventReactive
is a useful control structure where “this value should be recomputed because X changes”hist_data_eventReactive()
needs the ()
to function. Sadly there is not a specific error for this, just try and be careful with your typing.