This article covers the following topics:
An introduction to the Shiny app framework
Creating your first Shiny app
The connection between the server file and the user interface
The concept of reactive programming
Different types of interface layouts, widgets, and Shiny tags
How to create a dynamic user interface
Ways to share your Shiny applications with others
How to deploy Shiny apps to the web
(For more resources related to this topic, see here.)
Introducing Shiny – the app framework
The Shiny package delivers a powerful framework to build fully featured interactive Web applications just with R and RStudio. Basic Shiny applications typically consist of two components:
~/shinyapp
|-- ui.R
|-- server.R
While the ui.R function represents the appearance of the user interface, the server.R function contains all the code for the execution of the app. The look of the user interface is based on the famous Twitter bootstrap framework, which makes the look and layout highly customizable and fully responsive. In fact, you only need to know R and how to use the shiny package to build a pretty web application. Also, a little knowledge of HTML, CSS, and JavaScript may help.
If you want to check the general possibilities and what is possible with the Shiny package, it is advisable to take a look at the inbuilt examples. Just load the library and enter the example name:
library(shiny)
runExample("01_hello")
As you can see, running the first example opens the Shiny app in a new window. This app creates a simple histogram plot where you can interactively change the number of bins. Further, this example allows you to inspect the corresponding ui.R and server.R code files.
There are currently eleven inbuilt example apps:
01_hello
02_text
03_reactivity
04_mpg
05_sliders
06_tabsets
07_widgets
08_html
09_upload
10_download
11_timer
These examples focus mainly on the user interface possibilities and elements that you can create with Shiny.
Creating a new Shiny web app with RStudio
RStudio offers a fast and easy way to create the basis of every new Shiny app. Just click on New Project and select the New Directory option in the newly opened window:
After that, click on the Shiny Web Application field:
Give your new app a name in the next step, and click on Create Project:
RStudio will then open a ready-to-use Shiny app by opening a prefilled ui.R and server.R file:
You can click on the now visible Run App button in the right corner of the file pane to display the prefilled example application.
Creating your first Shiny application
In your effort to create your first Shiny application, you should first create or consider rough sketches for your app. Questions that you might ask in this context are, What do I want to show? How do I want it to show?, and so on.
Let's say we want to create an application that allows users to explore some of the variables of the mtcars dataset.
The data was extracted from the 1974 Motor Trend US magazine, and comprises fuel consumption and 10 aspects of automobile design and performance for 32 automobiles (1973–74 models).
Sketching the final app
We want the user of the app to be able to select one out of the three variables of the dataset that gets displayed in a histogram. Furthermore, we want users to get a summary of the dataset under the main plot. So, the following figure could be a rough project sketch:
Constructing the user interface for your app
We will reuse the already opened ui.R file from the RStudio example, and adapt it to our needs. The layout of the ui.R file for your first app is controlled by nested Shiny functions and looks like the following lines:
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("My First Shiny App"),
sidebarPanel(
selectInput(inputId =
"variable",
label = "Variable:",
choices = c
("Horsepower" = "hp",
"Miles
per Gallon" = "mpg",
"Number
of Carburetors" = "carb"),
selected = "hp")
),
mainPanel(
plotOutput("carsPlot"),
verbatimTextOutput
("carsSummary")
)
))
Creating the server file
The server file holds all the code for the execution of the application:
library(shiny)
library(datasets)
shinyServer(function(input, output) {
output$carsPlot <- renderPlot({
hist(mtcars[,input$variable],
main = "Histogram of mtcars
variables",
xlab = input$variable)
})
output$carsSummary <- renderPrint({
summary(mtcars[,input$variable])
})
})
The final application
After changing the ui.R and the server.R files according to our needs, just hit the Run App button and the final app opens in a new window:
As planned in the app sketch, the app offers the user a drop-down menu to choose the desired variable on the left side, and shows a histogram and data summary of the selected variable on the right side.
Deconstructing the final app into its components
For a better understanding of the Shiny application logic and the interplay of the two main files, ui.R and server.R, we will disassemble your first app again into its individual parts.
The components of the user interface
We have divided the user interface into three parts:
After loading the Shiny library, the complete look of the app gets defined by the shinyUI() function. In our app sketch, we chose a sidebar look; therefore, the shinyUI function holds the argument, pageWithSidebar():
library(shiny)
shinyUI(pageWithSidebar(
...
The headerPanel() argument is certainly the simplest component, since usually only the title of the app will be stored in it. In our ui.R file, it is just a single line of code:
library(shiny)
shinyUI(pageWithSidebar(
titlePanel("My First Shiny App"),
...
The sidebarPanel() function defines the look of the sidebar, and most importantly, handles the input of the variables of the chosen mtcars dataset:
library(shiny)
shinyUI(pageWithSidebar(
titlePanel("My First Shiny App"),
sidebarPanel(
selectInput(inputId =
"variable",
label = "Variable:",
choices = c
("Horsepower" = "hp",
"Miles
per Gallon" = "mpg",
"Number
of Carburetors" = "carb"),
selected = "hp")
),
...
Finally, the mainPanel() function ensures that the output is displayed. In our case, this is the histogram and the data summary for the selected variables:
library(shiny)
shinyUI(pageWithSidebar(
titlePanel("My First Shiny App"),
sidebarPanel(
selectInput(inputId =
"variable",
label = "Variable:",
choices = c
("Horsepower" = "hp",
"Miles
per Gallon" = "mpg",
"Number
of Carburetors" = "carb"),
selected = "hp")
),
mainPanel(
plotOutput("carsPlot"),
verbatimTextOutput
("carsSummary")
)
))
The server file in detail
While the ui.R file defines the look of the app, the server.R file holds instructions for the execution of the R code. Again, we use our first app to deconstruct the related server.R file into its main important parts. After loading the needed libraries, datasets, and further scripts, the function, shinyServer(function(input, output) {} ), defines the server logic:
library(shiny)
library(datasets)
shinyServer(function(input, output)
{
The marked lines of code that follow translate the inputs of the ui.R file into matching outputs. In our case, the server side output$ object is assigned to carsPlot, which in turn was called in the mainPanel() function of the ui.R file as plotOutput(). Moreover, the render* function, in our example it is renderPlot(), reflects the type of output. Of course, here it is the histogram plot. Within the renderPlot() function, you can recognize the input$ object assigned to the variables that were defined in the user interface file:
library(shiny)
library(datasets)
shinyServer(function(input, output) {
output$carsPlot <- renderPlot({
hist(mtcars[,input$variable],
main = "Histogram of mtcars variables",
xlab = input$variable)
})
...
In the following lines, you will see another type of the render function, renderPrint() , and within the curly braces, the actual R function, summary(), with the defined input variable:
library(shiny)
library(datasets)
shinyServer(function(input, output) {
output$carsPlot <- renderPlot({
hist(mtcars[,input$variable],
main = "Histogram of mtcars variables",
xlab = input$variable)
})
output$carsSummary <- renderPrint({
summary(mtcars[,input$variable])
})
})
There are plenty of different render functions. The most used are as follows:
renderPlot: This creates normal plots
renderPrin: This gives printed output types
renderUI: This gives HTML or Shiny tag objects
renderTable: This gives tables, data frames, and matrices
renderText: This creates character strings
Every code outside the shinyServer() function runs only once on the first launch of the app, while all the code in between the brackets and before the output functions runs as often as a user visits or refreshes the application. The code within the output functions runs every time a user changes the widget that belongs to the corresponding output.
The connection between the server and the ui file
As already inspected in our decomposed Shiny app, the input functions of the ui.R file are linked with the output functions of the server file. The following figure illustrates this again:
The concept of reactivity
Shiny uses a reactive programming model, and this is a big deal. By applying reactive programming, the framework is able to be fast, efficient, and robust. Briefly, changing the input in the user interface, Shiny rebuilds the related output. Shiny uses three reactive objects:
Reactive source
Reactive conductor
Reactive endpoint
For simplicity, we use the formal signs of the RStudio documentation:
The implementation of a reactive source is the reactive value; that of a reactive conductor is a reactive expression; and the reactive endpoint is also called the observer.
The source and endpoint structure
As taught in the previous section, the defined input of the ui.R links is the output of the server.R file. For simplicity, we use the code from our first Shiny app again, along with the introduced formal signs:
...
output$carsPlot <- renderPlot({
hist(mtcars[,input$variable],
main = "Histogram of mtcars variables",
xlab = input$variable)
})
...
The input variable, in our app these are the Horsepower; Miles per Gallon, and Number of Carburetors choices, represents the reactive source. The histogram called carsPlot stands for the reactive endpoint. In fact, it is possible to link the reactive source to numerous reactive endpoints, and also conversely. In our Shiny app, we also connected the input variable to our first and second output—carsSummary:
...
output$carsPlot <- renderPlot({
hist(mtcars[,input$variable],
main = "Histogram of mtcars variables",
xlab = input$variable)
})
output$carsSummary <- renderPrint({
summary(mtcars[,input$variable])
})
...
To sum it up, this structure ensures that every time a user changes the input, the output refreshes automatically and accordingly.
The purpose of the reactive conductor
The reactive conductor differs from the reactive source and the endpoint is so far that this reactive type can be dependent and can have dependents. Therefore, it can be placed between the source, which can only have dependents and the endpoint, which in turn can only be dependent. The primary function of a reactive conductor is the encapsulation of heavy and difficult computations. In fact, reactive expressions are caching the results of these computations. The following graph displays a possible connection of the three reactive types:
In general, reactivity raises the impression of a logically working directional system; after input, the output occurs. You get the feeling that an input pushes information to an output. But this isn't the case. In reality, it works vice versa. The output pulls the information from the input. And this all works due to sophisticated server logic. The input sends a callback to the server, which in turn informs the output that pulls the needed value from the input and shows the result to the user. But of course, for a user, this all feels like an instant updating of any input changes, and overall, like a responsive app's behavior. Of course, we have just touched upon the main aspects of reactivity, but now you know what's really going on under the hood of Shiny.
Discovering the scope of the Shiny user interface
After you know how to build a simple Shiny application, as well as how reactivity works, let us take a look at the next step: the various resources to create a custom user interface. Furthermore, there are nearly endless possibilities to shape the look and feel of the layout. As already mentioned, the entire HTML, CSS, and JavaScript logic and functions of the layout options are based on the highly flexible bootstrap framework. And, of course, everything is responsive by default, which makes it possible for the final application layout to adapt to the screen of any device.
Exploring the Shiny interface layouts
Currently, there are four common shinyUI () page layouts:
pageWithSidebar()
fluidPage()
navbarPage()
fixedPage()
These page layouts can be, in turn, structured with different functions for a custom inner arrangement structure of the page layout. In the following sections, we are introducing the most useful inner layout functions. As an example, we will use our first Shiny application again.
The sidebar layout
The sidebar layout, where the sidebarPanel() function is used as the input area, and the mainPanel() function as the output, just like in our first Shiny app. The sidebar layout uses the pageWithSidebar() function:
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("The Sidebar Layout"),
sidebarPanel(
selectInput(inputId = "variable",
label = "This is the sidebarPanel",
choices = c("Horsepower" = "hp",
"Miles per Gallon" = "mpg",
"Number of Carburetors" = "carb"),
selected = "hp")
),
mainPanel(
tags$h2("This is the mainPanel"),
plotOutput("carsPlot"),
verbatimTextOutput("carsSummary")
)
))
When you only change the first three functions, you can create exactly the same look as the application with the fluidPage() layout. This is the sidebar layout with the fluidPage() function:
library(shiny)
shinyUI(fluidPage(
titlePanel("The Sidebar Layout"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "variable",
label = "This is the sidebarPanel",
choices = c("Horsepower" = "hp",
"Miles per Gallon" = "mpg",
"Number of Carburetors" = "carb"),
selected = "hp")
),
mainPanel(
tags$h2("This is the mainPanel"),
plotOutput("carsPlot"),
verbatimTextOutput("carsSummary")
)
)
))
The grid layout
The grid layout is where rows are created with the fluidRow() function. The input and output are made within free customizable columns. Naturally, a maximum of 12 columns from the bootstrap grid system must be respected. This is the grid layout with the fluidPage () function and a 4-8 grid:
library(shiny)
shinyUI(fluidPage(
titlePanel("The Grid Layout"),
fluidRow(
column(4,
selectInput(inputId = "variable",
label = "Four-column input area",
choices = c("Horsepower" = "hp",
"Miles per Gallon" = "mpg",
"Number of Carburetors" = "carb"),
selected = "hp")
),
column(8,
tags$h3("Eight-column output area"),
plotOutput("carsPlot"),
verbatimTextOutput("carsSummary")
)
)
))
As you can see from inspecting the previous ui.R file, the width of the columns is defined within the fluidRow() function, and the sum of these two columns adds up to 12. Since the allocation of the columns is completely flexible, you can also create something like the grid layout with the fluidPage() function and a 4-4-4 grid:
library(shiny)
shinyUI(fluidPage(
titlePanel("The Grid Layout"),
fluidRow(
column(4,
selectInput(inputId = "variable",
label = "Four-column input area",
choices = c("Horsepower" = "hp",
"Miles per Gallon" = "mpg",
"Number of Carburetors" = "carb"),
selected = "hp")
),
column(4,
tags$h5("Four-column output area"),
plotOutput("carsPlot")
),
column(4,
tags$h5("Another four-column output area"),
verbatimTextOutput("carsSummary")
)
)
))
The tabset panel layout
The tabsetPanel() function can be built into the mainPanel() function of the aforementioned sidebar layout page. By applying this function, you can integrate several tabbed outputs into one view. This is the tabset layout with the fluidPage() function and three tab panels:
library(shiny)
shinyUI(fluidPage(
titlePanel("The Tabset Layout"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "variable",
label = "Select a variable",
choices = c("Horsepower" = "hp",
"Miles per Gallon" = "mpg",
"Number of Carburetors" = "carb"),
selected = "hp")
),
mainPanel(
tabsetPanel(
tabPanel("Plot", plotOutput("carsPlot")),
tabPanel("Summary", verbatimTextOutput("carsSummary")),
tabPanel("Raw Data", dataTableOutput("tableData"))
)
)
)
))
After changing the code to include the tabsetPanel() function, the three tabs with the tabPanel() function display the respective output. With the help of this layout, you are no longer dependent on representing several outputs among themselves. Instead, you can display each output in its own tab, while the sidebar does not change. The position of the tabs is flexible and can be assigned to be above, below, right, and left. For example, in the following code file detail, the position of the tabsetPanel() function was assigned as follows:
...
mainPanel(
tabsetPanel(position = "below",
tabPanel("Plot", plotOutput("carsPlot")),
tabPanel("Summary", verbatimTextOutput("carsSummary")),
tabPanel("Raw Data", tableOutput("tableData"))
)
)
...
The navlist panel layout
The navlistPanel() function is similar to the tabsetPanel() function, and can be seen as an alternative if you need to integrate a large number of tabs. The navlistPanel() function also uses the tabPanel() function to include outputs:
library(shiny)
shinyUI(fluidPage(
titlePanel("The Navlist Layout"),
navlistPanel(
"Discovering The Dataset",
tabPanel("Plot", plotOutput("carsPlot")),
tabPanel("Summary", verbatimTextOutput("carsSummary")),
tabPanel("Another Plot", plotOutput("barPlot")),
tabPanel("Even A Third Plot", plotOutput("thirdPlot"),
"More Information",
tabPanel("Raw Data", tableOutput("tableData")),
tabPanel("More Datatables", tableOutput("moreData"))
)
))
The navbar page as the page layout
In the previous examples, we have used the page layouts, fluidPage() and pageWithSidebar(), in the first line. But, especially when you want to create an application with a variety of tabs, sidebars, and various input and output areas, it is recommended that you use the navbarPage() layout. This function makes use of the standard top navigation of the bootstrap framework:
library(shiny)
shinyUI(navbarPage("The Navbar Page Layout",
tabPanel("Data Analysis",
sidebarPanel(
selectInput(inputId = "variable",
label = "Select a variable",
choices = c("Horsepower" = "hp",
"Miles per Gallon" = "mpg",
"Number of Carburetors" = "carb"),
selected = "hp")
),
mainPanel(
plotOutput("carsPlot"),
verbatimTextOutput("carsSummary")
)
),
tabPanel("Calculations"
…
),
tabPanel("Some Notes"
…
)
))
Adding widgets to your application
After inspecting the most important page layouts in detail, we now look at the different interface input and output elements. By adding these widgets, panels, and other interface elements to an application, we can further customize each page layout.
Shiny input elements
Already, in our first Shiny application, we got to know a typical Shiny input element: the selection box widget. But, of course, there are a lot more widgets with different types of uses. All widgets can have several arguments; the minimum setup is to assign an inputId, which instructs the input slot to communicate with the server file, and a label to communicate with a widget. Each widget can also have its own specific arguments.
As an example, we are looking at the code of a slider widget. In the previous screenshot are two versions of a slider; we took the slider range for inspection:
sliderInput(inputId = "sliderExample",
label = "Slider range",
min = 0,
max = 100,
value = c(25, 75))
Besides the mandatory arguments, inputId and label, three more values have been added to the slider widget. The min and max arguments specify the minimum and maximum values that can be selected. In our example, these are 0 and 100. A numeric vector was assigned to the value argument, and this creates a double-ended range slider. This vector must logically be within the set minimum and maximum values.
Currently, there are more than twenty different input widgets, which in turn are all individually configurable by assigning to them their own set of arguments.
A brief overview of the output elements
As we have seen, the output elements in the ui.R file are connected to the rendering functions in the server file. The mainly used output elements are:
htmlOutput
imageOutput
plotOutput
tableOutput
textOutput
verbatimTextOutput
downloadButton
Due to their unambiguous naming, the purpose of these elements should be clear.
Individualizing your app even further with Shiny tags
Although you don't need to know HTML to create stunning Shiny applications, you have the option to create highly customized apps with the usage of raw HTML or so-called Shiny tags. To add raw HTML, you can use the HTML() function. We will focus on Shiny tags in the following list. Currently, there are over a 100 different Shiny tag objects, which can be used to add text styling, colors, different headers, visual and audio, lists, and many more things. You can use these tags by writing tags $tagname. Following is a brief list of useful tags:
tags$h1: This is first level header; of course you can also use the known h1 -h6
tags$hr: This makes a horizontal line, also known as a thematic break
tags$br: This makes a line break, a popular way to add some space
tags$strong = This makes the text bold
tags$div: This makes a division of text with a uniform style
tags$a: This links to a webpage
tags$iframe: This makes an inline frame for embedding possibilities
The following ui.R file and corresponding screenshot show the usage of Shiny tags by an example:
shinyUI(fluidPage(
fluidRow(
column(6,
tags$h3("Customize your app with Shiny tags!"),
tags$hr(),
tags$a(href = "http://www.rstudio.com", "Click me"),
tags$hr()
),
column(6,
tags$br(),
tags$em("Look - the R project logo"),
tags$br(),
tags$img(src = "http://www.r-project.org/Rlogo.png")
)
),
fluidRow(
column(6,
tags$strong("We can even add a video"),
tags$video(src = "video.mp4", type = "video/mp4", autoplay = NA, controls = NA)
),
column(6,
tags$br(),
tags$ol(
tags$li("One"),
tags$li("Two"),
tags$li("Three"))
)
)
))
Creating dynamic user interface elements
We know how to build completely custom user interfaces with all the bells and whistles. But all the introduced types of interface elements are fixed and static. However, if you need to create dynamic interface elements, Shiny offers three ways to achieve it:
The conditinalPanel() function:
The renderUI() function
The use of directly injected JavaScript code
In the following section, we only show how to use the first two ways, because firstly, they are built into the Shiny package, and secondly, the JavaScript method is indicated as experimental.
Using conditionalPanel
The condtionalPanel() functions allow you to show or hide interface elements dynamically, and is set in the ui.R file. The dynamic of this function is achieved by JavaScript expressions, but as usual in the Shiny package, all you need to know is R programming.
The following example application shows how this function works for the ui.R file:
library(shiny)
shinyUI(fluidPage(
titlePanel("Dynamic Interface With Conditional Panels"),
column(4, wellPanel(
sliderInput(inputId = "n",
label= "Number of points:",
min = 10, max = 200, value = 50, step = 10)
)),
column(5,
"The plot below will be not displayed when the slider value",
"is less than 50.",
conditionalPanel("input.n >= 50",
plotOutput("scatterPlot", height = 300)
)
)
))
The following example application shows how this function works for the Related server.R file:
library(shiny)
shinyServer(function(input, output) {
output$scatterPlot <- renderPlot({
x <- rnorm(input$n)
y <- rnorm(input$n)
plot(x, y)
})
})
The code for this example application was taken from the Shiny gallery of RStudio (http://shiny.rstudio.com/gallery/conditionalpanel-demo.html).
As readable in both code files, the defined function, input.n, is the linchpin for the dynamic behavior of the example app. In the conditionalPanel() function, it is defined that inputId="n" must have a value of 50 or higher, while the input and output of the plot will work as already defined.
Taking advantage of the renderUI function
The renderUI() function is hooked, contrary to the previous model, to the server file to create a dynamic user interface. We have already introduced different render output functions in this article.
The following example code shows the basic functionality using the ui.R file:
# Partial example taken from the Shiny documentation
numericInput("lat", "Latitude"),
numericInput("long", "Longitude"),
uiOutput("cityControls")
The following example code shows the basic functionality of the Related sever.R file:
# Partial example
output$cityControls <- renderUI({
cities <- getNearestCities(input$lat, input$long)
checkboxGroupInput("cities", "Choose Cities", cities)
})
As described, the dynamic of this method gets defined in the renderUI() process as an output, which then gets displayed through the uiOutput() function in the ui.R file.
Sharing your Shiny application with others
Typically, you create a Shiny application not only for yourself, but also for other users. There are a two main ways to distribute your app; either you let users download your application, or you deploy it on the web.
Offering a download of your Shiny app
By offering the option to download your final Shiny application, other users can run your app locally. Actually, there are four ways to deliver your app this way. No matter which way you choose, it is important that the user has installed R and the Shiny package on his/her computer.
Gist
Gist is a public code sharing pasteboard from GitHub. To share your app this way, it is important that both the ui.R file and the server.R file are in the same Gist and have been named correctly. Take a look at the following screenshot:
There are two options to run apps via Gist. First, just enter runGist("Gist_URL") in the console of RStudio; or second, just use the Gist ID and place it in the shiny::runGist("Gist_ID") function.
Gist is a very easy way to share your application, but you need to keep in mind that your code is published on a third-party server.
GitHub
The next way to enable users to download your app is through a GitHub repository:
To run an application from GitHub, you need to enter the command, shiny::runGitHub ("Repository_Name", "GitHub_Account_Name"), in the console:
Zip file
There are two ways to share a Shiny application by zip file. You can either let the user download the zip file over the web, or you can share it via email, USB stick, memory card, or any other such device. To download a zip file via the Web, you need to type runUrl ("Zip_File_URL") in the console:
Package
Certainly, a much more labor-intensive but also publically effective way is to create a complete R package for your Shiny application. This especially makes sense if you have built an extensive application that may help many other users. Another advantage is the fact that you can also publish your application on CRAN. Later in the book, we will show you how to create an R package.
Deploying your app to the web
After showing you the ways users can download your app and run it on their local machines, we will now check the options to deploy Shiny apps to the web.
Shinyapps.io
http://www.shinyapps.io/ is a Shiny app- hosting service by RStudio. There is a free-to- use account package, but it is limited to a maximum of five applications, 25 so-called active hours, and the apps are branded with the RStudio logo. Nevertheless, this service is a great way to publish one's own applications quickly and easily to the web.
To use http://www.shinyapps.io/ with RStudio, a few R packages and some additional operating system software needs to be installed:
RTools (If you use Windows)
GCC (If you use Linux)
XCode Command Line Tools (If you use Mac OS X)
The devtools R package
The shinyapps package
Since the shinyapps package is not on CRAN, you need to install it via GitHub by using the devtools package:
if (!require("devtools"))
install.packages("devtools")
devtools::install_github("rstudio/shinyapps")
library(shinyapps)
When everything that is needed is installed ,you are ready to publish your Shiny apps directly from the RStudio IDE. Just click on the Publish icon, and in the new window you will need to log in to your http://www.shinyapps.io/ account once, if you are using it for the first time. All other times, you can directly create a new Shiny app or update an existing app:
After clicking on Publish, a new tab called Deploy opens in the console pane, showing you the progress of the deployment process. If there is something set incorrectly, you can use the deployment log to find the error:
When the deployment is successful, your app will be publically reachable with its own web address on http://www.shinyapps.io/.
Setting up a self-hosted Shiny server
There are two editions of the Shiny Server software: an open source edition and the professional edition. The open source edition can be downloaded for free and you can use it on your own server. The Professional edition offers a lot more features and support by RStudio, but is also priced accordingly.
Diving into the Shiny ecosystem
Since the Shiny framework is such an awesome and powerful tool, a lot of people, and of course, the creators of RStudio and Shiny have built several packages around it that are enormously extending the existing functionalities of Shiny. These almost infinite possibilities of technical and visual individualization, which are possible by deeply checking the Shiny ecosystem, would certainly go beyond the scope of this article. Therefore, we are presenting only a few important directions to give a first impression.
Creating apps with more files
In this article, you have learned how to build a Shiny app consisting of two files: the server.R and the ui.R. To include every aspect, we first want to point out that it is also possible to create a single file Shiny app. To do so, create a file called app.R. In this file, you can include both the server.R and the ui.R file. Furthermore, you can include global variables, data, and more. If you build larger Shiny apps with multiple functions, datasets, options, and more, it could be very confusing if you do all of it in just one file. Therefore, single-file Shiny apps are a good idea for simple and small exhibition apps with a minimal setup.
Especially for large Shiny apps, it is recommended that you outsource extensive custom functions, datasets, images, and more into your own files, but put them into the same directory as the app. An example file setup could look like this:
~/shinyapp
|-- ui.R
|-- server.R
|-- helper.R
|-- data
|-- www
|-- js
|-- etc
To access the helper file, you just need to add source("helpers.R") into the code of your server.R file. The same logic applies to any other R files. If you want to read in some data from your data folder, you store it in a variable that is also in the head of your server.R file, like this:
myData <- readRDS("data/myDataset.rds")
Expanding the Shiny package
As said earlier, you can expand the functionalities of Shiny with several add-on packages. There are currently ten packages available on CRAN with different inbuilt functions to add some extra magic to your Shiny app.
shinyAce: This package makes available Ace editor bindings to enable a rich text-editing environment within Shiny.
shinybootstrap2: The latest Shiny package uses bootstrap 3; so, if you built your app with bootstrap 2 features, you need to use this package.
shinyBS: This package adds the additional features of the original Twitter Bootstraptheme, such as tooltips, modals, and others, to Shiny.
shinydashboard: This packages comes from the folks at RStudio and enables the user to create stunning and multifunctional dashboards on top of Shiny.
shinyFiles: This provides functionality for client-side navigation of the server side file system in Shiny apps.
shinyjs: By using this package, you can perform common JavaScript operations in Shiny applications without having to know any JavaScript.
shinyRGL: This package provides Shiny wrappers for the RGL package. This package exposes RGL's ability to export WebGL visualization in a shiny-friendly format.
shinystan: This package is, in fact, not a real add-on. Shinystan is a fantastic full-blown Shiny application to give users a graphical interface for Markov chain Monte Carlo simulations.
shinythemes: This packages gives you the option of changing the whole look and feel of your application by using different inbuilt bootstrap themes.
shinyTree: This exposes bindings to jsTree—a JavaScript library that supports interactive trees—to enable rich, editable trees in Shiny.
Of course, you can find a bunch of other packages with similar or even more functionalities, extensions, and also comprehensive Shiny apps on GitHub.
Summary
To learn more about Shiny, the following books published by Packt Publishing (https://www.packtpub.com/) are recommended:
Learning Shiny (https://www.packtpub.com/application-development/learning-shiny)
Mastering Machine Learning with R (https://www.packtpub.com/big-data-and-business-intelligence/mastering-machine-learning-r)
Mastering Data Analysis with R (https://www.packtpub.com/big-data-and-business-intelligence/mastering-data-analysis-r)
Read more