Anleitung zur Erstellung einer interaktiven Shiny-App mit RStudio
Die interaktive Shiny-App PredMaintApp zur Vorausschauenden Wartung wurde mit dem R-Paket Shiny erstellt. Dieses stellt einen einfachen und schnellen Zugang zur App-Erstellung mit R bereit. Das vorliegende Tutorial ist eine Schritt-für-Schritt-Anleitung zur Erstellung und Ausführung einer Shiny-App in der Entwicklungsumgebung RStudio.
Motivation
Shiny ist ein R-Paket mit dem einfach und schnell interaktive Webanwendungen mit R erstellt werden. Shiny verfügt über vorinstallierte Ein- und Ausgabe-Bedienelemente, die eine automatische "reaktive" Bindung untereinander besitzen. Damit kann die App interaktiv und live vom Benutzer angepasst werden.
Warum R Shiny?
Shiny-Apps sind ein ansprechendes Werkzeug, um Inhalte und Funktionen aus dem Bereich des Maschinellen Lernens auf einer Benutzeroberfläche darzustellen.
Der Anwender kann ohne Hintergrundwissen zur Programmiersprache oder mathematischen Methoden die notwendigen Tools verwenden.
Shiny-Apps können in der Cloud gehostet oder als eigenständige Anzeigetafel auf externen Ausgabemedien (Notebooks, Tablets, Smartphones usw.) verwendet werden
und bieten damit einen umfangreiches Anwendungsfeld an.
Warum RStudio?
Posit's RStudio
ist eine Entwicklungsumgebung für die Datenanalyse mit Hilfe der statistischen
Programmiersprache R, die in Open-Source- und kommerziellen Editionen erhältlich ist,
sowohl als Desktop als auch als CLoud-Anwendung.
Die zur Datenanalyse benötigten Algorithmen sind in Pakete zusammengefasst, die nach Bedarf geladen werden können.
Alle gängigen Aufgaben der Datenanalyse werden so abgebildet und über Pakete, die aus der R-Konsole installiert werden können, zur Verfügung gestellt.
Übersicht
Die Schritt-für-Schritt-Anleitung ist in vier Abschnitte gegliedert.
Zunächst werden die zur Erstellung einer Shiny-App benötigten
Pakete und Dateien beschrieben, mit diesen wird eine Mini-App erstellt,
die die Funktionsweise der miteinander kommunizierenden Ein- und Ausgabewidgets erläutert.
Die mit R Shiny entwickelten interaktiven Apps können über die Shiny Cloud ausprobiert werden.
YouTube-Video
Die Erstellung und Ausführung einer interaktiven Shiny-App und die Reaktivität der verwendeten Ein- und Ausgabewidgets wird durch ein Video (Screencast mit zusätzlichen Erläuterungen) veranschaulicht.
1 R-Pakete
Um eine Shiny-App zu erstellen, benötigt man zunächst das R-Paket Shiny. Für aufwendigere Benutzeroberflächen mit Dashboard, Themes und Tooltips werden weitere Pakete benötigt, wie shinydashboard oder shinyBS. Die benötigten Pakete werden in der RStudio-Konsole mit dem Befehl install installiert, z.B.
install.packages("shiny")
Eine Shiny-App kann informell als eine Internetseite mit Benutzeroberfläche (engl. ui, User Interface) beschrieben werden, die mit einem Computer verbunden ist, auf dem eine aktive R-Session läuft (engl. server).
Der Entwickler der Shiny-App kann die Oberfläche anpassen. Über vorinstallierte miteinander kommunizierende Ein- und Ausgabe-Widgets, also automatische "reaktive" Bindungen,
wird über den Server, der den R-Quellcode ausführt, die Bildschirmanzeige der Benutzeroberfläche aktualisiert.
Eine Übersicht über die Syntax und Methodik einer interaktiven Webanwendung mit Shiny finden Sie in dem hier verlinkten
Shiny-Cheatsheet.
2 App erstellen
Eine erste minimale Shiny-App ist einfach eine R-Datei, die wir hier vorlage.R nennen, die den folgenden Code enthält.
- Zeile 1: Das Shiny-Paket wird geladen und somit zur Verwendung zur Verfügung gestellt.
- Zeile 3: Die Benutzeroberfläche (ui) wird mit Hilfe der Funktion fluidPage() definiert, der später alle Elemente der Benutzeroberfläche als R-Funktionen hinzugefügt werden.
- Zeile 4: Eine Funktion mit Anweisungen, sowie R-Objekten für die Benutzeroberfläche, die erstellt und aktualisiert werden sollen.
- Zeile 7: Über die Funktion shinyApp() werden den Parametern Benutzeroberfläche (ui=) und Server (server=) die vorher beschriebenen Funktionen zugeordnet und somit zu einer ausführbaren Shiny-Anwendung verknüpft.
library(shiny) #Paket laden
ui <- fluidPage() # Funktion definiert die Benutzeroberfläche
server <- function(input, output){} # Funktion mit R-Anweisungen und -Objekten
# Funktion, die ui und server zu einer Shiny-Anwendung verknüpft
shinyApp(ui = ui, server = server)
Eine Shiny-App kann entweder als eine Datei (in unserem Fall vorlage.R) oder als zwei Dateien (ui.R und server.R) gespeichert werden. Die Alternative mit zwei Dateien bietet sich bei größeren Anwendungen an, damit der Quellcode übersichtlicher gestaltet werden kann. Verwendet man zwei Dateien, muss shinyApp() nicht aufgerufen werden, siehe Shiny Cheatsheet (deutsch) oder Shiny Dokumentation (englisch).
3 App ausführen
Die Datei vorlage.R wird ausgeführt, indem in RStudio auf den Button "Run App" geklickt wird. Es öffnet sich ein Fenster mit der noch leeren Shiny-App. Die Shiny App kann alternativ auch in einem Browser angezeigt werden.
Screenshot RStudio
Shiny-App im Browser
Da noch keine Elemente in der ui-Funktion erstellt/definiert wurden, erfolgt auch keine Anzeige auf der Oberfläche der App. Beim Ausführen erzeugt der in R geschriebene Code eine Webseite (HTML, CSS und Javascript) mit responsivem Design.
4 Mini-App
In diesem Abschnitt wird die vorlage.R-Datei erweitert, um eine Mini-App zu erstellen, die die Funktionsweise der miteinander kommunizierenden Ein- und Ausgabewidgets erläutert. Dazu werden die ui-Funktion um Elemente der Benutzeroberfläche und die server-Funktion um R-Anweisungen und -Objekte ergänzt.
4-1 Layout der App
Im ersten Schritt wird das Layout der App festgelegt, hierbei werden einzelne Elemente über die Panel-Funktion zu einem einzigen Element, einem Feld mit festen Eigenschaften, zusammengefügt. Mit verschiedenen Layout-Funktionen kann das Design und die Anordnung der Felder vorgegeben werden. In dieser Mini-App wird zuerst das Sidebar-Layout vorgestellt, das ein responsives Webdesign erstellt und das seitliche Feld und das Hauptfeld je nach Anzeigemedium nebeneinander oder untereinander anordnet. Die Änderungen werden unter dem Namen "miniApp" als neue R-Datei gespeichert.
Die Anpassungen in der ui-Funktion sehen wie folgt aus:
- Zeile 2: Die Layout-Funktion "sidebarLayout" wird geöffnet und in Zeile 5 geschlossen, darin sind das seitliche Feld und das Hauptfeld enthalten.
- Zeile 3: Das seitliche Feld "sidebarPanel" wird definiert, enthält hier aber noch keine Elemente.
- Zeile 4: Das Hauptfeld "mainPanel" wird definiert, enthält hier aber noch keine Elemente.
Quellcode
ui <- fluidPage(
sidebarLayout(
sidebarPanel(),
mainPanel()
)
)
Anzeige der App
Hier ist die Desktop-Ansicht dargestellt, das seitliche Feld (grau hinterlegt) und das Hauptfeld (weiß hinterlegt) werden nebeneinander angezeigt.
Da noch keine Elemente in der ui-Funktion erstellt/definiert wurden, sondern nur die entsprechenden Felder vorbereitet wurden, erfolgt auch keine Anzeige in den Feldern der App.
Da zur Übersicht und Navigaton innerhalb der App ein Titel und eine Menü-Führung sinnvoll ist, wird das obige Layout abgeändert, indem mit dem Layout "navbarPage" ein Titel vergeben und mehrere Felder/Panels zum Navigieren übereinander gelegt, d.h. Tabs angelegt, werden. Dazu wird die sidebarLayout-Funktion durch die navbarPage-Funktion ersetzt und die einzelnenen Tabs mit seitlichem Feld und Hauptfeld gefüllt.
- Zeile 2: Das Layout "navbarPage" wird als Funktion geöffnet und in Zeile 11 geschlossen.
- Zeile 3: Die erste tabPanel-Funktion mit Namen "Tab 1" wird geöffnet und in Zeile 6 geschlossen.
- Zeile 4, 5: sidebarPanel und mainPanel als Felder in Tab 1 werden aufgerufen.
- Zeile 7: Die zweite tabPanel-Funktion mit Namen "Tab 2" wird geöffnet und in Zeile 10 geschlossen.
- Zeile 8, 9: sidebarPanel und mainPanel als Felder in Tab 2 werden aufgerufen.
Quellcode
# Funktion
# definiert die Benutzeroberfläche
ui <- fluidPage(
navbarPage(title="Mini-App",
tabPanel("Tab 1",
sidebarPanel(),
mainPanel()
),
tabPanel("Tab 2",
sidebarPanel(),
mainPanel()
)
)
)
Anzeige der App
Mini-App mit zwei Navigations-Tabs
Hier ist die mobile Ansicht dargestellt, die Navigations-Tabs stehen untereinander, sowie das seitliche Feld (grau hinterlegt) und das Hauptfeld (weiß hinterlegt).
4-2 Statische HTML-Elemente in der Benutzeroberfläche
Da die Benutzeroberfläche der Shiny-Anwendung ein HTML-Dokument ist, werden statische, also nicht veränderbare, Elemente über R-Funktionen erzeugt. Zur Erstellung von statischen Elementen stehen Tags zur Verfügung, die den gleichnamigen HTML-Tags entsprechen. Für Überschriften: h1, h2, h3, für Links: a, für Bilder: img.
Mittels der abgebildeten Tags kann die Benutzeroberfläche mit Inhalt gefüllt werden. Bilder, die eingefügt werden sollen, müssen in einem Unterverzeichnis namens "www" gespeichert werden und können dann mit dem "img"-Tag eingefügt werden.
Soll die Benutzeroberfläche einen größeren statischen HTML-Bereich mit Links, Listen etc. enthalten, kann mit Hilfe der Funktion includeHTML() eine komplette externe HTML-Datei eingefügt werden. Dies bietet sich zum Beispiel dann an, wenn ein statischer Info-Text in der Sidebar eines jeden Tabs eingefügt werden soll. Im folgenden Beispiel wird in das sidebarPanel die Datei sidebar.html eingefügt.
ui <- fluidPage(
navbarPage(title="Shiny-App",
tabPanel("Info",
sidebarPanel(
includeHTML("sidebar.html")
),
mainPanel(
p("Dies ist der Inhalt-Bereich")
)
)
)
)
4-3 Anwendung in der Mini-App
In der Mini-App wird Text mittels des h3- und h4-Tags, Bilder mittels des img-Tags und Links mittels des a-Tags gesetzt.
Tab "Info": Erstellung eines Tabs mit Info-Text- Zeile 3: Der Info-Tab wird geöffnet und in Zeile 14 geschlossen.
- Zeile 5-9: Mittels des img-, h3- und h4-Tags wird ein Bild und Text in das seitliche Feld eingefügt.
- Zeile 12: Das Hauptfeld wird mittels des h4-Tags mit Text gefüllt.
Quellcode
# Funktion
# definiert die Benutzeroberfläche
ui <- fluidPage(
navbarPage(title="Mini-App",
tabPanel("Info",
sidebarPanel(
img(src = 'info-icon.png',
height = "40px"),
h3("Willkommen!"),
h4("Diese App [..]
[..]Programmiersprache R.")
),
mainPanel(
h4("Shiny ist...")
)
),
)
Anzeige der App (Smartphone)
Tab "Links": Erstellung eines Tabs mit Verlinkungen
In der Mini-App werden mittels des a-Tags Links gesetzt. Damit der Link vom Layout zum restlichen Text passt, wird die paste0()-Tag
als direkte HTML-Funktion genutzt, dazu wird der HTML()-Tag im R-Quellcode aufgerufen.
- Zeile 3: Der Tab "Links" wird geöffnet und in Zeile 10 geschlossen.
- Zeile 4: Das Hauptfeld wird mittels des HTML-Tags mit Text und einem Link gefüllt.
- Zeile 5, 6, 7: Im HTML-Tag wird mit dem paste0-Tag ein h4-Tag und ein Link verbunden.
Quellcode
# ui-Funktion
# definiert die Benutzeroberfläche
ui <- fluidPage(
navbarPage(title="Mini-App",
tabPanel("Links",
mainPanel(
HTML(paste0(h4("Hier gehts ... " ,
a(href="https://shiny.rstudio.com/",
"Shiny", target="_blank")
)))
)
)
)
Anzeige der App (Smartphone)
Tab "Links" mit einer Verlinkung
Die Links erscheinen durch die paste0-Funktion im selben Layout wie der Text.
4-4 Reaktive Ein- und Ausgabe-Elemente in der Mini-App
Die Funktionsweise der miteinander kommunizierenden Ein- und Ausgabewidgets wird anhand der Mini-App erläutert.
Auf aktuelle Werte eines Eingabeobjektes wird vom Server mit input$id-name zugegriffen.
Eingabewerte sind reaktionsfähig (engl. reactive) und werden sofort an die im Hintergrund laufende aktive R-Session (server-Funktion) weitergegeben.
Eingabewerte werden in der Benutzeroberfläche (ui-Funktion)
mit *Input()-Funktionen eingefügt/erstellt und Ausgabewerte aus der server-Funktion mit der *Output()-Funktion in die Benutzeroberfläche eingebunden.
Dazu müssen die Ausgaben mit einem Namen output$id-name benannt werden und der Ausgabe-Code von einer render*({})-Funktion umschlossen
werden, bevor die Ausgabe unter dem Namen output$id-name gespeichert wird.
Eine Kurzübersicht über die render*({})-Funktionen der server-Funktion und die *Output()-Funktionen der ui-Funktion finden Sie in
dem hier verlinkten "Spickzettel"
Shiny RStudio Cheatsheet.
4-5 Anwendung in der Mini-App
- Zeile 5-8: Ein Eingabewidget, Schieberegler, wird in der ui-Funktion erzeugt. Der Default wird auf den Wert 25 gesetzt und unter dem Namen "n" gespeichert. In Zeile 17 wird der Wert dieses Elementes von der server-Funktion zur Erstellung von Zufallszahlen mittels input$n abgerufen.
- Zeile 16: Die renderPlot({})-Funktion wird in der server-Funktion aufgerufen und dessen Ausgabe unter dem Namen output$hist gespeichert.
- Zeile 17-20: Das Histogramm wird mittels R-Befehlen erzeugt.
- Zeile 9: Mittels der PlotOutput()-Funktion wird das Ausgabeobjekt "hist" in die Benutzeroberfläche integriert.
Quellcode (ui- und server-Funktion)
# Funktion
# definiert die Benutzeroberfläche
ui <- fluidPage(
navbarPage(title="Mini-App",
tabPanel("Grafische Anzeige",
mainPanel(
sliderInput(inputId = "n",
"Anzahl der Zufallswerte:",
min=1,max=100,
value = 25),
plotOutput(outputId = "hist")
)
)
)
)
# Funktion
# definiert Inhalte
server <- function(input, output){
output$hist<-renderPlot({
hist(rnorm(input$n), freq=FALSE,
xlab="Wertebereich ",
ylab="Häufigkeit der Werte",
main="Histogramm")})
}
Anzeige der App (Smartphone)
Bei Änderungen am Schieberegler wir das Histogramm automatisch an die neu gezogene Stichprobe angepasst.
Autoren, Tools und Quellen
Autoren:
M.Sc. Anke Welz
Prof. Dr. Eva Maria Kiss
Tools:
- R: r-project.org
- RStudio: rstudio.com
- Shiny: shiny.posit.co
- Shiny Cloud: shinyapps.io
Quellen und weiterführende Links