5 min read

Interactive Web Applications with Shiny. An intuition.

library(tidyverse)
library(shiny)

1 Introduction

Shiny ist ein R-Paket, mit dem man interaktive Web-Apps direkt aus R heraus erstellen kann. In R Studio gibt es dafür zwei Möglichkeiten.

File -> New File -> Shiny Wep App…

  • Möglichkeit 1: Single File (app.R)
  • Möglichkeit 2: Multiple File (ui.R/server.R)

Nachfolgend wird jeweils nur die Syntax für Variante 1 dargelegt.

Für diesen Post wurde der Datensatz IMDB-Movie-Data von der Statistik Plattform “Kaggle” verwendet. Eine Kopie des Datensatzes ist unter https://drive.google.com/open?id=13ytotLAXb70lgYHnblPbUWr9cb2z7SaN abrufbar.

movie <- read_csv("IMDB-Movie-Data.csv")

2 Preparation

movie %>% separate(Genre, into = c("main genre", "further genre1", "further genre2")) %>% 
  select(Genre = `main genre`, Titel = Title, Spielfilmlaenge = `Runtime (Minutes)`, Bewertung = Rating, Waehlerstimmen = Votes, Einnahmen = `Revenue (Millions)`, Metascore) -> movie2
## Warning: Expected 3 pieces. Additional pieces discarded in 110 rows [1,
## 2, 13, 20, 25, 33, 35, 36, 37, 49, 61, 65, 68, 81, 86, 95, 98, 103, 110,
## 122, ...].
## Warning: Expected 3 pieces. Missing pieces filled with `NA` in 332 rows
## [3, 8, 18, 19, 22, 26, 28, 29, 31, 32, 40, 42, 43, 45, 47, 50, 53, 58, 60,
## 69, ...].

3 Scatter Plot

Syntax: Single File (app.R)

ui <- fluidPage(
  
  
  sidebarLayout(
    
    
    sidebarPanel(
      
      
      selectInput(inputId = "y", 
                  label = "Y-axis:",
                  choices = c("Spielfilmlaenge", "Bewertung", "Waehlerstimmen", "Einnahmen", "Metascore"), 
                  selected = "Bewertung"),
      
      
      selectInput(inputId = "x", 
                  label = "X-axis:",
                  choices = c("Spielfilmlaenge", "Bewertung", "Waehlerstimmen", "Einnahmen", "Metascore"), 
                  selected = "Spielfilmlänge"),
      
      
      selectInput(inputId = "z", 
                  label = "Color by:",
                  choices = c("Bewertung", "Genre"),
                  selected = "Genre")
    ),
    
    
    
    
    mainPanel(
      plotOutput(outputId = "scatterplot")
    )
  )
)


server <- function(input, output) {
  
  
  output$scatterplot <- renderPlot({
    ggplot(data = movie2, aes_string(x = input$x, y = input$y,
                                     color = input$z)) +
      geom_point()
  })
}

shinyApp(ui = ui, server = server)

Result

“Interactive Scatter Plot”

4 Scatter Plot with slider input

Syntax: Single File (app.R)

ui <- fluidPage(
  
  
  sidebarLayout(
    
    
    sidebarPanel(
      
      
      selectInput(inputId = "y", 
                  label = "Y-axis:",
                  choices = c("Spielfilmlänge", "Bewertung", "Wählerstimmen", "Einnahmen", "Metascore"), 
                  selected = "Bewertung"),
      
      
      selectInput(inputId = "x", 
                  label = "X-axis:",
                  choices = c("Spielfilmlänge", "Bewertung", "Wählerstimmen", "Einnahmen", "Metascore"), 
                  selected = "Spielfilmlänge"),
      
      
      sliderInput(inputId = "alpha", 
                  label = "Alpha:", 
                  min = 0, max = 1, 
                  value = 0.5)
    ),
    
    
    
    
    mainPanel(
      plotOutput(outputId = "scatterplot")
    )
  )
)


server <- function(input, output) {
  
  
  output$scatterplot <- renderPlot({
    ggplot(data = movie2, aes_string(x = input$x, y = input$y,
                                     color = input$z)) +
      geom_point(alpha = input$alpha)
  })
}

shinyApp(ui = ui, server = server)

Result

“Interactive Scatter Plot with slider input”

5 Scatter Plot plus Density Plot

Syntax: Single File (app.R)

ui <- fluidPage(
  
  
  sidebarLayout(
    
    
    sidebarPanel(
      
      
      selectInput(inputId = "y", 
                  label = "Y-axis:",
                  choices = c("Spielfilmlänge", "Bewertung", "Wählerstimmen", "Einnahmen", "Metascore"), 
                  selected = "Bewertung"),
      
      
      selectInput(inputId = "x", 
                  label = "X-axis:",
                  choices = c("Spielfilmlänge", "Bewertung", "Wählerstimmen", "Einnahmen", "Metascore"), 
                  selected = "Spielfilmlänge")
      
    ),
    
    
    
    
    mainPanel(
      plotOutput(outputId = "scatterplot"),
      plotOutput(outputId = "densityplot", height = 200)
    )
  )
)


server <- function(input, output) {
  
  
  output$scatterplot <- renderPlot({
    ggplot(data = movie2, aes_string(x = input$x, y = input$y,
                                     color = input$z)) +
      geom_point()
  })
    
  output$densityplot <- renderPlot({
    ggplot(data = movie2, aes_string(x = input$x)) +
      geom_density()
      
  })
}

shinyApp(ui = ui, server = server)

Result

“Interactive Scatter Plot plus Density Plot”

6 Scatter Plot plus Correlation

Syntax: Single File (app.R)

ui <- fluidPage(
  
  
  sidebarLayout(
    
    
    sidebarPanel(
      
      
      selectInput(inputId = "y", 
                  label = "Y-axis:",
                  choices = c("Spielfilmlänge", "Bewertung", "Wählerstimmen", "Einnahmen", "Metascore"), 
                  selected = "Bewertung"),
      
      
      selectInput(inputId = "x", 
                  label = "X-axis:",
                  choices = c("Spielfilmlänge", "Bewertung", "Wählerstimmen", "Einnahmen", "Metascore"), 
                  selected = "Spielfilmlänge")
      
    ),
    
    
    
    
    mainPanel(
      plotOutput(outputId = "scatterplot"),
      textOutput(outputId = "correlation")
    )
  )
)


server <- function(input, output) {
  
  
  output$scatterplot <- renderPlot({
    ggplot(data = movie2, aes_string(x = input$x, y = input$y,
                                     color = input$z)) +
      geom_point()
  })
    
    output$correlation <- renderText({
     r <- round(cor(movie2[, input$x], movie2[, input$y], use = "pairwise"), 3)
      paste0("Correlation = ", r, "Beachte: Wenn die Beziehung zwischen den zwei Variablen nicht linear ist, wird der Korrelationskoeffizient nicht sinnvoll sein.")
    
      
  })
}

shinyApp(ui = ui, server = server)

Result

“Interactive Scatter Plot plus Correlation”

7 Scatter Plot plus regression analysis

Syntax: Single File (app.R)

ui <- fluidPage(
  
  
  sidebarLayout(
    
    
    sidebarPanel(
      
      
      selectInput(inputId = "y", 
                  label = "Y-axis:",
                  choices = c("Spielfilmlänge", "Bewertung", "Wählerstimmen", "Einnahmen", "Metascore"), 
                  selected = "Bewertung"),
      
      
      selectInput(inputId = "x", 
                  label = "X-axis:",
                  choices = c("Spielfilmlänge", "Bewertung", "Wählerstimmen", "Einnahmen", "Metascore"), 
                  selected = "Spielfilmlänge")
      
    ),
    
    
    
    
    mainPanel(
      plotOutput(outputId = "scatterplot"),
      textOutput(outputId = "avg_x"), 
      textOutput(outputId = "avg_y"), 
      verbatimTextOutput(outputId = "lmoutput")
      
    )
  )
)


server <- function(input, output) {
  
  
  output$scatterplot <- renderPlot({
    ggplot(data = movie2, aes_string(x = input$x, y = input$y,
                                     color = input$z)) +
      geom_point()
  })
    
  
  output$avg_x <- renderText({
    avg_x <- movie2 %>% pull(input$x) %>% mean() %>% round(2)
    paste("Average", input$x, "=", avg_x)
  })
  

  output$avg_y <- renderText({
    avg_y <- movie2 %>% pull(input$y) %>% mean() %>% round(2)
    paste("Average", input$y, "=", avg_y)
  })
  

  output$lmoutput <- renderPrint({
    x <- movie2 %>% pull(input$x)
    y <- movie2 %>% pull(input$y)
    summ <- summary(lm(y ~ x, data = movie2)) 
    print(summ, digits = 3, signif.stars = FALSE)
  })
  
}


shinyApp(ui = ui, server = server)

Result

“Interactive Scatter Plot plus regression analysis”

8 Conclusion

Dies war lediglich nur ein sehr kleiner Einblick in das Package shiny. Interaktive Diagramme lassen sich auf diese Weise relativ leicht erstellen und als app.R zu anderen R-Usern verschicken. Hat der Empfänger keine Zugriff auf R, so kann man die erstellten Diagramme auch online stellen (siehe hier: “shinyapps.io”) und per Link verschicken.