| Reporting mit R The R Bootcamp |   | 
 
 
 from https://dilbert.com/
In diesem Practical übst du, dynamische Dashboards in Markdown zu erstellen. Ziel ist es dieses Dashboard zu erstellen.
Am Ende des Practicals wirst du wissen wie man:
leaflet plottet.plotly interaktiv macht.Öffne dein TheRBootcamp R Projekt. Es sollte die Ordner 1_Data, 2_Assets und 3_Markdown enthalten.
Öffne ein neues RMarkdown Skript und wähle das Template “Flex Dashboard” aus (siehe screenshot unten).
Speichere das neue Skript unter dem Namen dashboards_I_practical.Rmd im 3_Markdown Ordner.
Schreibe als Titel Dashboards I Practical hinein.
Lösche alles unterhalb des setup R chunks.
tidyverse, plotly, leaflet, viridis, htmltools, lubridate, patchwork und flexdashboard (letzteres sollte, wenn du das richtige Template ausgewählt hast, bereits im setup Chunk als library() Befehl eingefügt sein).# Lade Pakete
library(flexdashboard)
library(tidyverse)
library(plotly)
library(leaflet)
library(viridis)
library(htmltools)setup chunk den airbnb Datensatz mit read_csv(), so wie du das in den bisherigen Practicals auch gemacht hast.Beim Erstellen eines Dashboards ist es hilfreich, sich von Beginn an ein Layout zurechtzulegen, welches man dann Schritt für Schritt auffüllt. Eine Skizze oder zumindest eine bildliche/ konzeptuelle Vorstellung ist daher wichtig.
Öffne das Ziel-Dashboard Link in einem separaten Tab in deinem Browser. Wir werden während dieses Practicals immer wieder darauf verweisen.
Schau dir das Dashboard genau an, um einen Eindruck zu erhalten, was du nachbauen sollst, wie das Layout aussieht und welche Komponenten verwendet werden.
Setze zunächst das Seitenlayout des Dashboards auf. Füge drei Seiten hinzu: Übersicht der Airbnbs in Berlin, Entwicklung über Zeit und Bewertungen der Airbnbs. Schreibe dazu die Titel in dein Markdown, unterhalb des R Setup chunks und füge eine Zeile von Gleichheitszeichen ======== unter jedem Titel ein.
TITEL
======================================================================In flexdashboards sind Seiten standardmässig spaltenweise ausgerichtet. Schaue dir das Dashboard nochmals an. Sind alle drei Seiten spaltenweise ausgerichtet?
Nur die zweite Seite ist spaltenweise ausgerichtet! Die erste Seite ist zeilenweise ausgerichtet, und die dritte Seite ist ein Storyboard. In einem Dashboard mit mehreren Seiten, kannst du jeweils nach dem Titel die Seitenausrichtung bestimmen. Schreibe für spaltenweise Ausrichtung {data-orientation=columns}, für zeilenweise Ausrichtung {data-orientation=rows} und für ein Storyboard {.storyboard} jeweils nach dem Titel (aber auf derselben Zeile). Füge die entsprechende Ausrichtung nach den drei Titeln ein.
Nun beginne Seite 1 zu layoutieren. Du siehst, dass es zwei Zeilen gibt, eine mit den valueBoxes, und eine mit der Karte. Die Zeilen werden mit Titel zweiter Ordnung (mit ----) definiert. Füge zwei Zeilen, mit dem Namen Zeile 1 und Zeile 2 ein. Hier müssen keine sinnvollen Titel angegeben werden, da die Titel zweiter Ordnung nicht angezeigt werden.
Zeile X
----------------------------------------------------------------------Wenn du das Dokument so knittest erhalten die beiden Zeilen gleich viel Platz. Die Karte soll jedoch mehr Platz erhalten. Füge dazu nach dem ersten Titel in derselben Zeile den folgenden Code ein: {data-height = 400}. Damit wird die Zeilenhöhe in Pixeln angegeben; Zeile 2 füllt dann den restlichen Platz aus. Hinweis: Die Platzverteilung erfolgt erst, wenn die Komponenten gefüllt werden; wenn du das Dokument jetzt knittest, wird also Zeile 1 im Moment noch gleich hoch sein, wie Zeile 2.
Zeile 1 mit den valueBoxes, ist wiederum in drei Spalten unterteilt, eine für jede valueBox. Verwende Titel dritter Ordnung um die Spalten mit den Namen Superhosts, Allstar, und Preiswert zu erstellen. Für diese Titel werden keine besonderen Zeichen verwendet, sondern wie gewohnt ###.
In Zeile 2 (also unterhalb des nächsten Titels zweiter Ordnung) musst du nur einen Titel einfügen, ohne Titel dritter Ordnung klappt die automatische Grössenanpassung nicht. Gib “Karte” als Titel an, und füge direkt dahinter {.no-title} ein; damit wird die Präsentation des Titels auf dem Dashboard unterdrückt.
Seite 1 ist vom Layout her fertig. Zeit, Seite zwei vorzubereiten. Schaue dir Vorlage dafür nochmals kurz an.
Diesmal besteht das Layout aus zwei Spalten. Überlege dir, wie du diese definieren würdest.
Du kannst wie bei Aufgabe C6 Titel zweiter Ordnung hinzfügen. Füge die zwei Spalten, diesmal mit den Titeln Spalte 1 und Spalte 2, unter dem Titel der zweiten Seite hinzu (also nach der Zeile mit den Gleichheitszeichen).
Wie auf Seite 1, musst du auch hier noch die Spalten anpassen. Dort hattest du mit {data-height = 400} die Höhe einer Zeile festgelegt. Die Breite einer Spalte kann analog mit {data-width = XXX} festgelegt werden. Definiere, dass Spalte 2 200 Pixel breit ist; die Erste wird dann automatisch angepasst.
Nun fehlen nur noch die Titel der beiden Spalten. Verwende dazu Titel dritter Ordnung (###) und nenne die linke Spalte Entwicklung der Berliner Airbnbs seit 2009 und die rechte Spalte Hintergründe. Füge diese Titel dritter Ordnung jeweils unter dem Titel zweiter Ordnung (Spalte 1 bzw. Spalte 2), welcher die Spalten definiert, ein.
So, nun fehlt nur noch das Layout der letzten Seite. Da es sich um ein Storyboard handelt, musst du keine Spalten oder Zeilen spezifizieren. Du kannst also direkt zu den Titeln dritter Ordnung übergehen.
Um die drei Abschnitte des Storyboards zu erstellen, verwende wiederum Titel dritter Ordnung (###). Erstelle drei Abschnitte mit den Namen Gesamtrating, Sauberkeit, und Lage.
In den Abschnitten des Storyboards soll es jeweils einen Hauptteil (links), sowie rechts eine schmalere Spalte mit Kommentaren haben. Definiere die Breite der kleineren Kommentarspalte, indem du nach jedem der drei Titel, aber auf derselben Zeile, {data-commentary-width=300} einfügst.
Fast geschafft! Die Titel der Storyboardabschnitte sind noch etwas klein. Um sie zu vergrössern, musst du etwas HTML Syntax verwenden. Kopiere den untenstehenden Code und ersetze die Titel damit, und füge die Titelnamen von Aufgabe C16 in die XXX des Codes ein.
<span style="font-size: 20px;">XXX</span>Das Layout ist fertig. Nun geht es an den Inhalt. Beginne mit den valueBoxes auf Seite 1. Um die erste valueBox einzufügen, erstelle nach dem Superhost Titel einen Code Chunk.
Berechne im erstellten R chunk zuerst die Anzahl im airbnb Datensatz vorhandener Superhosts. Verwende dazu den untenstehenden Code.
# berechne die Anzahl Superhosts im airbnb Datensatz
n_superhosts <- sum(airbnb$Host_superhost)valueBox() Funktion und zwar direkt unterhalb des Codes der Aufgabe D2. Gebe dabei als erstes Argument n_superhosts ein und setze caption auf "Superhost".# Erstelle valueBox
valueBox(XXX, caption = "XXX")Funktioniert das schon so?
Ein paar Dinge fehlen noch. Zunächst stimmt die Farbe nicht. Füge in die valueBox() Funktion ein Argument color ein und setze dieses auf "#6BB7B9".
Passt es jetzt?
Bisher ist noch kein Icon vorhanden. Füge in die valueBox() Funktion ein weiteres Argument icon ein und setze dieses auf "fa-medal".
Fast geschafft; der Titel ist noch etwas zu klein. Um das zu fixen, ersetze "Superhost" im caption Argument mit "<h3 style='color: white;'>Superhost</h3>". Damit passt nun alles. Um die anderen beiden value Boxen kümmern wir uns später.
So, das war es für den Moment für diese Seite; die interaktiven Grafiken erstellen wir weiter unten. Gehe im Code zur zweiten Seite. Dort wirst du den Text erstellen.
Schaue dir den Text in der rechten Spalte des Dashboards an. Versuche ihn mit deinen bisher erworbenen RMarkdown Kenntnissen selbst nachzubauen.
Du kannst deinen Text mit dem untenstehenden Code, mit dem diese Spalte tatsächlich erstellt wurde, vergleichen. Hast du alles gleich gemacht? Wo hast du andere Lösungen gefunden?
**Airbnbs in Berlin**
Das erste Airbnb in Berlin öffnete 2009 im Stadtteil [Pankow](https://de.wikipedia.org/wiki/Berlin-Pankow)  (siehe auch [Übersichtskarte](#page-1)). Von da an war ein  rascher Anstieg zu verzeichnen. Bereits 6 Jahre später gab  es in Berlin-Pankow alleine `r round(10**2.3)` Airbnbs.  Mittlerweile ist diese Zahl auf rund `r round(10**3.2 / 100) * 100` angestiegen.
Das teuerste heute verfügbare Airbnb kostet dabei `r max(airbnb$Preis)` pro Nacht; für die meisten Leute nicht gerade ein Schnäppchen. Dabei handelt es sich um ein `r airbnb$Unterkunftsart[max(airbnb$Preis)]` im Stadtteil `r airbnb$Stadtteil[max(airbnb$Preis)]`.
Insgesamt wurden über die Jahre in Berlin `r as.integer(sum(airbnb$Host_anzahl))` Gäste in Airbnbs empfangen.
Das war es schon für diese Seite. Den Plot erstellen wir wiederum später. Gehe nun in deinem Dokument zur dritten Seite zum Titel Gesamtrating (Titel dritter Ordnung).
Erstelle unterhalb des Titels einen R chunk und füge den untenstehenden Code ein. Dieser erstellt die erste Grafik.
# Erstelle das Histogramm der Gesamtratings
# Wähle die Rating_gesamt Variable zum Plotten aus
ggplot(airbnb, aes(Rating_gesamt)) +
  # Erstelle ein Histogramm mit Balkenbreite 1
  geom_histogram(binwidth = 1) +
  # Definiere die Achsenbeschriftungen
  labs(x = "Gesamtrating",
       y = "Häufigkeit") +
  # Definiere den Range der x-Achse von 0 bis 100
  coord_cartesian(xlim = c(0, 100)) +
  # Wähle ein Design für den Plot
  theme_light() +
  # Vergrössere die Achsenbeschriftungen
  theme(
    axis.title = element_text(size = 16),
    axis.text = element_text(size = 12)
  ) INHALT LINKE SPALTE (der eben erstellte Plot)
***
INHALT RECHTE (KOMMENTAR-) SPALTE
Füge nun einen fettgedruckten Titel (mit **TITEL**) unterhalb der eben eingefügten drei Sterne ein. Wähle als Titel Mittlere Gesamtratings.
Um den gauge zu erstellen, berechne zuerst das mittlere Gesamtrating. Erstelle dazu einen neuen Code Chunk und füge den untenstehenden Code ein.
# Berechne mittleres Gesamtrating und Runde auf eine Kommastelle
gesamtrating <- airbnb %>%
    pull(Rating_gesamt) %>% mean(na.rm = TRUE) %>%  round(1)gauge erstellen. Verwende das untenstehende Template und setze das gesamtrating Objekt als erstes Argument ein.# Estelle den gauge mit dem gesamtrating Objekt
gauge(XXX,
      # Setze Minimum und Maximum Werte
      min = 0, max = 100,
      # Definiere Farbwerte mit gaugeSectors
      gaugeSectors(
        # Grün, wenn der Wert zwischen 80 und 100 liegt
        success = c(80, 100),
        # Orange, wenn der Wert zwischen 50 un 79 liegt
        warning = c(50, 79),
        # Rot, wenn der Wert zwischen 0 und 49 liegt
        danger = c(0, 49)
        ))Wenn du das Dokument jetzt knittest, siehst du, dass die Dimensionen in der Kommentarspalte noch falsch sind, weil der gauge noch zu gross ist. Um das zu beheben, kannst du fig.width=3, fig.height=1.5, fig.align="center" in den Code Chunk Optionen erstellt.
Füge nun unterhalb des Code Chunks, der den gauge definiert, den folgenden Text ein:
<p style="font-size: 20px;">Die Berliner Airbnbs scheinen allgemein in einem
sehr guten Zustand zu sein. Zumindest lassen die hohen Gesamtratings darauf
schliessen.</p>leafletNun geht es an die Karte auf Seite 1. Gehe in deinem Skript zur Syntax, welche die Zeile 2 auf der ersten Seite erstellt (die Zeile unterhalb der valueBoxen).
leaflet bietet die Möglichkeit, sehr einfach interaktive Karten zu erstellen. Erstelle einen neuen Code chunk mit dem folgenden Code unterhalb des Karte Titel:
# Definiere Datensatz
airbnb %>% 
  # Erstelle Plot
  leaflet() %>% 
  # Setze Anfangskoordinaten und Zoomwert
  setView(lng = 13.40439, lat = 52.51128, zoom = 12) %>% 
  # Zeichne Karte
  addTiles()setView anpassen. Ersetze nun addTiles() in deinem Code mit dem untenstehenden Code, um die Airbnbs einzuzeichnen:  addTiles() %>%
  # Füge Marker hinzu
  addCircleMarkers(
    lng = ~Längengrad,
    lat = ~Breitengrad,
    radius = 4,
    stroke = FALSE, fillOpacity = 0.5,
    color = "#6BB7B9"
  )plotlyEntwicklung der Berliner Airbnbs seit 2009 in der linken Spalte auf der zweiten Seite erstellt:### Entwicklung der Berliner Airbnbs seit 2009
HIER!
### Plot zum Verlauf über die Zeit
# Anzahl Stadtteile
n_stadtteile <- length(unique(airbnb$Stadtteil))
# Definiere n_stadtteile verschiedene Farben aus der viridis palette
farben <- viridis(n_stadtteile)
# Passe den Datensatz an
Verlauf <- airbnb %>%
  # Gruppiere über Stadtteile
  group_by(Stadtteil) %>%
  # Ordne Zeilen Aufsteigend nach Erstellungsdatum 
  arrange(Erstellungsdatum) %>%
  # Erstelle neue Variablen Datum und Kumulativ,
  # letztere als 10er Logarithmus der Anzahl Airbnbs
  mutate(Datum = Erstellungsdatum,
         Kumulativ = log10(1:n())) %>%
  # Gruppiere über Stadtteil, Datum, und Kumulativ Variablen
  group_by(Stadtteil, Datum, Kumulativ) %>% 
  # Berechne deskriptive Statistiken und erstelle Variable mit 
  # Text für Popup Felder
  summarise(
    m_preis = mean(Preis, na.rm = TRUE),
    superhosts = sum(Host_superhost, na.rm = TRUE),
    m_rating = mean(Rating_gesamt, na.rm = TRUE),
    hover_text = paste0("Mittlerer Preis: <b>", m_preis,
                        "</b><br>Superhosts: <b>", superhosts,
                        "</b><br>Mittleres Gesamtrating: <b>",
                        m_rating, "</b>")
  ) %>% 
  # Erstelle den Plot mit Datum auf der x- und Kumulativ auf der y-Achse
  # Separate und eingefärbte Linien pro Stadtteil
  ggplot(aes(x = Datum, y = Kumulativ, col = Stadtteil)) +
  # Zeichne Punkte ein; das text Argument wird später von ggplotly() verwendet
  geom_point(aes(text = hover_text)) +
  # Zeichne Linien
  geom_line(show.legend = FALSE) +
  # Definiere Farbwerte; Objekt farben stammt noch von der Karte auf p.1
  scale_color_manual(values = farben) +
  # Definiere y-Achsenbeschriftung; verwendet HTML wegen plotly
  ylab("log<sub>10</sub>(Kumulative Häufigkeit)") +
  # Definiere Plot design
  theme_light()
# Erstelle Plot
VerlaufDer Code von Aufgabe F2 erstellt einen statischen Plot. Dieses ggplot Objekt kann jetzt ganz einfach an ggplotly(), einer plotly Funktion weitergegeben werden, um den Plot interaktiv zu gestalten. Dazu musst du nur das Verlauf am Ende des R chunks in ggplotly(Verlauf) umwandeln. Fertig!
Bzw. fast fertig. Passe die Dimensionen des Plots (fig.width und fig.height in den R Chunk Optionen) so an, dass die Spalte möglichst ausgefüllt wird. Dazu musst du evtl. ein paar Werte ausprobieren …
valueBox musst du zuerst die Anzahl Airbnbs, welche überall Topratings haben berechnen. Verwende dazu den untenstehenden Code in einem R chunk, diesmal unterhalb des “Allstar” Titels.# Berechne die Anzahl allstars, mit ausschliesslich top ratings
allstar <- airbnb %>% 
  # Rating_gesamt ist von 0 bis 100 -> reskaliere auf 0 bis 10
  mutate(Rating_gesamt = Rating_gesamt / 10) %>% 
  # Behalte ausschliessliche Spalten mit Ratings
  select(starts_with("Rating")) %>% 
  # Berechne die Mittelwerte jeder Zeile über alle Spalten
  mutate(Ratings_m = rowMeans(.)) %>% 
  # Behalte nur die Zeilen mit Mittelwert 10 (Maximum Rating)
  filter(Ratings_m == 10) %>% 
  # Zähle die Anzahl verbliebener Zeilen
  summarise(n())Verwende den valueBox Code den du in Teil D erstellt hast als Template um die value Box der Anzahl Allstars zu erstellen. Ersetze dazu n_superhosts durch allstar und ändere das "Superhost" im caption Argument zu "Allstars".
Diese value Box sieht aber noch nicht ganz gleich aus wie im vorgegebenen Dashboard. Zum Einen ist die Farbe noch grün statt gold, zum Anderen ist das Icon noch falsch. Ändere zunächst die Farbe (das color Argument) von "#6BB7B9" zu "#f5d142".
Nun ändere den Input zum icon Argument von "fa-medal" zu "fa-gem". Dabei spezifiziert das “fa-”, dass das Icon aus der Font Awesome Sammlung stammt. “medal” und “gem” geben dann den Namen des Icons an.
Nun zur dritten value Box, die die Anzahl preiswerter Airbnbs - definiert als weniger als 100 Euro pro Nacht - angibt. Berechne dazu zunächst die Anzahl mit dem untenstehenden Code in einem R chunk unterhalb des “Preiswert” Titels.
# Berechne die Anzahl preiswerter Airbnbs
preiswert <- sum(airbnb$Preis < 100)Verwende wiederum den valueBox Code von Aufgaben im Teil D als Template um nun die value Box zu erstellen. Ersetze dazu n_superhosts durch preiswert und ersetze das "Superhost" durch "Preiswert". Ändere ausserdem das icon zu "fa-money-bill-wave" und die Farbe zu "#85a95d".
Auf Seite 3 sind noch zwei Seiten des Storyboards leer. Fülle diese mit Inhalt; du kannst dich dabei and das vorgegebene Dashboard halten (siehe Aufgaben im Abschnitt D für Hilfestellungen), oder eigene Dinge ausprobieren.
Der airbnb.csv Datensatz enthält Zahlen zu 9868 Berliner Airbnbs
| Variable | Beschreibung | 
|---|---|
| Preis | Preis pro Nacht | 
| Erstellungsdatum | Eröffnungsdatum des Airbnbs | 
| Unterkunftsart | Appartement, Loft, House, etc. | 
| Schlafplätze | Anzahl Schlafplätze | 
| Schlafzimmer | Anzahl Schlafzimmer | 
| Badezimmer | Anzahl Badezimmer | 
| Reinigungsgebühr | Reinigungsgebühr | 
| Verfügbarkeit_90Tage | |
| Viertel | In welchem Viertel befindet sich das Airbnb | 
| Stadtteil | In welchem Stadtteil befindet sich das Airbnb | 
| Breitengrad | Breitengrad | 
| Längengrad | Längengrad | 
| Host_id | Host id | 
| Host_seit | Erfahrung des Hosts | 
| Host_antwortzeit | Host Antwortzeit | 
| Host_antwortrate | Host Antwortrate | 
| Host_superhost | Superhost Ja/Nein | 
| Host_anzahl | Anzahl Gäste | 
| Rating_gesamt | Gesamtrating | 
| Rating_genauigkeit | Genauigkeitsrating | 
| Rating_sauberkeit | Sauberkeitsrating | 
| Rating_checkin | Checkinrating | 
| Rating_kommunikation | Kommunikationsrating | 
| Rating_lage | Lagerating | 
| Rating_wertigkeit | Wertigkeitsrating | 
| Küche | Küche vorhanden TRUE/FALSE | 
| Wifi | WLAN vorhanden TRUE/FALSE | 
| TV | TV vorhanden TRUE/FALSE | 
| Kaffeemaschine | Kaffeemaschine vorhanden TRUE/FALSE | 
| Geschirrspüler | Geschirrspüler vorhanden TRUE/FALSE | 
| Terrasse_Balkon | Terrasse/Balkon vorhanden TRUE/FALSE | 
| Badewanne | Badewanne vorhanden TRUE/FALSE | 
| Check_in_24h | 24h Check-In vorhanden TRUE/FALSE | 
| Paket | Installation | 
|---|---|
| tidyverse | install.packages("tidyverse") | 
| flexdashboard | install.packages("flexdashboard") | 
| plotly | install.packages("plotly") | 
| leaflet | install.packages("leaflet") | 
| viridis | install.packages("viridis") | 
| htmltools | install.packages("htmltools") | 
| patchwork | install.packages("patchwork") | 
| Funktion | Paket | Beschreibung | 
|---|---|---|
| gauge() | flexdashboard | Erstelle einen gauge. | 
| valueBox() | flexdashboard | Erstelle eine value Box | 
| ggplotly() | plotly | Konvertiere ggplot2Objekt inplotlyObjekt | 
| leaflet() | leaflet | Initiiere leafletKarte | 
| setView() | leaflet | Definiere Anfangsfenster | 
| addTiles() | leaflet | Zeige Karte | 
| addCircleMarkers() | leaflet | Füge Kreisförmige Marker auf die Karte |