There are many types of interactivity
Filter data based on a variable
Zoom in on a plot
Add fit lines of various types
Anything that changes your plot from static
The very simplest way to introduce interactivity is with a package called plotly
Wrap your ggplot (or any other plot) in the ggplotly()
function:
ggplotly(scatter)
(This only works for HTML output, so I’m not running it here – see plotlyHTMLdemo file)
You can select certain portions of the plot, zoom in, mouse over to see data values, etc.
This is a very easy way to make your HTML documents
interactive, but just using plotly
is very limited
because the plot is static
From least to most flexible / interactive:
flexdashboard package
shinydashboard package
shiny elements in a markdown file
stand-alone shiny app
https://rmarkdown.rstudio.com/flexdashboard/
Done through a markdown document
Focus is on the layout and static objects
But you can add interactive objects using shiny
Need to specify runtime: shiny
in the YAML (indented
once, so it’s an output option)
Note that it’s no longer “Knit” but “Run”
See flexdashboarddemo file for an example
https://rstudio.github.io/shinydashboard/get_started.html
Done through a (non-markdown) R syntax file
Two functions contain most of your code: ui
and
server
ui
contains information about the look, including
input and output objects
server
constains information about any calculations
or graphics
At the end, run shinyApp(ui, server)
to run the app
See shinydashboarddemo file for an example
https://bookdown.org/yihui/rmarkdown/shiny-documents.html
Done within a markdown document, but not to make a whole dashboard (as in flexdashboard) but to add a small interactive element to a markdown document
Need to specify runtime: shiny
in the YAML (not
indented, so it’s a top-level option)
Note that it’s no longer “Knit” but “Run”
See shinyinmarkdowndemo file for an example
Start by selecting “New File” and then “Shiny Web App”
You can choose a single file or multiple file format
Single file: 1 file called “app.R” in a folder with the name of your application
Multiple file: 1 file called “ui.R” with the UI code and 1 file called “server.R” with the calculations code
Single file can be easier because it’s all in one place, but multiple file is easier to deal with for large projects
The template is already in place, just fill in your input, output, and calculations code
See app.R file for an example
There are a bunch of pre-defined input widgets (functions)
numericInput
radioButtons
sliderInput
fileInput
With a few exceptions, they end with “Input”
See http://shiny.rstudio.com/tutorial/written-tutorial/lesson3/ for a full list with examples
Each one requires at least 1) a label that you’ll use to refer to it in the program and 2) a text label that will show up in the app
Output functions are actually pairs of functions
One defines the object you’re outputting (in
server.R
if you have one)
These usually start with “render” such as renderPlot
or renderTable
Your code (e.g., a call to a named ggplot
) will go
inside
One defines where to put the object (in the ui.R
if
you have one)
These will match the render functions, such as
plotOutput
or tableOutput
Usually, the only argument is the named object from the server
See http://shiny.rstudio.com/tutorial/written-tutorial/lesson4/ for a full list with examples
When you change an input, it looks like the output changes in response
When the output needs to happen, it checks the input values
So the flow is actually the opposite direction
shiny and R call this reactivity
See here for some more details: https://shiny.rstudio.com/articles/understanding-reactivity.html
Many calculations in a Shiny app need to be reactive to be used throughout the app
For instance, something you calculate at the start may not be available later in the program
A plain old calculation that you make is NOT reactive
If you don’t make calculations reactive, you will frequently get errors that a function can only accept reactive objects
We can wrap calculations in a special reactive({})
function to make them reactive
This is kind of (but not exactly) like making them a function
Similar to a function, if you use the value later, it needs to
have ()
at the end
hbins <- reactive({
repbin <- input$reps / 100
trunc(repbin, 0)
})
hbins
variable, call it like it’s
a function:hbins()
Within the function for the input widget, include the
width =
argument
selectInput("num_bins", label = "Number of bins:",
choices = c(10, 20, 30, 40, 50), selected = 20,
width = 120%)
will make the input widget a bit wider
Wherever you place the output function (likely in “ui” portion)
plotOutput("expplot", width = "600px")
Step 1. Create the upload widget (ui portion)
fileInput("file1", "Choose CSV File",
multiple = FALSE,
accept = c("text/csv",
"text/comma-separated-values,text/plain", ".csv"))
Only the first two arguments are required
multiple = FALSE
means they can only upload 1 at a
time
The arguments in accept =
are the file types that
can be uploaded
Step 2. Actually read in the data (server portion)
output$contents <- renderTable({
req(input$file1)
df <- read.csv(input$file1$datapath)
})
The function read.csv
reads in .csv files
Three steps:
Step 1. Server side: Put the relevent variables into a dataframe (using a reactive function so the values can be used elsewhere)
saveData <- reactive({data.frame(
"reg_model" = input$reg_model,
"b0" = input$b0,
"b1" = input$b1,
"b0se" = input$b0se,
"b1se" = input$b1se,
"expeff" = expeff(),
"expLL" = expLL(),
"expUL" = expUL(),
check.names = F)
})
Step 2. Server side: Use the downloadHandler()
function
to write the data frame to a file
Give the file a name (e.g., “rcountd.csv”)
Use the write.csv
function to to save the reactive
data frame (saveData()
) in the file
output$downloadData <- downloadHandler(
filename = function() {"rcountd.csv"},
content = function(file) {
write.csv(saveData(), file, row.names = FALSE)
}
)
Step 3. UI side: Use the downloadButton()
function to
create a button that downloads the file you created
Here are two entries in the mainPanel()
function
(separated by ,
because each is just an argument)
downloadButton("downloadData", "Download"),
h4("Downloadable file in Excel format")
h4
is a text head command
Any time you want to do something only under certain conditions, you
can use an if
statement. (This applies to any R code, not
just shiny.)
if (condition) {
do_this_if_condition_is_true
}
condition
is the condition that much be satisfied to do
the thing
input$input_var > 5
input$condition == 1
input$fit_line == TRUE
If the condition is true, R will do the thing in the curly brackets
do_this_if_condition_is_true
This can be any code: calculations, a plot, a text output, etc.
It will happen only if the condition is satisfied
None of it will happen if the condition is false
So if some of it needs to happen, put that part outside the if statement
There are other types of if statements that let you have more options
if (condition1) {
do this
}
else if (condition2) {
do this instead
}
else {
do this if no conditions above were satisfied
}
Use something like this when you have several options the lead to different calculations, etc.