7. Einführung in Shiny

Vorwort zu working directory, Daten und Packages

Die Daten für dieses Tutorial werden über Github zur Verfügung gestellt. Wenn Sie den Code mit eigenen Daten reproduzieren wollten, ersetzen Sie die URL mit ihrem lokalen Dateipfad.

Definieren Sie in diesem Fall Ihren “working directory”, ihr Arbeitsverzeichnis.

setwd("YOUR/FILEPATH") 
# this will not work. if you want to use it, define a path on your computer

Dabei handelt es sich um den Dateispeicherort, wo Ihre Daten und Skripte gespeichert sind. Weitere Infos finden Sie hier.

Der Code für das Speichern von Daten und Ergebnissen ist in diesen Tutorials deaktiviert. Ersetzen Sie zum Speichern “YOUR/FILEPATH” mit ihrem gewünschten Dateipfad.

Wir haben den Code zum Laden von packages so geschrieben, dass diese installiert werden, sofern diees noch nicht auf Ihrem PC abgespeichert sind. Anschließend werden diese direkt geladen. Sofern nicht anderweitig spezifiziert werden die packages an einer standardmäßigen Stelle auf Ihrem Computer abgespeichert.

Was ist Shiny?

Shiny ist ein R-Paket, das es einfach macht, interaktive Webanwendungen direkt aus R zu erstellen. Es können eigenständige Anwendungen auf einer Webseite gehostet, in R-Markdown-Dokumente eingebettet oder als Dashboards erstellt werden. Shiny Apps können auch um CSS-Themen, HTML-Widgets und JavaScript-Aktionen erweitert werden.

Ein kurzes Erklärvideo zum Funktionsumfang von Shiny findet sich auf der folgenden Seite.

Rstudio stellt zahlreiche Tutorials zum allgemeinen Umgang mit Shiny zur Verfügung. Diese sind sehr hilfreich beim Erlernen des Umgangs mit shiny.

if (!require(leaflet)) {install.packages("leaflet"); library(leaflet)}
if (!require(shiny)){install.packages("shiny"); library(shiny)}
if (!require(RColorBrewer)){install.packages("RColorBrewer"); library(RColorBrewer)}

Zahlreiche Beispiele zu den Einsatzmöglichkeiten von Shiny Apps und deren Visualisierungen finden sich in der Shiny Gallery.

Einfaches Beispiel

Das Shiny Paket stellt bereits eine einfache Shiny App als Beispiel zur Verfügung, anhand derer die grundlegende Funktionsweise anschaulich dargestellt ist:

runExample("01_Hello")

Grundlegender Aufbau von Shiny Applikationen

Shiny Applikationen bestehen aus zwei Komponenten. Einerseits aus einem Benutzeroberflächen-Objekt (ui = user interface) sowie einer Serverfunktion. Auf beide soll anhand des obigen Beispiels im Folgenden eingegangen werden:

User interface

Das Benutzeroberflächen-Objekt regelt, wie der Name sagt, die Interaktionsmöglichkeiten des Benutzers mit der Anwendung:

# Define UI for app that draws a histogram ----
ui <- fluidPage(

  # App title ----
  titlePanel("Hello Shiny!"),

  # Sidebar layout with input and output definitions ----
  sidebarLayout(

    # Sidebar panel for inputs ----
    sidebarPanel(

      # Input: Slider for the number of bins ----
      sliderInput(inputId = "bins",
                  label = "Number of bins:",
                  min = 1,
                  max = 50,
                  value = 30)

    ),

    # Main panel for displaying outputs ----
    mainPanel(

      # Output: Histogram ----
      plotOutput(outputId = "distPlot")

    )
  )
)

Serverfunktion

Die Server-Seite der Anwendung ist unten dargestellt. Ihr Aufbau ist eigentlich recht einfach - eine Zufallsverteilung wird als Histogramm mit der gewünschten Anzahl von Bins dargestellt. Sie werden jedoch auch feststellen, dass der Code, der den Plot erzeugt, in die Funktion renderPlot() eingebunden ist.

# Define server logic required to draw a histogram ----
server <- function(input, output) {

  # Histogram of the Old Faithful Geyser Data ----
  # with requested number of bins
  # This expression that generates a histogram is wrapped in a call
  # to renderPlot to indicate that:
  #
  # 1. It is "reactive" and therefore should be automatically
  #    re-executed when inputs (input$bins) change
  # 2. Its output type is a plot
  output$distPlot <- renderPlot({

    x    <- faithful$waiting
    bins <- seq(min(x), max(x), length.out = input$bins + 1)

    hist(x, breaks = bins, col = "#75AADB", border = "white",
         xlab = "Waiting time to next eruption (in mins)",
         main = "Histogram of waiting times")

    })

}

Shiny App erstellen

Abschließend verwendet man die shinyApp-Funktion, um ein Shiny-App-Objekt aus dem oben definierten UI/Server-Paar zu erstellen:

# Create Shiny app --> Ausführung des Codes
app <- shinyApp(ui = ui, server = server)

app

Der Code, das ui-Objekt, die Serverfunktion und der Aufruf der shinyApp-Funktion werden in einem R-Skript (.r) gespeichert. Dies ist die gleiche Grundstruktur für alle Shiny-Anwendungen.

Shiny und Leaflet kombinieren

Die Vorteile, Karten Interaktiv zu erkunden, liegen auf der Hand. Entsprechend existieren einige Beispiele unterschiedlicher Komplexität, die am Ende des Tutorials aufgeführt sind.

Der grundsätzliche Aufbau sieht wie bei den obigen Beispielen die Kombination des User-Interfaces und der Serverfunktion vor, welche gemeinsam über die Funktion shinyApp ausgeführt werden.

ui <- fluidPage(
    leafletOutput("my_leaf")
)

server <- function(input, output, session){
    
    output$my_leaf <- renderLeaflet({
        
        leaflet() %>%
            addProviderTiles(providers$Esri.WorldImagery) %>%
            setView(lat = 47.98, lng = 7.8, zoom = 12)
        
    })
    
}

shinyApp(ui, server)

Im Folgenden soll ein vergleichweise einfaches Beispiel analysiert werden. Dies kann als Ausgangspunkt für komplexere Apps verwendet werden. Der Abschnitt ist von dieser Website inspiriert.

Zunächst wird ein Punktdatensatz geladen:

urlfile <- "https://raw.githubusercontent.com/RafHo/teaching/master/geodaten_kommunizieren/datasource/lng_lat_shiny.csv"

df <- read.csv(urlfile, sep = ",", header = TRUE, encoding = "UTF-8")

#cloud <- dplyr::filter(df, node_label == "cloud cover")
temp <- dplyr::filter(df, node_label == "temperature level")
#precip <- dplyr::filter(df, node_label == "shortterm precipitation")

Der Datensatz enthält einen Temperaturindex, der in der Spalte value_index enthalten ist. Die Indexwerte beziehen sich jeweils auf eine bestimmte Punktkoordinate. Die Indexwerte dienen als Ausgangspunkt für die interaktiv einstellbare Sichtbarkeit der Punkte.

# UI wird erstellt. Min und Max-Werte sind dem Datensatz entnommen
ui <- fluidPage(
    sliderInput(inputId = "slider", 
                label = "values",
                min = -3,
                max = 1,
                value = 0,
                step = 1),
    leafletOutput("my_leaf")
)


server <- function(input, output, session){
      temp <- dplyr::filter(df, node_label == "temperature level")
        
    ## create static element --> der view der Karte
    output$my_leaf <- renderLeaflet({
        
        leaflet() %>%
            addProviderTiles(providers$Esri.WorldImagery) %>%
            setView(lat = 47.98, lng = 7.8, zoom = 12)
        
    })
    
    ## filter data --> regelt das Verhältnis von Kartenansicht und slider
    df_filtered <- reactive({
        temp[temp$value_index >= input$slider, ]
    })
    
    ## respond to the filtered data --> LeafletProxy sorgt dafür dass immer wieder gerendert werden kann
    observe({

        leafletProxy(mapId = "my_leaf", data = df_filtered()) %>%
            clearMarkers() %>%   ## clear previous markers
            addCircles(popup = ~value_label) # zeigt die popups an
      
      
      
    })
    
}

# zum Anzeigen müssen ui und server zusammen ausgeführt werden
shinyApp(ui, server) 

Shiny-App Veröffentlichen

Die Überführung einer Shiny-App in Blogdown ist nicht ohne weiteres möglich, da das Blogdown-Paket für statische Websites, d.h. nur für statische Websites konzipiert ist. Der Unterschied zwischen dynamischen und statischen Websites wird beispielsweise hier erklärt. Entsprechend kann Shiny nicht mit Blogdown verwendet werden, da Shiny Apps eine Live-R-Sitzung benötigen. Diese Problem kann umgangen werden, wenn die App auf einem Server veröffentlicht wird, auf dem R und Shiny Server verfügbar sind. Über diesen Server wird dann die App auf der von Blogdown generierten Website eingebettet.

Im folgenden wird die Bereitstellung einer Shiny-App via shinyapps.io in R-Studio erläutert. Dazu ist dort ein Account erforderlich (oder eine Verknüpfung eines Google- bzw. GitHub-Accounts).

Voraussetzungen

Das Paket rsconnect kann direkt aus CRAN installiert werden. Um sicherzustellen, dass Sie die neueste Version haben, führen Sie folgenden Code in Ihrer R-Konsole aus:

if (!require(rsconnect)) {install.packages("rsconnect"); library(rsconnect)}

Mit Account verbinden

Das Paket rsconnect muss für Ihr Konto mit einem Token und einem Schlüssel autorisiert sein. Dafür sollten sie Ihre Credentials auf www.shinyapps.io suchen und nach folgendem Muster in der Konsole ausführen. Nachdem Sie den Befehl erfolgreich in R eingegeben haben, ist dieser Computer nun berechtigt, Anwendungen auf Ihrem Konto bei shinyapps.io bereitzustellen.

rsconnect::setAccountInfo(name='username',
              token='XXXXEED5ZZZZZZ09CYYYYYUUUZT',
              secret='GJHGOUHZ')

Bereitstellen

Sobald das Paket konfiguriert ist, können Sie Ihre erste Anwendung bereitstellen. Führen Sie den folgenden Code in Ihrer R-Konsole aus.

rsconnect::deployApp('path/to/your/app')

Weitere Beispiel

Die obigen Beispiele machen klar, dass es bei der Erstellung interaktiven Karten quasi keine Grenze nach oben gibt 1. Hier sind einige von Ihnen aufgelistet:


  1. Sofern die Daten dies hergeben…↩︎

  2. Die größte Sammlung von Super Zips befindet sich in der Nähe von Washington, D.C.↩︎

Previous