mirror of
https://github.com/rstudio/shiny.git
synced 2026-02-04 19:55:06 -05:00
Convert code blocks to use templating format
This commit is contained in:
@@ -4,13 +4,17 @@ The examples so far have demonstrated outputs that appear directly in the page,
|
||||
|
||||
To run the example below, type:
|
||||
|
||||
<pre><code class="console">> library(shiny)
|
||||
> runExample("10_download")</code></pre>
|
||||
{% highlight console %}
|
||||
> library(shiny)
|
||||
> runExample("10_download")
|
||||
{% endhighlight %}
|
||||
|
||||
You define a download using the `downloadHandler` function on the server side, and either `downloadButton` or `downloadLink` in the UI:
|
||||
|
||||
#### ui.R
|
||||
<pre><code class="r">shinyUI(pageWithSidebar(
|
||||
|
||||
{% highlight r %}
|
||||
shinyUI(pageWithSidebar(
|
||||
headerPanel('Download Example'),
|
||||
sidebarPanel(
|
||||
selectInput("dataset", "Choose a dataset:",
|
||||
@@ -21,29 +25,31 @@ You define a download using the `downloadHandler` function on the server side, a
|
||||
tableOutput('table')
|
||||
)
|
||||
))
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
#### server.R
|
||||
<pre><code class="r">shinyServer(function(input, output) {
|
||||
datasetInput <- reactive({
|
||||
|
||||
{% highlight r %}
|
||||
shinyServer(function(input, output) {
|
||||
datasetInput <- reactive({
|
||||
switch(input$dataset,
|
||||
"rock" = rock,
|
||||
"pressure" = pressure,
|
||||
"cars" = cars)
|
||||
})
|
||||
|
||||
output$table <- renderTable({
|
||||
output$table <- renderTable({
|
||||
datasetInput()
|
||||
})
|
||||
|
||||
output$downloadData <- downloadHandler(
|
||||
output$downloadData <- downloadHandler(
|
||||
filename = function() { paste(input$dataset, '.csv', sep='') },
|
||||
content = function(file) {
|
||||
write.csv(datasetInput(), file)
|
||||
}
|
||||
)
|
||||
})
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
As you can see, `downloadHandler` takes a `filename` argument, which tells the web browser what filename to default to when saving. This argument can either be a simple string, or it can be a function that returns a string (as is the case here).
|
||||
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
|
||||
The Hello Shiny example is a simple application that generates a random distribution with a configurable number of observations and then plots it. To run the example, type:
|
||||
|
||||
<pre><code class="console">> library(shiny)
|
||||
> runExample("01_hello")
|
||||
</code></pre>
|
||||
{% highlight console %}
|
||||
> library(shiny)
|
||||
> runExample("01_hello")
|
||||
{% endhighlight %}
|
||||
|
||||
Shiny applications have two components: a user-interface definition and a server script. The source code for both of these components is listed below.
|
||||
|
||||
@@ -15,18 +16,20 @@ The user interface is defined in a source file named ui.R:
|
||||
|
||||
#### ui.R
|
||||
|
||||
<pre><code class="r">library(shiny)
|
||||
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
|
||||
# Define UI for application that plots random distributions
|
||||
shinyUI(pageWithSidebar(
|
||||
|
||||
# Application title
|
||||
headerPanel("Hello Shiny!"),
|
||||
headerPanel("Hello Shiny!"),
|
||||
|
||||
# Sidebar with a slider input for number of observations
|
||||
sidebarPanel(
|
||||
sliderInput("obs",
|
||||
"Number of observations:",
|
||||
sliderInput("obs",
|
||||
"Number of observations:",
|
||||
min = 0,
|
||||
max = 1000,
|
||||
value = 500)
|
||||
@@ -34,16 +37,17 @@ shinyUI(pageWithSidebar(
|
||||
|
||||
# Show a plot of the generated distribution
|
||||
mainPanel(
|
||||
plotOutput("distPlot")
|
||||
plotOutput("distPlot")
|
||||
)
|
||||
))
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
The server-side of the application is shown below. At one level, it's very simple--a random distribution with the requested number of observations is generated, and then plotted as a historgram. However, you'll also notice that the function which returns 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.
|
||||
|
||||
#### server.R
|
||||
|
||||
<pre><code class="r">library(shiny)
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
|
||||
# Define server logic required to generate and plot a random distribution
|
||||
shinyServer(function(input, output) {
|
||||
@@ -51,17 +55,17 @@ shinyServer(function(input, output) {
|
||||
# Expression that generates a plot of the distribution. The expression
|
||||
# is wrapped in a call to renderPlot to indicate that:
|
||||
#
|
||||
# 1) It is "reactive" and therefore should be automatically
|
||||
# 1) It is "reactive" and therefore should be automatically
|
||||
# re-executed when inputs change
|
||||
# 2) Its output type is a plot
|
||||
#
|
||||
output$distPlot <- renderPlot({
|
||||
output$distPlot <- renderPlot({
|
||||
|
||||
# generate an rnorm distribution and plot it
|
||||
dist <- rnorm(input$obs)
|
||||
dist <- rnorm(input$obs)
|
||||
hist(dist)
|
||||
})
|
||||
})
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
The next example will show the use of more input controls, as well as the use of reactive functions to generate textual output.
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
|
||||
The HTML UI application demonstrates defining a Shiny user-interface using a standard HTML page rather than a ui.R script. To run the example type:
|
||||
|
||||
<pre><code class="console">> library(shiny)
|
||||
> runExample("08_html")
|
||||
</code></pre>
|
||||
{% highlight console %}
|
||||
> library(shiny)
|
||||
> runExample("08_html")
|
||||
{% endhighlight %}
|
||||
|
||||
### Defining an HTML UI
|
||||
|
||||
@@ -72,7 +73,8 @@ All of the changes from the original Tabsets application were to the user-interf
|
||||
|
||||
#### server.R
|
||||
|
||||
<pre><code class="r">library(shiny)
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
|
||||
# Define server logic for random distribution application
|
||||
shinyServer(function(input, output) {
|
||||
@@ -80,8 +82,8 @@ shinyServer(function(input, output) {
|
||||
# Reactive expression to generate the requested distribution. This is
|
||||
# called whenever the inputs change. The output renderers defined
|
||||
# below then all used the value computed from this expression
|
||||
data <- reactive({
|
||||
dist <- switch(input$dist,
|
||||
data <- reactive({
|
||||
dist <- switch(input$dist,
|
||||
norm = rnorm,
|
||||
unif = runif,
|
||||
lnorm = rlnorm,
|
||||
@@ -95,24 +97,22 @@ shinyServer(function(input, output) {
|
||||
# plot label. Note that the dependencies on both the inputs and
|
||||
# the data reactive expression are both tracked, and all expressions
|
||||
# are called in the sequence implied by the dependency graph
|
||||
output$plot <- renderPlot({
|
||||
dist <- input$dist
|
||||
n <- input$n
|
||||
output$plot <- renderPlot({
|
||||
dist <- input$dist
|
||||
n <- input$n
|
||||
|
||||
hist(data(),
|
||||
main=paste('r', dist, '(', n, ')', sep=''))
|
||||
main=paste('r', dist, '(', n, ')', sep=''))
|
||||
})
|
||||
|
||||
# Generate a summary of the data
|
||||
output$summary <- renderPrint({
|
||||
output$summary <- renderPrint({
|
||||
summary(data())
|
||||
})
|
||||
|
||||
# Generate an HTML table view of the data
|
||||
output$table <- renderTable({
|
||||
output$table <- renderTable({
|
||||
data.frame(x=data())
|
||||
})
|
||||
})
|
||||
</code></pre>
|
||||
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
@@ -10,28 +10,30 @@ We want to provide a way to select which variable to plot MPG against as well as
|
||||
|
||||
#### ui.R
|
||||
|
||||
<pre><code class="r">library(shiny)
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
|
||||
# Define UI for miles per gallon application
|
||||
shinyUI(pageWithSidebar(
|
||||
|
||||
# Application title
|
||||
headerPanel("Miles Per Gallon"),
|
||||
headerPanel("Miles Per Gallon"),
|
||||
|
||||
# Sidebar with controls to select the variable to plot against mpg
|
||||
# and to specify whether outliers should be included
|
||||
sidebarPanel(
|
||||
selectInput("variable", "Variable:",
|
||||
list("Cylinders" = "cyl",
|
||||
"Transmission" = "am",
|
||||
"Gears" = "gear")),
|
||||
selectInput("variable", "Variable:",
|
||||
list("Cylinders" = "cyl",
|
||||
"Transmission" = "am",
|
||||
"Gears" = "gear")),
|
||||
|
||||
checkboxInput("outliers", "Show outliers", FALSE)
|
||||
checkboxInput("outliers", "Show outliers", FALSE)
|
||||
),
|
||||
|
||||
mainPanel()
|
||||
))
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
If you run the application again after making these changes you'll see the two user-inputs we defined displayed within the sidebar:
|
||||
|
||||
@@ -51,38 +53,39 @@ Here is the source code for the full server script (the inline comments explain
|
||||
|
||||
#### server.R
|
||||
|
||||
<pre><code class="r">library(shiny)
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
library(datasets)
|
||||
|
||||
# We tweak the "am" field to have nicer factor labels. Since this doesn't
|
||||
# We tweak the "am" field to have nicer factor labels. Since this doesn't
|
||||
# rely on any user inputs we can do this once at startup and then use the
|
||||
# value throughout the lifetime of the application
|
||||
mpgData <- mtcars
|
||||
mpgData$am <- factor(mpgData$am, labels = c("Automatic", "Manual"))
|
||||
mpgData <- mtcars
|
||||
mpgData$am <- factor(mpgData$am, labels = c("Automatic", "Manual"))
|
||||
|
||||
# Define server logic required to plot various variables against mpg
|
||||
shinyServer(function(input, output) {
|
||||
|
||||
# Compute the forumla text in a reactive expression since it is
|
||||
# shared by the output$caption and output$mpgPlot expressions
|
||||
formulaText <- reactive({
|
||||
paste("mpg ~", input$variable)
|
||||
formulaText <- reactive({
|
||||
paste("mpg ~", input$variable)
|
||||
})
|
||||
|
||||
# Return the formula text for printing as a caption
|
||||
output$caption <- renderText({
|
||||
output$caption <- renderText({
|
||||
formulaText()
|
||||
})
|
||||
|
||||
# Generate a plot of the requested variable against mpg and only
|
||||
# include outliers if requested
|
||||
output$mpgPlot <- renderPlot({
|
||||
output$mpgPlot <- renderPlot({
|
||||
boxplot(as.formula(formulaText()),
|
||||
data = mpgData,
|
||||
outline = input$outliers)
|
||||
})
|
||||
})
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
The use of `renderText` and `renderPlot` to generate output (rather than just assigning values directly) is what makes the application reactive. These reactive wrappers return special expressions that are only re-executed when their dependencies change. This behavior is what enables Shiny to automatically update output whenever input changes.
|
||||
|
||||
@@ -95,33 +98,35 @@ In the updated user-interface definition below you can see that we've added the
|
||||
|
||||
#### ui.R
|
||||
|
||||
<pre><code class="r">library(shiny)
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
|
||||
# Define UI for miles per gallon application
|
||||
shinyUI(pageWithSidebar(
|
||||
|
||||
# Application title
|
||||
headerPanel("Miles Per Gallon"),
|
||||
headerPanel("Miles Per Gallon"),
|
||||
|
||||
# Sidebar with controls to select the variable to plot against mpg
|
||||
# and to specify whether outliers should be included
|
||||
sidebarPanel(
|
||||
selectInput("variable", "Variable:",
|
||||
list("Cylinders" = "cyl",
|
||||
"Transmission" = "am",
|
||||
"Gears" = "gear")),
|
||||
selectInput("variable", "Variable:",
|
||||
list("Cylinders" = "cyl",
|
||||
"Transmission" = "am",
|
||||
"Gears" = "gear")),
|
||||
|
||||
checkboxInput("outliers", "Show outliers", FALSE)
|
||||
checkboxInput("outliers", "Show outliers", FALSE)
|
||||
),
|
||||
|
||||
# Show the caption and plot of the requested variable against mpg
|
||||
mainPanel(
|
||||
h3(textOutput("caption")),
|
||||
h3(textOutput("caption")),
|
||||
|
||||
plotOutput("mpgPlot")
|
||||
plotOutput("mpgPlot")
|
||||
)
|
||||
))
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
Running the application now shows it in its final form including inputs and dynamically updating outputs:
|
||||
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
|
||||
The More Widgets application demonstrates the help text and submit button widgets as well as the use of embedded HTML elements to customize formatting. To run the example type:
|
||||
|
||||
<pre><code class="console">> library(shiny)
|
||||
> runExample("07_widgets")
|
||||
</code></pre>
|
||||
{% highlight r %}
|
||||
> library(shiny)
|
||||
> runExample("07_widgets")
|
||||
{% endhighlight %}
|
||||
|
||||
### UI Enhancements
|
||||
|
||||
@@ -20,13 +21,14 @@ Here is the updated source code for the user-interface:
|
||||
|
||||
#### ui.R
|
||||
|
||||
<pre><code class="r">library(shiny)
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
|
||||
# Define UI for dataset viewer application
|
||||
shinyUI(pageWithSidebar(
|
||||
|
||||
# Application title.
|
||||
headerPanel("More Widgets"),
|
||||
headerPanel("More Widgets"),
|
||||
|
||||
# Sidebar with controls to select a dataset and specify the number
|
||||
# of observations to view. The helpText function is also used to
|
||||
@@ -36,30 +38,31 @@ shinyUI(pageWithSidebar(
|
||||
# when inputs change). This is useful if the computations required
|
||||
# to render output are inordinately time-consuming.
|
||||
sidebarPanel(
|
||||
selectInput("dataset", "Choose a dataset:",
|
||||
choices = c("rock", "pressure", "cars")),
|
||||
selectInput("dataset", "Choose a dataset:",
|
||||
choices = c("rock", "pressure", "cars")),
|
||||
|
||||
numericInput("obs", "Number of observations to view:", 10),
|
||||
numericInput("obs", "Number of observations to view:", 10),
|
||||
|
||||
helpText("Note: while the data view will show only the specified",
|
||||
"number of observations, the summary will still be based",
|
||||
"on the full dataset."),
|
||||
helpText("Note: while the data view will show only the specified",
|
||||
"number of observations, the summary will still be based",
|
||||
"on the full dataset."),
|
||||
|
||||
submitButton("Update View")
|
||||
submitButton("Update View")
|
||||
),
|
||||
|
||||
# Show a summary of the dataset and an HTML table with the requested
|
||||
# number of observations. Note the use of the h4 function to provide
|
||||
# an additional header above each output section.
|
||||
mainPanel(
|
||||
h4("Summary"),
|
||||
verbatimTextOutput("summary"),
|
||||
h4("Summary"),
|
||||
verbatimTextOutput("summary"),
|
||||
|
||||
h4("Observations"),
|
||||
tableOutput("view")
|
||||
h4("Observations"),
|
||||
tableOutput("view")
|
||||
)
|
||||
))
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
### Server Script
|
||||
|
||||
@@ -67,29 +70,30 @@ All of the changes from the original Shiny Text application were to the user-int
|
||||
|
||||
#### server.R
|
||||
|
||||
<pre><code class="r">library(shiny)
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
library(datasets)
|
||||
|
||||
# Define server logic required to summarize and view the selected dataset
|
||||
shinyServer(function(input, output) {
|
||||
|
||||
# Return the requested dataset
|
||||
datasetInput <- reactive({
|
||||
datasetInput <- reactive({
|
||||
switch(input$dataset,
|
||||
"rock" = rock,
|
||||
"pressure" = pressure,
|
||||
"cars" = cars)
|
||||
"rock" = rock,
|
||||
"pressure" = pressure,
|
||||
"cars" = cars)
|
||||
})
|
||||
|
||||
# Generate a summary of the dataset
|
||||
output$summary <- renderPrint({
|
||||
dataset <- datasetInput()
|
||||
output$summary <- renderPrint({
|
||||
dataset <- datasetInput()
|
||||
summary(dataset)
|
||||
})
|
||||
|
||||
# Show the first "n" observations
|
||||
output$view <- renderTable({
|
||||
# Show the first "n" observations
|
||||
output$view <- renderTable({
|
||||
head(datasetInput(), n = input$obs)
|
||||
})
|
||||
})
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
|
||||
The Reactivity application is very similar to Hello Text, but goes into much more detail about reactive programming concepts. To run the example, type:
|
||||
|
||||
<pre><code class="console">> library(shiny)
|
||||
> runExample("03_reactivity")
|
||||
</code></pre>
|
||||
{% highlight console %}
|
||||
> library(shiny)
|
||||
> runExample("03_reactivity")
|
||||
{% endhighlight %}
|
||||
|
||||
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](#reactivity-overview).
|
||||
|
||||
@@ -30,20 +31,23 @@ The most common way you'll encounter reactive values in Shiny is using the `inpu
|
||||
|
||||
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:
|
||||
|
||||
<pre><code class="r">datasetInput <- reactive({
|
||||
{% highlight r %}
|
||||
datasetInput <- reactive({
|
||||
switch(input$dataset,
|
||||
"rock" = rock,
|
||||
"pressure" = pressure,
|
||||
"cars" = cars)
|
||||
"rock" = rock,
|
||||
"pressure" = pressure,
|
||||
"cars" = cars)
|
||||
})
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
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 `input$obs`:
|
||||
|
||||
<pre><code class="r">output$view <- renderTable({
|
||||
{% highlight r %}
|
||||
output$view <- renderTable({
|
||||
head(datasetInput(), n = input$obs)
|
||||
})
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
This expression will be re-executed (and its output re-rendered in the browser) whenever either the `datasetInput` or `input$obs` value changes.
|
||||
|
||||
@@ -53,39 +57,41 @@ Now that we've taken a deeper loop at some of the core concepts, let's revisit t
|
||||
|
||||
#### ui.R
|
||||
|
||||
<pre><code class="r">library(shiny)
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
|
||||
# Define UI for dataset viewer application
|
||||
shinyUI(pageWithSidebar(
|
||||
|
||||
# Application title
|
||||
headerPanel("Reactivity"),
|
||||
headerPanel("Reactivity"),
|
||||
|
||||
# Sidebar with controls to provide a caption, select a dataset, and
|
||||
# specify the number of observations to view. Note that changes made
|
||||
# to the caption in the textInput control are updated in the output
|
||||
# area immediately as you type
|
||||
sidebarPanel(
|
||||
textInput("caption", "Caption:", "Data Summary"),
|
||||
textInput("caption", "Caption:", "Data Summary"),
|
||||
|
||||
selectInput("dataset", "Choose a dataset:",
|
||||
choices = c("rock", "pressure", "cars")),
|
||||
selectInput("dataset", "Choose a dataset:",
|
||||
choices = c("rock", "pressure", "cars")),
|
||||
|
||||
numericInput("obs", "Number of observations to view:", 10)
|
||||
numericInput("obs", "Number of observations to view:", 10)
|
||||
),
|
||||
|
||||
|
||||
# Show the caption, a summary of the dataset and an HTML table with
|
||||
# the requested number of observations
|
||||
mainPanel(
|
||||
h3(textOutput("caption")),
|
||||
h3(textOutput("caption")),
|
||||
|
||||
verbatimTextOutput("summary"),
|
||||
verbatimTextOutput("summary"),
|
||||
|
||||
tableOutput("view")
|
||||
tableOutput("view")
|
||||
)
|
||||
))
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
### Server Script
|
||||
|
||||
@@ -93,7 +99,8 @@ The server script declares the `datasetInput` reactive expression as well as thr
|
||||
|
||||
#### server.R
|
||||
|
||||
<pre><code class="r">library(shiny)
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
library(datasets)
|
||||
|
||||
# Define server logic required to summarize and view the selected dataset
|
||||
@@ -108,41 +115,41 @@ shinyServer(function(input, output) {
|
||||
# new result is compared to the previous result; if the two are
|
||||
# identical, then the callers are not notified
|
||||
#
|
||||
datasetInput <- reactive({
|
||||
datasetInput <- reactive({
|
||||
switch(input$dataset,
|
||||
"rock" = rock,
|
||||
"pressure" = pressure,
|
||||
"cars" = cars)
|
||||
"rock" = rock,
|
||||
"pressure" = pressure,
|
||||
"cars" = cars)
|
||||
})
|
||||
|
||||
# The output$caption is computed based on a reactive expression that
|
||||
# returns input$caption. When the user changes the "caption" field:
|
||||
# returns input$caption. When the user changes the "caption" field:
|
||||
#
|
||||
# 1) This expression is automatically called to recompute the output
|
||||
# 2) The new caption is pushed back to the browser for re-display
|
||||
#
|
||||
# Note that because the data-oriented reactive expression below don't
|
||||
# Note that because the data-oriented reactive expression below don't
|
||||
# depend on input$caption, those expression are NOT called when
|
||||
# input$caption changes.
|
||||
output$caption <- renderText({
|
||||
output$caption <- renderText({
|
||||
input$caption
|
||||
})
|
||||
|
||||
# The output$summary depends on the datasetInput reactive expression,
|
||||
# so will be re-executed whenever datasetInput is re-executed
|
||||
# (i.e. whenever the input$dataset changes)
|
||||
output$summary <- renderPrint({
|
||||
dataset <- datasetInput()
|
||||
output$summary <- renderPrint({
|
||||
dataset <- datasetInput()
|
||||
summary(dataset)
|
||||
})
|
||||
|
||||
# The output$view depends on both the databaseInput reactive expression
|
||||
# and input$obs, so will be re-executed whenever input$dataset or
|
||||
# input$obs is changed.
|
||||
output$view <- renderTable({
|
||||
output$view <- renderTable({
|
||||
head(datasetInput(), n = input$obs)
|
||||
})
|
||||
})
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
We've reviewed a lot code and covered a lot of conceptual ground in the first three examples. The next section focuses on the mechanics of building a Shiny application from the ground up and also covers tips on how to run and debug Shiny applications.
|
||||
|
||||
@@ -10,8 +10,9 @@ To stop the application you simply interupt R -- you can do this by pressing the
|
||||
|
||||
If you don't want to block access to the console while running your Shiny application you can also run it in a separate process. You can do this by opening a terminal or console window and executing the following:
|
||||
|
||||
<pre><code class="console">R -e "shiny::runApp('~/shinyapp')"
|
||||
</code></pre>
|
||||
{% highlight console %}
|
||||
R -e "shiny::runApp('~/shinyapp')"
|
||||
{% endhighlight %}
|
||||
|
||||
By default `runApp` starts the application on port 8100. If you are using this default then you can connect to the running application by navigating your browser to [http://localhost:8100](http://localhost:8100).
|
||||
|
||||
@@ -28,37 +29,42 @@ One qualification to this: when a browser reload occurs Shiny explicitly checks
|
||||
#### Printing
|
||||
There are several techniques available for debugging Shiny applications. The first is to add calls to the [cat](http://stat.ethz.ch/R-manual/R-devel/library/base/html/cat.html) function which print diagnostics where appropriate. For example, these two calls to cat print diagnostics to standard output and standard error respectively:
|
||||
|
||||
<pre><code class="r">cat("foo\n")
|
||||
cat("bar\n", file=stderr())
|
||||
</code></pre>
|
||||
{% highlight r %}
|
||||
cat("foo\n")
|
||||
cat("bar\n", file=stderr())
|
||||
{% endhighlight %}
|
||||
|
||||
#### Using browser
|
||||
The second technique is to add explicit calls to the [browser](http://stat.ethz.ch/R-manual/R-devel/library/base/html/browser.html) function to interrupt execution and inspect the environment where browser was called from. Note that using browser requires that you start the application from an interactive session (as opposed to using R -e as described above).
|
||||
|
||||
For example, to unconditionally stop execution at a certain point in the code:
|
||||
|
||||
<pre><code class="r"># Always stop execution here
|
||||
{% highlight r %}
|
||||
# Always stop execution here
|
||||
browser()
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
You can also use this technique to stop only on certain conditions. For example, to stop the MPG application only when the user selects "Transmission" as the variable:
|
||||
|
||||
<pre><code class="r"># Stop execution when the user selects "am"
|
||||
browser(expr = identical(input$variable, "am"))
|
||||
</code></pre>
|
||||
{% highlight r %}
|
||||
# Stop execution when the user selects "am"
|
||||
browser(expr = identical(input$variable, "am"))
|
||||
{% endhighlight %}
|
||||
|
||||
#### Establishing a custom error handler
|
||||
You can also set the R "error" option to automatically enter the browser when an error occurs:
|
||||
|
||||
<pre><code class="r"># Immediately enter the browser when an error occurs
|
||||
{% highlight r %}
|
||||
# Immediately enter the browser when an error occurs
|
||||
options(error = browser)
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
Alternatively, you can specify the [recover](http://stat.ethz.ch/R-manual/R-devel/library/utils/html/recover.html) function as your error handler, which will print a list of the call stack and allow you to browse at any point in he stack:
|
||||
|
||||
<pre><code class="r"># Call the recover function when an error occurs
|
||||
{% highlight r %}
|
||||
# Call the recover function when an error occurs
|
||||
options(error = recover)
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
If you want to set the error option automatically for every R session, you can do this in your .Rprofile file as described in this article on [R Startup](http://stat.ethz.ch/R-manual/R-patched/library/base/html/Startup.html).
|
||||
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
|
||||
The Shiny Text application demonstrates printing R objects directly, as well as displaying data frames using HTML tables. To run the example, type:
|
||||
|
||||
<pre><code class="console">> library(shiny)
|
||||
> runExample("02_text")
|
||||
</code></pre>
|
||||
{% highlight console %}
|
||||
> library(shiny)
|
||||
> runExample("02_text")
|
||||
{% endhighlight %}
|
||||
|
||||
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.
|
||||
|
||||
@@ -15,32 +16,33 @@ Here is the user interface definition for the application. Notice in particular
|
||||
|
||||
#### ui.R
|
||||
|
||||
<pre><code class="r">library(shiny)
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
|
||||
# Define UI for dataset viewer application
|
||||
shinyUI(pageWithSidebar(
|
||||
|
||||
# Application title
|
||||
headerPanel("Shiny Text"),
|
||||
headerPanel("Shiny Text"),
|
||||
|
||||
# Sidebar with controls to select a dataset and specify the number
|
||||
# of observations to view
|
||||
sidebarPanel(
|
||||
selectInput("dataset", "Choose a dataset:",
|
||||
choices = c("rock", "pressure", "cars")),
|
||||
selectInput("dataset", "Choose a dataset:",
|
||||
choices = c("rock", "pressure", "cars")),
|
||||
|
||||
numericInput("obs", "Number of observations to view:", 10)
|
||||
numericInput("obs", "Number of observations to view:", 10)
|
||||
),
|
||||
|
||||
# Show a summary of the dataset and an HTML table with the requested
|
||||
# number of observations
|
||||
mainPanel(
|
||||
verbatimTextOutput("summary"),
|
||||
verbatimTextOutput("summary"),
|
||||
|
||||
tableOutput("view")
|
||||
tableOutput("view")
|
||||
)
|
||||
))
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
The server side of the application has also gotten a bit more complicated. Now we create:
|
||||
|
||||
@@ -51,31 +53,33 @@ These expressions work similarly to the `renderPlot` expression used in the firs
|
||||
|
||||
#### server.R
|
||||
|
||||
<pre><code class="r">library(shiny)
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
library(datasets)
|
||||
|
||||
# Define server logic required to summarize and view the selected dataset
|
||||
shinyServer(function(input, output) {
|
||||
|
||||
# Return the requested dataset
|
||||
datasetInput <- reactive({
|
||||
datasetInput <- reactive({
|
||||
switch(input$dataset,
|
||||
"rock" = rock,
|
||||
"pressure" = pressure,
|
||||
"cars" = cars)
|
||||
"rock" = rock,
|
||||
"pressure" = pressure,
|
||||
"cars" = cars)
|
||||
})
|
||||
|
||||
# Generate a summary of the dataset
|
||||
output$summary <- renderPrint({
|
||||
dataset <- datasetInput()
|
||||
output$summary <- renderPrint({
|
||||
dataset <- datasetInput()
|
||||
summary(dataset)
|
||||
})
|
||||
|
||||
# Show the first "n" observations
|
||||
output$view <- renderTable({
|
||||
# Show the first "n" observations
|
||||
output$view <- renderTable({
|
||||
head(datasetInput(), n = input$obs)
|
||||
})
|
||||
})
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
We've introduced 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.
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
|
||||
The Sliders application demonstrates the many capabilities of slider controls, including the ability to run an animation sequence. To run the example type:
|
||||
|
||||
<pre><code class="console">> library(shiny)
|
||||
> runExample("05_sliders")
|
||||
</code></pre>
|
||||
{% highlight console %}
|
||||
> library(shiny)
|
||||
> runExample("05_sliders")
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
### Customizing Sliders
|
||||
|
||||
@@ -19,44 +21,46 @@ Slider controls are created by calling the `sliderInput` function. The ui.R file
|
||||
|
||||
#### ui.R
|
||||
|
||||
<pre><code class="r">library(shiny)
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
|
||||
# Define UI for slider demo application
|
||||
shinyUI(pageWithSidebar(
|
||||
|
||||
# Application title
|
||||
headerPanel("Sliders"),
|
||||
headerPanel("Sliders"),
|
||||
|
||||
# Sidebar with sliders that demonstrate various available options
|
||||
sidebarPanel(
|
||||
# Simple integer interval
|
||||
sliderInput("integer", "Integer:",
|
||||
sliderInput("integer", "Integer:",
|
||||
min=0, max=1000, value=500),
|
||||
|
||||
# Decimal interval with step value
|
||||
sliderInput("decimal", "Decimal:",
|
||||
sliderInput("decimal", "Decimal:",
|
||||
min = 0, max = 1, value = 0.5, step= 0.1),
|
||||
|
||||
# Specification of range within an interval
|
||||
sliderInput("range", "Range:",
|
||||
sliderInput("range", "Range:",
|
||||
min = 1, max = 1000, value = c(200,500)),
|
||||
|
||||
# Provide a custom currency format for value display, with basic animation
|
||||
sliderInput("format", "Custom Format:",
|
||||
sliderInput("format", "Custom Format:",
|
||||
min = 0, max = 10000, value = 0, step = 2500,
|
||||
format="$#,##0", locale="us", animate=TRUE),
|
||||
format="$#,##0", locale="us", animate=TRUE),
|
||||
|
||||
# Animation with custom interval (in ms) to control speed, plus looping
|
||||
sliderInput("animation", "Looping Animation:", 1, 2000, 1, step = 10,
|
||||
sliderInput("animation", "Looping Animation:", 1, 2000, 1, step = 10,
|
||||
animate=animationOptions(interval=300, loop=T))
|
||||
),
|
||||
|
||||
# Show a table summarizing the values entered
|
||||
mainPanel(
|
||||
tableOutput("values")
|
||||
tableOutput("values")
|
||||
)
|
||||
))
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
### Server Script
|
||||
|
||||
@@ -64,34 +68,33 @@ The server side of the Slider application is very straightforward: it creates a
|
||||
|
||||
#### server.R
|
||||
|
||||
<pre><code class="r">library(shiny)
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
|
||||
# Define server logic for slider examples
|
||||
shinyServer(function(input, output) {
|
||||
|
||||
# Reactive expression to compose a data frame containing all of the values
|
||||
sliderValues <- reactive({
|
||||
sliderValues <- reactive({
|
||||
|
||||
# Compose data frame
|
||||
data.frame(
|
||||
Name = c("Integer",
|
||||
"Decimal",
|
||||
"Range",
|
||||
"Custom Format",
|
||||
"Animation"),
|
||||
Name = c("Integer",
|
||||
"Decimal",
|
||||
"Range",
|
||||
"Custom Format",
|
||||
"Animation"),
|
||||
Value = as.character(c(input$integer,
|
||||
input$decimal,
|
||||
paste(input$range, collapse=' '),
|
||||
paste(input$range, collapse=' '),
|
||||
input$format,
|
||||
input$animation)),
|
||||
stringsAsFactors=FALSE)
|
||||
})
|
||||
|
||||
# Show the values using an HTML table
|
||||
output$values <- renderTable({
|
||||
output$values <- renderTable({
|
||||
sliderValues()
|
||||
})
|
||||
})
|
||||
</code></pre>
|
||||
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
|
||||
The Tabsets application demonstrates using tabs to organize output. To run the example type:
|
||||
|
||||
<pre><code class="console">> library(shiny)
|
||||
> runExample("06_tabsets")
|
||||
</code></pre>
|
||||
{% highlight console %}
|
||||
> library(shiny)
|
||||
> runExample("06_tabsets")
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
### Tab Panels
|
||||
|
||||
@@ -15,27 +17,29 @@ Tabsets are created by calling the `tabsetPanel` function with a list of tabs cr
|
||||
In this example we updated our Hello Shiny application to add a summary and table view of the data, each rendered on their own tab. Here is the revised source code for the user-interface:
|
||||
|
||||
#### ui.R
|
||||
<pre><code class="r">library(shiny)
|
||||
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
|
||||
# Define UI for random distribution application
|
||||
shinyUI(pageWithSidebar(
|
||||
|
||||
# Application title
|
||||
headerPanel("Tabsets"),
|
||||
headerPanel("Tabsets"),
|
||||
|
||||
# Sidebar with controls to select the random distribution type
|
||||
# and number of observations to generate. Note the use of the br()
|
||||
# element to introduce extra vertical spacing
|
||||
sidebarPanel(
|
||||
radioButtons("dist", "Distribution type:",
|
||||
list("Normal" = "norm",
|
||||
"Uniform" = "unif",
|
||||
"Log-normal" = "lnorm",
|
||||
"Exponential" = "exp")),
|
||||
radioButtons("dist", "Distribution type:",
|
||||
list("Normal" = "norm",
|
||||
"Uniform" = "unif",
|
||||
"Log-normal" = "lnorm",
|
||||
"Exponential" = "exp")),
|
||||
br(),
|
||||
|
||||
sliderInput("n",
|
||||
"Number of observations:",
|
||||
sliderInput("n",
|
||||
"Number of observations:",
|
||||
value = 500,
|
||||
min = 1,
|
||||
max = 1000)
|
||||
@@ -45,13 +49,14 @@ shinyUI(pageWithSidebar(
|
||||
# of the generated distribution
|
||||
mainPanel(
|
||||
tabsetPanel(
|
||||
tabPanel("Plot", plotOutput("plot")),
|
||||
tabPanel("Summary", verbatimTextOutput("summary")),
|
||||
tabPanel("Table", tableOutput("table"))
|
||||
tabPanel("Plot", plotOutput("plot")),
|
||||
tabPanel("Summary", verbatimTextOutput("summary")),
|
||||
tabPanel("Table", tableOutput("table"))
|
||||
)
|
||||
)
|
||||
))
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
### Tabs and Reactive Data
|
||||
|
||||
@@ -59,7 +64,8 @@ Introducing tabs into our user-interface underlines the importance of creating r
|
||||
|
||||
#### server.R
|
||||
|
||||
<pre><code class="r">library(shiny)
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
|
||||
# Define server logic for random distribution application
|
||||
shinyServer(function(input, output) {
|
||||
@@ -67,8 +73,8 @@ shinyServer(function(input, output) {
|
||||
# Reactive expression to generate the requested distribution. This is
|
||||
# called whenever the inputs change. The renderers defined
|
||||
# below then all use the value computed from this expression
|
||||
data <- reactive({
|
||||
dist <- switch(input$dist,
|
||||
data <- reactive({
|
||||
dist <- switch(input$dist,
|
||||
norm = rnorm,
|
||||
unif = runif,
|
||||
lnorm = rlnorm,
|
||||
@@ -82,22 +88,22 @@ shinyServer(function(input, output) {
|
||||
# plot label. Note that the dependencies on both the inputs and
|
||||
# the 'data' reactive expression are both tracked, and all expressions
|
||||
# are called in the sequence implied by the dependency graph
|
||||
output$plot <- renderPlot({
|
||||
dist <- input$dist
|
||||
n <- input$n
|
||||
output$plot <- renderPlot({
|
||||
dist <- input$dist
|
||||
n <- input$n
|
||||
|
||||
hist(data(),
|
||||
main=paste('r', dist, '(', n, ')', sep=''))
|
||||
main=paste('r', dist, '(', n, ')', sep=''))
|
||||
})
|
||||
|
||||
# Generate a summary of the data
|
||||
output$summary <- renderPrint({
|
||||
output$summary <- renderPrint({
|
||||
summary(data())
|
||||
})
|
||||
|
||||
# Generate an HTML table view of the data
|
||||
output$table <- renderTable({
|
||||
output$table <- renderTable({
|
||||
data.frame(x=data())
|
||||
})
|
||||
})
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
@@ -13,40 +13,47 @@ To get started building the application, create a new empty directory wherever y
|
||||
Now we'll add the minimal code required in each source file. We'll first define the user interface by calling the function `pageWithSidebar` and passing it's result to the `shinyUI` function:
|
||||
|
||||
#### ui.R
|
||||
<pre><code class="r">library(shiny)
|
||||
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
|
||||
# Define UI for miles per gallon application
|
||||
shinyUI(pageWithSidebar(
|
||||
|
||||
# Application title
|
||||
headerPanel("Miles Per Gallon"),
|
||||
headerPanel("Miles Per Gallon"),
|
||||
|
||||
sidebarPanel(),
|
||||
|
||||
mainPanel()
|
||||
))
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
The three functions `headerPanel`, `sidebarPanel`, and `mainPanel` define the various regions of the user-interface. The application will be called "Miles Per Gallon" so we specify that as the title when we create the header panel. The other panels are empty for now.
|
||||
|
||||
Now let's define a skeletal server implementation. To do this we call `shinyServer` and pass it a function that accepts two parameters: `input` and `output`:
|
||||
|
||||
#### server.R
|
||||
<pre><code class="r">library(shiny)
|
||||
|
||||
{% highlight r %}
|
||||
library(shiny)
|
||||
|
||||
# Define server logic required to plot various variables against mpg
|
||||
shinyServer(function(input, output) {
|
||||
|
||||
})
|
||||
</code></pre>
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
Our server function is empty for now but later we'll use it to define the relationship between our inputs and outputs.
|
||||
|
||||
We've now created the most minimal possible Shiny application. You can run the application by calling the `runApp` function as follows:
|
||||
|
||||
<pre><code class="console">> library(shiny)
|
||||
> runApp("~/shinyapp")
|
||||
</code></pre>
|
||||
{% highlight console %}
|
||||
> library(shiny)
|
||||
> runApp("~/shinyapp")
|
||||
{% endhighlight %}
|
||||
|
||||
If everything is working correctly you'll see the application appear in your browser looking something like this:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user