The basic parts of a Shiny app
The Shiny package comes with eleven built-in examples that demonstrate how Shiny works. This article reviews the first three examples, which demonstrate the basic structure of a Shiny app.
Example 1: Hello Shiny
The Hello Shiny example is a simple application that plots R’s built-in
faithful dataset with a configurable number of bins. To run the example, type:
Shiny applications have two components, a user interface object and a server function, that are passed as arguments to the
shinyApp function that creates a Shiny app object from this UI/server pair. The source code for both of these components is listed below.
In subsequent sections of the article we’ll break down Shiny code in detail and explain the use of “reactive” expressions for generating output. For now, though, just try playing with the sample application and reviewing the source code to get an initial feel for things. Be sure to read the comments carefully.
The user interface is defined as follows:
The server-side of the application is shown below. At one level, it’s very simple – a random distribution is plotted as a histogram with the requested number of bins. However, you’ll also notice that the code that generates the plot is wrapped in a call to
renderPlot. The comment above the function explains a bit about this, but if you find it confusing, don’t worry, we’ll cover this concept in much more detail soon.
Finally, we use the
shinyApp function to create a Shiny app object from the UI/server pair that we defined above.
We save all of this code, the
ui object, the
server function, and the call to the
shinyApp function, in an R script called
app.R. This is the same basic structure for all Shiny applications.
The next example will show the use of more input controls, as well as the use of reactive functions to generate textual output.
Example 2: Shiny Text
The Shiny Text application demonstrates printing R objects directly, as well as displaying data frames using HTML tables. To run the example, type:
The first example had a single numeric input specified using a slider and a single plot output. This example has a bit more going on: two inputs and two types of textual output.
If you try changing the number of observations to another value, you’ll see a demonstration of one of the most important attributes of Shiny applications: inputs and outputs are connected together “live” and changes are propagated immediately (like a spreadsheet). In this case, rather than the entire page being reloaded, just the table view is updated when the number of observations change.
Here is the user interface object for the application. Notice in particular that the
mainPanel functions are now called with two arguments (corresponding to the two inputs and two outputs displayed):
The server side of the application has also gotten a bit more complicated. Now we create:
- A reactive expression to return the dataset corresponding to the user choice
- Two other rendering expressions (
renderTable) that return the
These expressions work similarly to the
renderPlot expression used in the first example: by declaring a rendering expression you tell Shiny that it should only be executed when its dependencies change. In this case that’s either one of the user input values (
We’ve demonstrated more use of reactive expressions but haven’t really explained how they work yet. The next example will start with this one as a baseline and expand significantly on how reactive expressions work in Shiny.
Example 3: Reactivity
The Reactivity application is very similar to Hello Text, but goes into much more detail about reactive programming concepts. To run the example, type:
The previous examples have given you a good idea of what the code for Shiny applications looks like. We’ve explained a bit about reactivity, but mostly glossed over the details. In this section, we’ll explore these concepts more deeply. If you want to dive in and learn about the details, see the Understanding Reactivity section, starting with Reactivity Overview.
What is Reactivity?
The Shiny web framework is fundamentally about making it easy to wire up input values from a web page, making them easily available to you in R, and have the results of your R code be written as output values back out to the web page.
input values => R code => output values
Since Shiny web apps are interactive, the input values can change at any time, and the output values need to be updated immediately to reflect those changes.
Shiny comes with a reactive programming library that you will use to structure your application logic. By using this library, changing input values will naturally cause the right parts of your R code to be reexecuted, which will in turn cause any changed outputs to be updated.
Reactive Programming Basics
Reactive programming is a coding style that starts with reactive values–values that change in response to the user, or over time–and builds on top of them with reactive expressions–expressions that access reactive values and execute other reactive expressions.
What’s interesting about reactive expressions is that whenever they execute, they automatically keep track of what reactive values they read and what reactive expressions they invoked. If those “dependencies” become out of date, then they know that their own return value has also become out of date. Because of this dependency tracking, changing a reactive value will automatically instruct all reactive expressions that directly or indirectly depend on that value to re-execute.
The most common way you’ll encounter reactive values in Shiny is using the
input object. The
input object, which is passed to your
shinyServer function, lets you access the web page’s user input fields using a list-like syntax. Code-wise, it looks like you’re grabbing a value from a list or data frame, but you’re actually reading a reactive value. No need to write code to monitor when inputs change–just write reactive expression that read the inputs they need, and let Shiny take care of knowing when to call them.
It’s simple to create reactive expression: just pass a normal expression into
reactive. In this application, an example of that is the expression that returns an R data frame based on the selection the user made in the input form:
To turn reactive values into outputs that can viewed on the web page, we assigned them to the
output object (also passed to the
shinyServer function). Here is an example of an assignment to an output that depends on both the
datasetInput reactive expression we just defined, as well as
This expression will be re-executed (and its output re-rendered in the browser) whenever either the
input$obs value changes.
Back to the Code
Now that we’ve taken a deeper look at some of the core concepts, let’s revisit the source code for the Reactivity example and try to understand what’s going on in more depth. The user interface object has been updated to include a text-input field that defines a caption. Other than that it’s very similar to the previous example:
The server function declares the
datasetInput reactive expression as well as three reactive output values. There are detailed comments for each definition that describe how it works within the reactive system:
We’ve reviewed a lot code and covered a lot of conceptual ground in the first three examples. The next article focuses on the mechanics of building a Shiny application from the ground up.
We love it when R users help each other, but RStudio does not monitor or answer the comments in this thread. If you'd like to get specific help, we recommend the RStudio Community as well as the Shiny Discussion Forum for in depth discussion of Shiny related questions and How to get help article for a list of the best ways to get help with R code.comments powered by Disqus