Developing a single-file Shiny app

Shiny apps probably were one of the most game-changing products developed by RStudio.

These apps, because of their ability to link the analytical environment to the production one, are great instruments in the hands of developers and researchers interested in transforming their work into an actual data-driven product.

In this recipe, I will introduce you to the single-file app, which is becoming the standard for Shiny app development.

When Shiny was first introduced, apps had to be composed of two separate files: one for the user interface and another for the server logic.

Among several refinements and improvements, the RStudio team later introduced a way to produce a Shiny app contained within a single R script. This app is named app.R.

Getting ready

First, we need to install the Shiny package and load it in the R environment:

Install.packages('shiny')
library(shiny)

How to do it…

  1. Create an app.R file.
  2. Add a call to the Shiny package:
    library(shiny)
  3. Create a ui object:
    ui <- fluidPage()
  4. Create a server object:
    server ← function(input,output) { }
  5. Define a reactive data frame:
    dataset <- reactive({
        subset(iris,iris$Species == input$species  & iris$Petal.Length >= input$range[1] & iris$Petal.Length <= input$range[2])
      })
  6. Define a table object within your server, depending on the data frame:
    output$table <- renderTable({dataset()})
  7. Define a plot object within your server, depending on the data frame:
    output$plot <- renderPlot({
        plot(x=dataset()$Sepal.Length,y=dataset()$Sepal.Width)
  8. Add a title to your ui object:
    h1("custom filtering and visualization of your dataset"),
  9. Add a brief description of your app:
    p("using this app you can easily filter the iris dataset, choosing which species
        to show and which range of Sepal.Length to consider"),
  10. Add a radio button control to your UI to select a species:
    radioButtons('species',label='select the species you want to focus on',c("virginica","versicolor","setosa"),),
  11. Add a slider control to filter the data frame based on the Petal.Length value:
    sliderInput('range', label= 'select a range for Petal.Length attribute',min= 1,max = 6.9, value = c(1,6.9)),
  12. Add a plot output to your ui object:
    plotOutput('plot'),
  13. Add a table output to your ui object:
    tableOutput('table')
  14. Execute your code:
    Source("app.R")
  15. Run your app:
    shinyApp(ui=ui,server=server)

    Running this code will make your Shiny application show up:

    How to do it…

How it works…

We first created an R file that will contain all the code to compose your Shiny app. Be aware that naming the file app.R is mandatory.

The call to the Shiny package will make Shiny functions available to the app environment.

The logical framework behind Shiny requires every app to be composed of two main parts:

  • User interface (UI): This shows the user all available input controls and all elaboration results
  • Server logic: This actually contains the code that reacts to user inputs and prepares the results to be shown to the user

We thus initialized the user interface of our app.

We then initialized the server logic of our app, which is defined as a function that has an argument input and output.

  • input: This stores all user choices, captured from the input controls on the user interface
  • output: This stores all the object resulting from server elaboration, making them available to the user interface

The two arguments are assumed to be of the list type.

The next step involves a core concept of the Shiny framework: reactivity. Reactivity is the ability to intercept user choices and actions, and consequently trigger pieces of code and concatenate pieces of code if any.

Let's visualize the flow:

  • In the UI, the user specifies a choice, for instance, within the iris dataset, let me see only the observation pertaining to the versicolor species.
  • Within the server logic, a reactive() function intercepts this choice and reacts to it, filtering the iris dataset accordingly and giving us an output of a dataset object of the data frame type.
  • Still within the server logic, a renderplot() function reacts to the reactive() function filtering, since it has the dataset object within its brackets. The renderplot() function takes this modified dataset object as an input and gives a plot object as an output.
  • On the UI side, a plotOutput function reacts to the change of plot object on the server side, since it has this object as an argument. Consequently, plotOutput shows a plot for the iris dataset filtered on the versicolor species.

That's it. The user's choice generates a long chain of actions and reactions that produce the final updated output.

However, here are two warnings:

  • The reactive() function must include curly brackets, for instance, reactive({ iris})
  • When you refer to the output of a reactive function, you need to add a () token on the right-hand side of the object, for instance, Dataset()

If you want to select an attribute of the object, you could add the usual dollar symbol or squared brackets.

We then created a table object that will let us show our filtered dataset to the user. Be aware of the use of renderTable({}), which is a special case of the more general reactive() function. We then defined a plot object, leveraging the renderPlot({}) function.

We then skipped to the ui side, adding a title.

You can write text using the following functions:

  • H1()
  • H2()
  • H3()
  • H4()
  • H5()
  • H6()
  • P()

While the first six functions are equivalent to the HTML title's tags, the last one is a general function for paragraph writing, corresponding to the HTML <p></p> tag.

We then used the p() function shown earlier.

Next, we actually added an input control, in the form of a radio button, which required us to perform only one choice among many.

We specified the following:

  • The ID of the control to be used within the server logic to retrieve choices performed by the user
  • The label, a piece of text to be shown to the user to help them make a choice
  • The available choices, in the form of a vector
  • The default choice

In a way similar to what we have done with the radio buttons, we add a slider control to let the user specify a range for the Petal.Length variable of the iris dataset. The main difference here is the presence of a minimum and maximum value, used to specify the available range of choice.

In the UI, we add two functions that will let us show the plot defined in the server logic named plot and the table named table.

In order to see your app, you have to execute your code to actually make the ui and server objects available within the environment.

Running your app just requires you to run a line of code in which you specify which objects Shiny should consider as ui and server objects.

See also

  • Shiny apps deserved a separate section of the RStudio website at http://shiny.rstudio.com.

    In this website, you can find a lot of learning material to get you up and running with Shiny, from easy tutorials to advanced topics.

  • In particular, I suggest that you further explore the UI controls that are available, in the reference section and the UI controls subsection: http://shiny.rstudio.com/reference/shiny/latest/.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset