This page provides additional information about our R Shiny skeletal dysplasias web application. It is a supplement to the education exhibit “A Shiny New World: Creating Your Own Radiology Decision App Using R” presented at the Radiological Society of North America 2016 Annual Meeting in Chicago, Illinois. It provides additional details on how to use R to create interactive HTML tables. The hope is that this will be a useful example for those new to Shiny, although readers are definitely encouraged to read through Shiny’s official tutorials. Our example describes three files,
ui.R, that are used to create a Shiny app.
global.R script creates R ojects that are shared accross both
ui.R. This script is not strictly necessary, but it has a number of advantages. First, it allows you to keep all code that creates global objects in one place. Second, in many cases, you will want to reference the same objects in both
ui.R. For example, this might be the case if you want to use an object for both an R computation and to set input values in a Shiny widget. Third, objects created in
global.R are not loaded each time a new user uses the app, which is especially important if you need to load a large dataset.
Lets now take a look at
global.R in our Skeletal Dysplasia app.
The first two lines load the shiny and data.table packages respectively. The third line uses the data.table function
fread–which is a much faster version of base R’s
read.txt–to load in our dataset into a data.table object named diseases. Let’s examine the first 6 rows of diseases.
This is the dataset that we will use in our app to match features to diseases. We also want a vector of the unique features in the dataset for our users to select from. We create this vector, in alphabetical order, with the fourth line:
features <- sort(unique(diseases$feature)).
ui.R contains the code to create the user interface. The Shiny package provides a number of R functions that convert R code into html. To illustrate, consider our
ui.R script below.
titlePanel function creates a header for our webpage by transating our R code to the HTML syntax <h2>Skeletal Dysplasias</h2>.
One major advantage of Shiny is that it comes with a number of predesigned widgets. In our app, we use the
selectInput widget, which allows users to select inputs from a list of options. In the
selectInput function above, use the object features that we created in
global.R to populate the list of options (
choices = diseases). Again, this is an advantage of using
global.R. We also set
multiple = TRUE, which means that users can select more than one feature at a time, and
selected = NULL, because we don’t want any features to be initially selected for a user.
Once the inputs are selected by the user, we need to display some output. This is the purpose of the
dataTableOutput(("Table")) function, which takes an HTML table created in
server.R named “Table” and displays it to the user.
Three other functions,
fluidPage simply tell our web browser how to display our selectInput widget and our HTML table on the page.
fluidPage is especially useful because it automatically scales the components on the page to fit the browser width.
The final piece of the puzzle is
Even in our simple app, we are able to use R’s data.table package to quickly manipulate a dataset based on a user’s selections. Our aim was to help radiologists quickly determine whether a patient would be likely to have a particular given their clinical findings (which we refer to as features.) To do this, we used the
server.R code below to count the number of (user chosen) features associated with each disease.
The workhorse function in the code above is
To create the “Table” object, we manipulate the diseases data.table according to the features selected by the user (
input$features). In particular, the line,
x <- diseases[feature %in% input$features] subsets the dataset so that it only includes the user chosen features. The second line
x <- x[, .N, by = disease], counts the number of features associated with each disease. This allows us to determine which diseases are most likely to be associated with a particular set of features.
The remaining lines of code make the data.table more presentable. To be exact we sort the table so the diseases with the most matching features appear at the top of the table and give the columns reasonable names.
It’s also worth noting that since we are using the DataTable JQuery plugin, we can pass arguments from R to the DataTable. For example, in our app, we set the default text to display in an empty table as “No disease match found”. A full list of options can be found by visting the DataTable website.
Our hope is that this app will help radiologists efficiently diagnose patients given their clinical findings. Our aim is to help others create similar apps to help clinicians. Shiny is particularly advantageous because it allows developers to integrate R’s computational power with the web. We used R to quickly manipulate a dataset given user chosen options, but R’s vast array of statistical algorithms could also be used for more complicated tasks, such as predicting the probability having a disease given clinical findings.