Lecture 25 (Day 1): Intro to Shiny apps

What is Shiny?

Shiny apps are not your standard websites!

  • Most web pages are a set of static pages that you navigate with links (like this course website!)
  • Shiny apps are reactive apps, which receive packets of information from other places (in our case, the user– but it could be other things like databases) and respond to those packets of information in real time.
  • Shiny apps are composed of elements (often called widgets) that the user interacts with.
  • shiny is an R package that helps you write Shiny apps.

whatisshiny - Production-ready apps must be deployed on a server. Posit provides free server instances for Shiny users, but this can also be an instance hosted by your institution. - You can also use Shiny to capture the logic within the app and use it to return code that will reproduce certain outputs (shinymeta) - More on this later, but Shiny apps can also be embedded in things like RMarkdown documents.


Creating a Shiny app

Task: Go to a new RStudio window and go to File –> New File –> Shiny web app. You’ll get a pop-up window that asks you to choose an app name and a directory.


Task: Pick your app name and Multiple File and click ‘Create’.

Note: The distinction between the ‘Multiple File’ and ‘Single file’ options is purely a matter of how you like to work. This choice will not affect functionality.

  • You will see two scripts, “ui.R” and “server.R”.
  • These files are automatically populated with code for a dummy app- sometimes the easiest way to build an app is to start with these building blocks and start changing elements to get the functionality you want.
  • From either file, you can click “Run App” and it will open a window with the app as it would appear. This button is the equivalent of a call to runApp() in the console.


Success: Voila! You have rendered your first app. As you’re building your app, you will end up pressing this button many…many times.

Adding an element

Now that you have a template shiny app set up, you can build on it!

Task: Let’s add a plot element to this app called EruptionScatter. Go to server.R and add this to the server:

  output$EruptionScatter <- renderPlot({
      
      # just a little scatterplot
      plot(faithful$eruptions,faithful$waiting, 
           pch = 19,col = scales::alpha("darkblue",0.5),
           xlab = "Eruption time (mins)", ylab = "Waiting time to next eruption (mins)")
    })

When you click “Render App”, it doesn’t appear in the app! Why not? Because we also need to put it in the UI in order for it to appear. After you have been writing code all day, the easiest oversights to make are calling something the wrong type of render object or putting something in the server but forgetting to add it to the ui.

Task: You have to tell R what type of output object it is. Add the element EruptionScatter to the ui, so that your mainPanel section looks like this:

 mainPanel(
            plotOutput("distPlot"),
            plotOutput("EruptionScatter")
        )

Note: In order for something to appear in your app, it must be in the ui.R.

When you click “Run App,” yay! Your new plot element has appear in the UI.


Lecture 26 (Day 2): Building out and deploying Shiny apps

Leaflet maps in Shiny

Leaflet makes maps you can serve as standalone HTMLs. You can also embed them in:

  • Markdown or Quarto
  • Shiny apps

They’re very flexible! And they’re interactive.

Making your base leaflet plot

You can make a map in leaflet that renders to an HTML without any extra bells and whistles.

Embedding a Shiny app in a Markdown document

You can embed a Shiny app in a Markdown / Quarto page.

A Markdown document with shiny widgets and outputs is called an “interactive document.”

To make a Markdown document interactive, you add the following to the yaml header:

---
runtime: shiny
output:html_document
---

You can do it with an inline definition, like this:

library(palmerpenguins)
library(ggplot2)
library(shiny)
shinyApp(
  ui = fluidPage(
    checkboxGroupInput(
      inputId = "species",
      label = "Penguin species:",
      c(
        "Gentoo" = "Gentoo",
        "Adelie" = "Adelie",
        "Chinstrap" = "Chinstrap"
      ),
      selected = c("Gentoo", "Adelie")
    ),
    plotOutput("penguinPlot")
  ),
  server = function(input, output) {
    output$penguinPlot <- renderPlot({
      penguins_plot <- subset(penguins, species == input$species)
      p1 <- ggplot(
        penguins_plot,
        aes(x = bill_length_mm, y = bill_depth_mm, color = species)
      ) +
        geom_point(size = 4) +
        scale_color_brewer(palette = "Dark2") +
        ylab("Bill depth (mm)") +
        xlab("Bill length (mm)") +
        theme_light(base_size = 14)
      p1
    })
  },
  options = list(height = 500)
)

You can also call a Shiny app defined in another directory; it would look like this:

library(shiny)
shinyAppDir(
  system.file("examples/01_hello", package="shiny"),
  options = list(width = "100%", height = 700)
)

Creating interactive documents with Markdown and Shiny

You can embed shiny widgets in Markdown documents. Because those render differently than a static HTML file (like this one), there are instructions for creating interactive documents here and source code here.

Other useful Shiny things

Display modes

Shiny has different display modes.

Normal display

The default is display.mode = "normal" which returns the usual Shiny looking interface:

Showcase display

But you can also use display.mode = "showcase", which shows the source code for the app alongside the content. This can be nice for teaching!

Note that “showcase mode” (the shiny interface that shows both ui and code at the same time) won’t work in Markdown docs.

Resources

User experience (UX)

Since you’re at UW, you can take advantage of UW IT’s UX testing consultations: https://uxdesign.uw.edu/consultations.html

Pilot testing

  • if your institution doesn’t have UX resources, design pilot testing so that you get helpful feedback on UX: