Taking Control of Reactivity, Inputs, and Outputs

Exclusive offer: get 50% off this eBook here
Web Application Development with R Using Shiny

Web Application Development with R Using Shiny — Save 50%

Harness the graphical and statistical power of R and rapidly develop interactive user interfaces using the superb Shiny package with this book and ebook

$20.99    $10.50
by Chris Beeley | October 2013 | Open Source Web Development

This article by Chris Beeley, the author of Web Application Development with R Using Shiny, enables us to extend our toolkit by learning about advanced Shiny functions. These allow us to take control of the fine details of our application, including the interface, reactivity, data, and graphics.

In order to do this, we're going to go back to the Google Analytics application and totally upgrade it, making it much smoother, more intuitive, and well-featured. The finished code and data for this advanced GA application can be found at https://github.com/ChrisBeeley/GoogleAnalyticsAdvanced.

In this article we will do the following:

  • Learn how to show and hide parts of the interface
  • Change the interface reactively
  • Finely control reactivity so functions and outputs run at the appropriate time
  • Use URLs and reactive Shiny functions to populate and alter the selections within an interface
  • Upload and download data to and from a Shiny application
  • Use custom graphics and animations in Shiny

(For more resources related to this topic, see here.)

Showing and hiding elements of the UI

We'll start easy with a simple function that you are certainly going to need if you build even a moderately complex application. Those of you who have been doing extra credit exercises and/or experimenting with your own applications will probably have already wished for this or, indeed, have already found it. conditionalPanel() allows you to show/hide UI elements based on other selections within the UI. The function takes a condition (in JavaScript, but the form and syntax will be familiar from many languages) and a UI element, and displays the UI only when the condition is true. This is actually used a couple of times in the advanced GA application and indeed in all the applications I've ever written of even moderate complexity. The following is a simpler example (from ui.R, of course, in the first section, within sidebarPanel()), which allows users who request a smoothing line to decide what type they want:

conditionalPanel(
condition = "input.smoother == true",
selectInput("linearModel", "Linear or smoothed",
list("lm", "loess"))
)

As you can see, the condition appears very R/Shiny-like, except with the "." operator familiar to JavaScript users in place of "$", and with "true" in lower case. This is a very simple but powerful way of making sure that your UI is not cluttered with irrelevant material.

Giving names to tabPanel elements

In order to further streamline the UI, we're going to hide the hour selector when the monthly graph is displayed and the date selector when the hourly graph is displayed. The difference is illustrated in the following screenshot with side-by-side pictures, hourly figures UI on the left-hand side and monthly figures on the right-hand side:

In order to do this, we're going to have to first give the tabs of the tabbed output names. This is done as follows (with the new code in bold):

tabsetPanel(id ="theTabs",
tabPanel("Summary", textOutput("textDisplay"),
value = "summary"),
tabPanel("Monthly figures",
plotOutput("monthGraph"), value = "monthly"),
tabPanel("Hourly figures",
plotOutput("hourGraph"), value = "hourly")
)

As you can see, the whole panel is given an ID (theTabs), and then each tabPanel is also given a name (summary, monthly, and hourly). They are referred to in the server.R file very simply as input$theTabs. Let's have a quick look at a chunk of code in server.R that references the tab names; this code makes sure that we subset based on date only when the date selector is actually visible, and by hour only when the hour selector is actually visible. Our function to calculate and pass data now looks like the following (new code again bolded):

passData <- reactive({
if(input$theTabs != "hourly"){
analytics <- analytics[analytics$Date %in%
seq.Date(input$dateRange[1], input$dateRange[2],
by = "days"),]
}
if(input$theTabs != "monthly"){
analytics <- analytics[analytics$Hour %in%
as.numeric(input$minimumTime) :
as.numeric(input$maximumTime),]
}
analytics <- analytics[analytics$Domain %in%
unlist(input$domainShow),]
analytics
})

As you can see, subsetting by month is carried out only when the date display is visible (that is, when the hourly tab is not shown), and vice versa.

Finally, we can make our changes to ui.R to remove parts of the UI based on tab selection:

conditionalPanel(
condition = "input.theTabs != 'hourly'",
dateRangeInput(inputId = "dateRange",
label = "Date range",
start = "2013-04-01",
max = Sys.Date()
)
),
conditionalPanel(
condition = "input.theTabs != 'monthly'",
sliderInput(inputId = "minimumTime",
label = "Hours of interest- minimum",
min = 0,
max = 23,
value = 0,
step = 1
),
sliderInput(inputId = "maximumTime",
label = "Hours of interest- maximum",
min = 0,
max = 23,
value = 23,
step = 1)
)

Note the use in the latter example of two UI elements within the same conditionalPanel() call; it is worth noting that it helps you keep your code clean and easy to debug.

Reactive user interfaces

Another trick you will definitely want up your sleeve at some point is a reactive user interface. This enables you to change your UI (for example, the number or content of radio buttons) based on reactive functions. For example, consider an application that I wrote related to survey responses across a broad range of health services in different areas. The services are related to each other in quite a complex hierarchy, and over time, different areas and services respond (or cease to exist, or merge, or change their name...), which means that for each time period the user might be interested in, there would be a totally different set of areas and services. The only sensible solution to this problem is to have the user tell you which area and date range they are interested in and then give them back the correct list of services that have survey responses within that area and date range.

The example we're going to look at is a little simpler than this, just to keep from getting bogged down in too much detail, but the principle is exactly the same and you should not find this idea too difficult to adapt to your own UI. We are going to imagine that your users are interested in the individual domains from which people are accessing the site, rather than just have them lumped together as the NHS domain and all others. To this end, we will have a combo box with each individual domain listed. This combo box is likely to contain a very high number of domains across the whole time range, so we will let users constrain the data by date and only have the domains that feature in that range return. Not the most realistic example, but it will illustrate the principle for our purposes.

Reactive user interface example – server.R

The big difference is that instead of writing your UI definition in your ui.R file, you place it in server.R, and wrap it in renderUI(). Then all you do is point to it from your ui.R file. Let's have a look at the relevant bit of the server.R file:

output$reacDomains <- renderUI({
domainList = unique(as.character(passData()$networkDomain))
selectInput("subDomains", "Choose subdomain", domainList)
})

The first line takes the reactive dataset that contains only the data between the dates selected by the user and gives all the unique values of domains within it. The second line is a widget type we have not used yet which generates a combo box. The usual id and label arguments are given, followed by the values that the combo box can take. This is taken from the variable defined in the first line.

Reactive user interface example – ui.R

The ui.R file merely needs to point to the reactive definition as shown in the following line of code (just add it in to the list of widgets within sidebarPanel()):

uiOutput("reacDomains")

You can now point to the value of the widget in the usual way, as input$subDomains. Note that you do not use the name as defined in the call to renderUI(), that is, reacDomains, but rather the name as defined within it, that is, subDomains.

Summary

It's a relatively small but powerful toolbox with which you can build a vast array of useful and intuitive applications with comparatively little effort.

This article looked at fine-tuning the UI using conditionalPanel() and observe(), and changing our UI reactively.

Resources for Article:


Further resources on this subject:


Web Application Development with R Using Shiny Harness the graphical and statistical power of R and rapidly develop interactive user interfaces using the superb Shiny package with this book and ebook
Published: October 2013
eBook Price: $20.99
Book Price: $34.99
See more
Select your format and quantity:

About the Author :


Chris Beeley

Chris Beeley is an Applied Researcher working in healthcare in the UK. He completed his PhD in Psychology at the University of Nottingham in 2009 and now works with Nottinghamshire Healthcare NHS Trust providing statistical analysis and other types of evaluation and reporting using routine data generated within the Trust. Chris has a special interest in the use of regression methods in applied healthcare settings, particularly forensic psychiatric settings, as well as in the collection, analysis, and reporting of patient feedback data.

Chris has been a keen user of R and a passionate advocate of open-source tools within research and healthcare settings since completing his PhD. He has made extensive use of R (and Shiny) to automate analysis and reporting for new patient feedback websites. This was funded by a grant from the NHS Institute for Innovation and made in collaboration with staff, service users, and carers within the Trust, particularly individuals from the Involvement Center.

Books From Packt


Web Application Development with Yii and PHP
Web Application Development with Yii and PHP

Agile Web Application Development with Yii1.1 and PHP5
Agile Web Application Development with Yii1.1 and PHP5

Mastering Web Application Development with AngularJS
Mastering Web Application Development with AngularJS

Learning RStudio for R Statistical Computing
Learning RStudio for R Statistical Computing

Spring Web Flow 2 Web Development
Spring Web Flow 2 Web Development

Node Web Development - Second Edition
Node Web Development - Second Edition

HTML5 iPhone Web Application Development
HTML5 iPhone Web Application Development

Express Web Application Development
Express Web Application Development


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
2
V
x
t
a
p
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software