Interactivity overview

Interactivity – what is it?

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

Interactivity – how can I do it?

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

  • But it also doesn’t require any connection to R to work

More ways to introduce interactivity

From least to most flexible / interactive:

  • flexdashboard package

  • shinydashboard package

  • shiny elements in a markdown file

  • stand-alone shiny app

flexdashboard

https://rmarkdown.rstudio.com/flexdashboard/

Done through a markdown document

  • After installing flexdashboard, there is a template available for your 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

shinydashboard

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

  • Note that it’s no longer “Knit” but “Run”

See shinydashboarddemo file for an example

shiny elements in a markdown file

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

Stand-alone shiny app

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

  • Put it in a folder called “shiny_demo”, open it in R, and run it

Shiny input functions

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

  • Some widgets have other options too

Shiny output functions

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

New topics

Reactivity

When you change an input, it looks like the output changes in response

  • But in fact, that’s not what’s going on

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

Reactivity: why do we care?

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

    • This is similar to “scope” in other programming languages

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

Reactivity: how to do it?

  • Where you make calculations (usually in the “server” portion):

hbins <- reactive({

repbin <- input$reps / 100

trunc(repbin, 0)

})

  • When you use this new hbins variable, call it like it’s a function:

hbins()

Using a “go” button

Reactivity has one major downside

If the output updates (or appears to update) every time you change an input:

  • You can confuse users because things are changing before they’re done

  • There can be some lag because your calculations take a few seconds

One option is to include a button that tells the app to actually calculate now

Using a “go” button

In the input section (with other inputs or in “ui” portion)

submitButton("Go!")

No other changes needed

Note. The actionButton() function is more versatile but more complicated.

Changing size of input / output objects: Sidebar

Input widgets in the sidebar are just arguments

  • Separately by ,

As an additional argument in the SidebarPanel()

  • width = 3 changes the sidebar width to 3 units

  • Total width of app is 12 units (scaled to the screen size)

  • Other options are in terms of pixels (px) or percentage (%)

Changing size of input / output objects: Input

Within the function for the input widget, include the width = argument

  • For example:

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

Changing size of input / output objects: Output

Wherever you place the output function (likely in “ui” portion)

  • Additional optional argument for width

plotOutput("expplot", width = "600px")

Uploading a file and using values from it

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

    • Useful if you want to control what can be uploaded

Uploading a file and using values from

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

Output a file and let users download it

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)
})

Output a file and let users download it

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)
}
)

Output a file and let users download it

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

  • This puts a text label that says “Downloadable file in Excel format” under the download button

If statements

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

}

If statements

condition is the condition that much be satisfied to do the thing

  • For example:

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

If statements

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

If statements

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.