Grundlegendes

Installation und Hilfe

Die folgenden Ressourcen sind zu empfehlen:

Installation

Hilfe

Wie bei allen Programmiersprachen lässt sich viel über trial-and-error probieren und lösen. Alternativ gibt es eine riesige R Community und durch eine einfache Internetsuche der Fehlermeldung lassen sich viele Lösungen finden.

R als Taschenrechner

Es ist eigentlich selbsterklärend, aber hier eine Demonstration, dass man R wie einen einfachen Taschenrechner verwenden kann.

1 + 2                #Summe 
2 - 1                #Differenz
2 * 3                #Produkt
4 / 2                #Quotient
1001 %% 11           #Modulo

sqrt(2)              #Wurzel        
2 ^ (1/2)            #Wurzel Alternativ
exp(1)               #e-Funktion
log(2)               #natuerlicher Logarithmus
sin(pi)                #Sinus
cos(pi)                #Kosinus
abs(-3)                #Betrag
sign(-3)                 #Signum
## [1] 3
## [1] 1
## [1] 6
## [1] 2
## [1] 0
## [1] 1.414214
## [1] 1.414214
## [1] 2.718282
## [1] 0.6931472
## [1] 1.224606e-16
## [1] -1
## [1] 3
## [1] -1

Variablen und Ausgabe

In R funktioniert die Zuweisung von Variablen per <- (Shortcut in RStudio ALT + -) oder =. Da das Symbol = auch in anderen R-Funktionen Verwendung findet, ist es sinnvoll die Zuweisung per <- zu bevorzugen. Die Ausgabe des Variablenwertes erfolgt per Ausführen der Variable oder per Funktion print(). Zweiteres sorgt selbst in for-Schleifen für eine Ausgabe , obwohl dort Ausgaben normalerweise unterdrückt sind.

x <- 4
x <- 2.7
x <- sqrt(36)        
x                    #gibt x aus (nicht in Skripten oder Schleifen)
## [1] 6
print(x)             #gibt x aus (auch in Skripten oder Schleifen)
## [1] 6

Vektoren

Über den Befehl c(), seq(), rep() lassen sich Vektoren erstellen. Diese können ebenfalls in Variablen gespeichert werden. Außerdem kann man mit Vektoren rechnen, wobei der Standard bei R von elementweisen Operationen ausgeht. Für eine echte Multiplikation von Vektoren muss %*% verwendet werden. Vektoren sind indiziert und per [] kann auf einzelne oder mehrere Elemente zugegriffen werden.

X <- c(1,2,6,5,9)    #Vektoren durch einzelne Elemente definieren
X
## [1] 1 2 6 5 9
Y <- rep(3,5)        #Vektor der fünfmal die drei enthält
Y
## [1] 3 3 3 3 3
Z <- seq(2,10,2)     #alle Zahlen von zwei bis zehn in 2er-Schritten
Z
## [1]  2  4  6  8 10
U <- 1:5             #entspricht seq(1,5,1)
U
## [1] 1 2 3 4 5
V <- c(X, U, 6)      #hängt die Vektoren X und U hintereinander 
                     #und 6 als weiteres Element dran
V
##  [1] 1 2 6 5 9 1 2 3 4 5 6
X+Y                      #elementweise Addition
## [1]  4  5  9  8 12
X*Z                      #elementweise Multiplikation
## [1]  2  8 36 40 90
X%*%Z                #Vektormultiplikation mit 1x1 Matrix als Ausgabe
##      [,1]
## [1,]  176
X[1]                 #Auswählen von Teilvektoren (Indizierung beginnt bei 1)
## [1] 1
X[3:5]                 # -||- 
## [1] 6 5 9
X[c(4,2,1)]          # -||- 
## [1] 5 2 1

Arbeiten mit Dataframes/Tibbles

Das Arbeiten mit Daten im Tabellenformat gehört zu den Standardaufgaben von R. Tabellen werden in R im data.frame Format gespeichert. Mit dem Package tidyverse ist das Format tibble hinzugekommen. Im Wesentlichen funktionieren tibbles und data.frames gleich, jedoch sind tibbles in der Handhabung an einzelnen Stellen einfacher und bieten z.B. die Möglichkeit ganze Vektoren o.ä. in Zellen eines tibbles zu speichern. Es ist zwar ganz nett den Unterschied der beiden Formate zu kennen, fürs Erste könnt ihr jedoch davon ausgehen, dass wir ausschließlich mit tibbles arbeiten und es reicht zu wissen, dass fast alles was wir in diesem Semester machen mit data.frames genauso gut geht.

Visualisierung von vorhandenen Daten

In R gibt es einige Datensätze wie zum Beispiel den folgenden Datensatz mpg. Dieser ist Teil des ggplot2 Package, das zusammen mit dem tidyverse Package installiert wird, und stellt ein klassisches Beispiel eines tibbles dar. Um Zugriff auf das Package zu erhalten, benutzt man den Befehl library() nach vorheriger Installation über install.packages() (nur einmalig notwendig).

#install.packages('tidyverse')
library(tidyverse)
mpg

Eine Beschreibung des Datensatzes findet sich in der Dokumentation. Diese ruft man über den Befehl ?Name auf. In diesem Fall also über ?mpg. Dieser Syntax funktioniert genauso gut für die Dokumentationen von Funktionen. Ihr könntet also über den Befehl ?seq die Dokumentation des Befehls seq() aufrufen, falls ihr z.B. vergessen habt, in welcher Reihenfolge die Argumente der Funktion angegeben werden müssen. Wir wollen nun einzelne Aspekte des mpg Datensatzes visualisieren. Dazu benutzen wir den Befehl ggplot(). Rufen wir den Befehl ggplot(data = mpg) auf, so erhalten wir das folgende Bild.

Hier hat der Befehl nichts weitergemacht als ein leeres Zeichenfeld zu initialisieren. Damit wir nun dort auch etwas (spannendes) sehen können, müssen wir per Code steuern, was genau wir geplottet haben wollen. Die Befehlsstruktur von ggplot() ist so aufgebaut, dass man geometrische Inhalte “schichtweise” zur bisherigen Grafik “addiert”. Wollen wir beispielsweise einzelne Punkte oder ein Liniendiagramm plotten, so addieren wir geom_point() bzw. geom_line() zu ggplot(data = mpg). Möchte man ein Liniendiagramm inkl. der zugehörigen Verbindungspunkte plotten, so addiert man beides. Man schichtet sozusagen die geometrischen Inhalte übereinander.

Natürlich muss man R trotzdem mitteilen, welche Variablen geplottet werden sollen. Dazu spezifiziert man das sogenannte mapping. Dies tun wir, indem wir dem jeweiligen geom_ Befehl Informationen bzgl. der gewünschten aesthetics übermitteln. Grob gesagt ist ein aesthetic eine Information darüber, welche Variablen des Datensatzes wir für welche graphische Komponente nutzen wollen. Im einfachsten Fall sagen wir bspw. über das x- und y-aesthetic, welche Variablen entlang der x- bzw. y-Achse geplottet bzw. als x- und y-Werte verwendet werden sollen. Möchte man den Hubraum displ jedes im Datensatz enthaltenen Auto gegen dessen Verbrauch hwy (auf dem highway in miles per gallon (mpg)) plotten, so sieht das in der Praxis so aus:

ggplot(data = mpg)+
  geom_point(mapping = aes(x = displ, y = hwy))

ggplot(mpg)+
  geom_line(mapping = aes(x = displ, y = hwy))

ggplot(mpg, aes(x = displ, y = hwy))+
  geom_point()+
  geom_line()

In diesem Fall ist ein Liniendiagramm nicht wirklich sinnvoll, aber zur Illustration des Syntaxes ist das Beispiel dennoch nützlich. Im letzten Befehl stellt man außerdem fest, dass man nicht immer das gleiche schreiben muss, wenn man in jeder Schicht des Bildes sowieso die gleichen aesthetics für das mapping verwenden möchte. In diesem Fall genügt es, das mapping schon im ggplot()-Aufruf zu übergeben. Ebenso stellen wir fest, dass wir nicht immer explizit angeben müssen, dass wir den Datensatz als data angeben und die aesthetics für das `mapping benutzen. Wir können also auch data = und mapping= weglassen, wenn wir uns Schreibarbeit ersparen wollen.

Nun können wir weitere Eigenschaften der Plots verändern. Wollen wir beispielsweise, dass alle Punkte rot sind, so ist dies unabhängig von Variablen im Datensatz und nicht Teil des Mappings. Wollen wir andererseits, dass jeder Punkt eine Farbe bzgl. der zugehörigen Fahrzeugklasse class zugewiesen bekommt, so ist dies Teil des mappings. In beiden Fällen nutzen wir die Eigenschaft col =, jedoch werden diese an unterschiedlichen Stellen im Code platziert.

ggplot(mpg)+
  geom_point(mapping = aes(x = displ, y = hwy), col = 'red')

ggplot(mpg)+
  geom_point(mapping = aes(x = displ, y = hwy, col = class))

Ein großes Problem mit Punktdiagrammen bzw. Scatterplots ist die Gefahr des Overplotting also des Überlagern von Punkten. Um dem entgegen zu wirken, kann man statt geom_point() auch den Befehl geom_jitter() verwenden, wodurch zufällige kleine Schwankungen in die Datenpunkte eingebaut werden, um Punkte nicht komplett zu überlagern.

ggplot(mpg)+
  geom_jitter(mapping = aes(x = displ, y = hwy, col = class ))

Wir haben in den letzten Plots die Farbe anhand einer qualitativen/kategorialen Variable bestimmt. Wir können die Farbe auch anhand von quantitativen/nominalen Variablen zuordnen. Probleme können Auftreten, wenn die zu nutzende Variable zwar einen nominalen Wert hat, aber nur wenige verschiedene Werte annimmt (und dadurch kategorial zu verstehen ist). In diesem Fall erkennt ggplot() nicht automatisch, dass es sich bei der Variable um eine kategoriale Variable handelt. Bspw. lässt sich das gut anhand der Anzahl der Zylinder cyl verdeutlichen. In diesem Fall muss man R nachhelfen und über den Befehl factor() klarstellen, dass hier keine quantitative Variable vorliegt.

# ohne factor()
ggplot(mpg)+
  geom_jitter(mapping = aes(x = displ, y = hwy, col = cyl ))

# mit factor()
ggplot(mpg)+
  geom_jitter(mapping = aes(x = displ, y = hwy, col = factor(cyl) ))

# Man kann auch Variablen mehrfach verwenden
ggplot(mpg)+
  geom_jitter(mapping = aes(x = displ, y = hwy, col = hwy))+
  scale_color_gradient(high = 'darkgreen', low = 'red')# (nicht klausurrelevant)

Visualisierungen mit berechneten Größen

Bisher haben wir zur Visualisierung immer nur Größen verwendet, die schon im Datensatz vorhanden waren. Mit dem richtigen geom können wir aber auch andere Muster im Datensatz erkennen. Bspw. zählen die Befehle geom_histogram und geom_bar, wie oft Variablen in einen bestimmten Wertebereich fallen. Ersteres verwendet man für quantitative Variablen, während man letzteres für qualitative Variablen verwendet. Wie bei geom_line und geom_point kann man weitere Variablen für aesthetics wie Farbe verwenden. Alternativ kann man über die zusätzliche Schicht facet_wrap(~Variable) den Datensatz entsprechend der Variable aufteilen und separate Plots erstellen. In den nachfolgenden zwei Plots wollen wir die Verteilung von Hubraum (quantitativ) und Anzahl von Zylindern (qualitativ) in den unterschiedlichen Fahrzeugklassen visualisieren.

ggplot(mpg) +
  geom_histogram(mapping = aes(x = displ), binwidth = 0.4)+
  facet_wrap(~class)

ggplot(mpg)+
  geom_bar(mapping = aes(x = cyl, fill = class), 
           position = 'dodge', 
           width = 0.5)

Uns fällt zunächst auf, dass die Variable count, die auf der y-Achse abgetragen ist, nicht im Datensatz zu finden ist. Diese wurde durch die geoms selbstständig berechnet. Wir stellen außerdem fest, dass wir über zusätzliche Optionen wie binwidth oder position weitere Einstellungen am Bild vornehmen können. Man kann über die Dokumentation des jeweiligen geoms herausfinden, was die jeweilige Option macht bzw. welche Werte möglich sind. Manchmal ist es aber auch hilfreich einfach mal auszuprobieren, wie sich die Bilder verändern, wenn ihr den Code verändert.

Eine letzte sinnvolle Option ist die Option stat = "identity", die dafür sorgt, dass geom_bar nicht versucht die \(y\)-Achse selber zu zählen, sondern das y-aesthetic verwendet, das dann natürlich auch angegeben werden muss. Um dies zu demonstrieren, habe ich für euch zählen lassen, wie viele Einträge es von den verschiedenen Herstellern im Datensatz gibt. Dieser Datensatz ist in der Variable Anzahlen abgespeichert und sieht folgendermaßen aus:

Anzahlen

Dies kann man nun per geom_bar und der Option stat = "identity" visualisieren.

ggplot(Anzahlen) +
  geom_bar(aes(x = manufacturer, y = Anzahl), stat = "identity") +
  coord_flip() # Nur für schönere Ausgabe

Ein nützliches Mittel zur Visualisierung der Verteilung von quantititativen Variablen sind Boxplots. Dabei entspricht die Box dem Bereich, in dem die mittleren 50 % der Werte liegen. Die Linien bzw. Whiskers entsprechen jeweils dem Bereich der äußeren 25 % der Werte und die Punkte beschreiben “Ausreißer”. Die Breite der Box spielt dabei keine Rolle und wird je nach Befehlsaufruf von R selber bestimmt. Wieder kann man mehrere Variablen verwenden und durch unterschiedliche aesthetics visualisieren.

ggplot(mpg)+
  geom_boxplot(mapping = aes(y = hwy))

ggplot(mpg)+
  geom_boxplot(mapping = aes(x = factor(cyl), y = hwy, col = class))