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:
Arda Kosars führt in die Thematik der [interaktiven Kartographie] (https://www.datascience.com/blog/beginners-guide-to-shiny-and-leaflet-for-interactive-mapping) anhand des NYPD Seven Major Felonies dataset ein.
Joy P. Wyckoff visualiesiert und analysiert Erdbeben weltweit anhand des earthquake datasets des USGS.
Nic Crane visualisiert eine interaktive Karte der Medianeinkommen in den Londoner Borroughs anhand des Average Income of Tax Payers, Borough datasets.
Auch auf der Hilfeseite von R Studio findet sich eine Einführung in die Interaktion von Leaflet und Shiny.
Darunter auch das sehr komplex aufgebaute Superzip Beispiel, welches die Postleitzahl-Bezirke der USA anhand der höchsten Einkommen und College Abschlüsse interaktiv visualisiert 2.
Ein weiteres Beispiel anhand eigens kreierter Daten.