Shiny

What it is and the logic behind it

Logic

ui (User Interface)

The container, whatever sees the user

Used for setting the desired configurations of options that will be elaborated in the server

Used for displaying the results of the computations that took place in the server

server

It gets the work done, according to the configuration set in the UI

Replaces the results into the allocated spaces

UI and Server work in a flow, communicating to each other (Figure 1).

flowchart LR

    UI["**UI**<br/><br/>Set the options<br/>Displays the results"]
    SERVER["**SERVER**<br/><br/>Elaborates the options<br/>Sends back the results"]

    UI -->|"Input"| SERVER
    SERVER -->|"Output"| UI

    style UI fill:#2b6c8e,stroke:#1b4258,stroke-width:2px,color:#ffffff
    style SERVER fill:#8fd36f,stroke:#4c8b3a,stroke-width:2px,color:#ffffff

    linkStyle default stroke:#FFD700,stroke-width:5px

Figure 1: Interaction between the user interface (UI) and the server.

Basics

install.packages("shiny") # install
library(shiny) # use it
1ui = fluidPage(
   [...]
  )
2server = function(input, output){
  [...]
}
3shinyApp(ui, server)
1
Define the ui
2
Define the server
3
Shine

The ui contains two kinds of elements:

  • inputs, the controls the user plays with (a menu, a slider, a box to type in, a button…)
  • outputs, empty boxes where the server will put the results (a text, a plot, a table…)

There is a widget for (almost) everything: numbers, text, dates, files… We see the most useful ones in Input widgets and Outputs and render functions.

A first app

An astonishing result

First, play with it: choose an option in the menu and look at the text below.

#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true
#| components: [viewer]
#| viewerHeight: 220
library(shiny)

ui = fluidPage(
  selectInput(inputId = "mySelection",
              label = h3("Select box"),
              choices = list("Choice 1" = 1, "Choice 2" = 2, "Choice 3" = 3),
              selected = 1),
  verbatimTextOutput(outputId = "myOutput")
)

server = function(input, output) {
  output$myOutput = renderPrint({
    paste("This is my choice:", input$mySelection)
  })
}

shinyApp(ui, server)

The code behind it

Input and output, in the ui and in the server:

ui = fluidPage(
  selectInput(inputId = "mySelection",
              label = h3("Select box"),
              choices = list("Choice 1" = 1, "Choice 2" = 2, "Choice 3" = 3),
              selected = 1),
  verbatimTextOutput(outputId = "myOutput")
)

server = function(input, output) {
  output$myOutput = renderPrint({
    paste("This is my choice:", input$mySelection)
  })
}

shinyApp(ui, server)
  • In the ui, selectInput() creates the menu you just used, called mySelection, and verbatimTextOutput() reserves the empty box below it, called myOutput
  • In the server, input$mySelection reads the choice of the user, and output$myOutput fills the box with the result

The names are what connects the two pieces: we look at them closely in How Shiny thinks.

In the next page we put this same app in an RStudio project, with the ui in a script called ui.R and the server in a script called server.R.