Today, we’ll discover how you can use the power of R (and RStudio) to create, for instance, an interactive visualization with the ShinyApp framework.

πŸ’‘ What is a ShinyApp?

Shiny is a framework that allows you to create web applications - ShinyApps 😊 You can use them for multiple purposes - a common example is visualizing data (for instance the Scottish Household Survey), building interactive appendices, search engines, and so much more ✨

small_image

Alternative text Scottish Household Survey showing a visualization of data in a line chart

small_image

Alternative text Appendix of an academic paper showing a correlation matrix

small_image

Alternative text Search engine showing a coordinate system where papers are located and a sidebar on the left-hand side that allows the users to select papers relevant to them

πŸ’‘ What does a ShinApp need?

A ShinyApp consists of two central components. The UI and the server – or, as I like to think about them, the body πŸ‘€ and the brain 🧠

πŸ’‘ What is the UI?

The user interface (or short UI) is like the body of your app πŸ‘€ It allows you to define how it looks and where the components (such as text, visualizations, or tables) are placed. It defines the outer appearance of your app. The code works as follows:

small_image

Alternative text

An image showing a pseudo UI

ui <- fluidPage(
titltePanel("Your Title"),
sidebarLayout(sidebarPanel(... Some content...), 
mainPanel(...place-your-plot...))

πŸ’‘ What is the server?

The server is the brain - here’s where all the computing happens 🧠 You can dump (more or less) all your typical functions (such as plotting something with πŸ“¦{ggplot2}) in here πŸ€— It can look like this:

small_image

Alternative text

An image showing a pseudo server

server <- function(input, output{output$first_plot <- renderPlot({...create-your-plot....})}

πŸ‘©πŸΌβ€πŸ’» How do you set up your own ShinyApp?

But how do we set it up? Easy!

small_image

Alternative text

Code snapshot showing how to create a simple ShinyApp

###Build your first ShinyApp ✨

library(shiny) # Shiny
library(ggplot2) # For plotting
library(dplyr) # For data wrangling
library(overviewR) # To get the data

data(toydata)

#---------------------------------------------------------#
##UI πŸ‘€
ui <- fluidPage(titlePanel ("Visualization"),
                ###Define sidebar
                sidebarLayout(sidebarPanel(
                  checkboxGroupInput(
                    "countries",
                    h4("Select the countries"),
                    choices = unique(toydata$ccode),
                    selected = c("RWA", "AGO")
                  )
                ),
                ###Show the visualization
                mainPanel(plotOutput("first_plot"))))
πŸ™‹πŸΌβ€β™€οΈ
#---------------------------------------------------------# 
##Server 🧠
server <- function (input, output) {
  output$first_plot <-
    renderPlot({
      ###Generate a normal ggplot2 with some data wrangling
      toydata %>%
        dplyr::filter(ccode %in% input$countries) %>%
        dplyr::mutate(year = as.integer(year)) %>% 
        ggplot2::ggplot(aes(x = year, y = population)) +
        ggplot2::geom_col() +
        ggplot2::facet_wrap( ~ ccode) + 
        ggplot2::theme_minimal()
    })
}

#---------------------------------------------------------#
##Let it run πŸƒοΈ
shinyApp (ui = ui, server = server)

What you now see in code is how you can fill the UI and server with content. I picked checkboxes for the selection in the sidebar of the UI (but there are multiple other possibilities for more control widgets) and added a ggplot2 inside the renderPlot function in the server to generate the visualization πŸ‘©πŸΌβ€πŸŽ¨

And here’s how it “runs” (just highlight the code and let it run - a new window with your first ShinyApp will open πŸ™Œ)

small_image

Alternative text GIF showing how to run code and how a simple ShinyApp showing bar graphs opens

What I learned from building ShinyApps:

  • Sketch your ShinyApp on paper (or tablet) with a pencil. This helps to understand what you want to get (and also what’s probably missing). It’s a bit like doing a design workshop with yourself.
  • Start simple. Trust me, you ShinyApp will get complicated soon enough πŸ˜„
  • πŸ“¦ {echarts4r} is a package for making beautiful visualizations
  • If you’re up for a production-ready ShinyApp, have a look at πŸ“¦ {golem} (and the Golemverse)
  • If you’re not so much up for writing code, have a look at πŸ“¦ {shinyuieditor} - it allows you to create a UI without coding

πŸ’‘ What is reactivity and what does it have to do with a carrier pigeon?

To better understand how a ShinyApp works, it’s good to understand reactivity. To describe it, I love the image of a carrier pigeon 🐦 (I picked up this idea when reading a post by Garett Grolemund - so all credits go to him ✨):

What reactivity does is “a magic trick [that] creates the illusion that one thing is happening, when in fact something else is going on”. Your ShinyApp only re-runs those parts where it is necessary. But what does this have to do with a carrier pigeon? Have a look at the GIF:

small_image

Alternative text GIF showing a pigeon carrier flying to the server to update a visualization when it is relevant

It shows your ShinyApp (bottom right) and the server (top right). The user (bottom left) asks for something. In the first round, the user asks for “Rwanda” and - after checking, the ShinyApp does not re-run because it already shows Rwanda. In the next round, the user asks for “Rwanda” and “Angola” - the ShinyApp evaluates and initiates a re-run to update the requested selection. Here comes the carrier pigeon 🐦 It starts sending the signal to update to the server. Once it has delivered the message, it comes back to where it started and waits until it gets a new message to deliver (just like a carrier pigeon 😊).

This was a simple wrap-up of Garrett Grolemund’s post - if you want to know more about reactive values and observers, have a look here πŸ‘©πŸΌβ€πŸ’»


More helpful resources:

  • πŸ—‚ As announced at RStudioConf2022, you can now also build ShinyApps in Python! Rami Krispin set up a great repository that shows you how to set up your ShinyApp in Python using shinyelive πŸ’»
  • πŸ“– If you’re up for more input on ShinyApps, here’s the bible of Shiny: “Mastering Shiny”
  • πŸ“Ί And a recording of a talk I gave at CorrelAid’s CorrelCon 2020 about the topic
  • πŸ‘©πŸΌβ€πŸ« And here are the slides and the code (including a πŸ“¦{ggplot2} and πŸ“¦{echarts4r} comparison) (it’s the material for the CorrelCon 2020)

πŸ“ And if you also keep thinking about brains and bodies, here is more of it to summarize the key points πŸ€“ (also as πŸ“„PDF for you to download here):

small_image

Alternative text

A visual summary of ShinyApps

left side: User interface (body) that defines the outer appearance of the app An image showing a pseudo UI

ui <- fluidPage(
titltePanel("Your Title"),
sidebarLayout(sidebarPanel(... Some content...), 
mainPanel(...place-your-plot...))

right side:

server (brain) where all the calculation happens
An image showing a pseudo server
server <- function(input, output{output$first_plot <- renderPlot({...create-your-plot....})}