Sie sind auf Seite 1von 102

Zusammenfassungen Tutorials

Jakob Scarlata

WS 2023

Contents
1 Einführung in R - Zusammenfassung 2
1.1 Die R Sprache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 Datensätze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.3 Daten transformieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
1.4 Grafiken mit ggplot2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

2 W3schools’s R Tutorial - Zusammenfassung 84


2.1 Tutorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
2.2 Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

1
Anbei befinden sich Zusammenfassungen und kleine Ergänzungen zu Tutorials, wie “Einführung in R” von
Andrew Ellis und Boris Mayer(Link), so wie von der bekannten “w3schools”-Seite (Link). Diese sollen dazu
dienen einen guten und bereits detailierten Einblick in die Computer- und Statistiksprache R zu erhalten.
Weiters soll diese Zusammenfassung schlussendlich mir persönlich in der Zukunft dienen, da ich immer wieder
darauf zurückgreifen kann.

1 Einführung in R - Zusammenfassung
1.1 Die R Sprache
1.1.1 Operatoren und Funktionen
1.1.1.1 Arithmetische Operatoren In R gibt es 8 arithmetische Operatoren. Diese sind:
• + Addition
• - Subtraktion
• * Multiplikation
• / Division
• ^ od. ** Potenz
• x %% y* Matrixmultiplikation
• x %% y Modulo
• x %/% y Ganzzahlige Teilung
Die ersten fünf sind ziemlich selbst erklärend. Die anderen 3 möchte ich hier noch einmal etwas näher
erklären, bzw. ein Beispiel geben.
1. Matrixmultiplikation Diese funktioniert so, dass zwei Matrixen multipliziert werden und das dann so
ausschaut: c(5,3) %*% c(2,4) == 22
2. Modulo Eine Modulo Rechnung funktioniert so: 5 %% 2 == 1
3. Ganzzahlige Teilung: Die Ganzzahlige Teilung teilt eine Zahl, so wie der Name bereits sagt, so, dass
keine Kommastellen bleiben. Der Rest wird weggelassen. Also wie folgt: 5 %/% 2 == 2

1.1.1.2 Logische Operatoren und Funktionen In R unterscheidet man zwischen 11 logischen Oper-
atoren und Funktionen:
• < Kleiner
• <= Kleiner gleich
• > Größer
• >= Größer gleich
• == Gleich (Äquivalenz)
• != Ungleich
• !x nicht x
• x | y x ODER y
• x & y x UND y
• xor(x,y) Entweder in x oder y, aber nicht in beiden
• isTRUE(x) testet, ob x wahr ist

1.1.1.3 Numerische Funktionen In R unterscheidet man zwischen 10 numerischen Funktionen:


• abs(x) Betrag
• squrt(x) Quadratwurzel
• ceiling(x) Aufrunden (ceiling(3,475) -> 4)
• floor(x) Abrunden (floor(3.475) -> 3)
• round(x, digits = n) Runden (round(3.475, digits = 2) -> 3.48)
• log(x) Natürlicher Logarithmus

2
• log(x, base = n) Natürlicher Logarithmus mit der Basis n
• log2(x) Natürlicher Logarithmus mit der Basis 2
• log10(x) Natürlicher Logarithmus mit der Basis 10
• exp(x) Exponentialfunktion e^x
In R gehen Operatoren und Funktionen Hand in Hand. Was bedeutet, dass man das Additionszeichen
beispielsweise auch so aufrufen kann (als Funktion):
+(2,3)

1.1.1.4 R als Taschenrechner Um R als Taschenrechner zu benutzen, muss man gelegentlich die Berech-
nung eintippen und kann dann die spezifische Berechnung mit “CTRL + ENTER” berechnen lassen.
5+5
Die Ausgabe wird in der Konsole angezeigt.

1.1.1.5 Statistische Funktionen Anbei befinden sich statistische Funktionen. “na. rm = FALSE”
bedeutet hierbei, dass alle Zahlen, die keinen Wert haben (na = not available), nicht gelöscht werden (rm =
remove).
• mean(x, na.rm = FALSE) Mittelwert
• sd(x) Standardabweichung
• var(x) Varianz
• median(x) Median
• quantile(x, probs) Quantile von x. probs: Vektor mit Wahrscheinlichkeiten
• sum(x) Summe
• min(x) Minimalwert x_min
• max(x) Maximalwert x_max
• range(x) x_min und x_max
Folgende Optionen kann man zusätzlich auch noch festlegen:
• center = TRUE: zentrieren
• scale = TRUE: durch SD teilen
Beispiel:
scale(x, center = TRUE, scale = TRUE) Zentrieren und ‘Standardisieren
Gewichtetes Ziehen mit prob:
sample(x, size, replace = FALSE, prob) Ziehen mit/ohne Zurücklegen.
Wobei prob einfach nur ein Vektor mit Wahrscheinlichkeiten ist.

1.1.1.6 Weitere nützliche Funktionen Anbei sind weiter nützliche Funktionen, die man ab und zu
gebrauchen kann:
• c() Combine: kreiert einen Vektor
• seq(from, to, by) Generiert eine Sequenz
• : Colon Operator: generiert eine reguläre Sequenz (d.h. Sequenz in Einerschritten)
• rep(x, times, each) Wiederholt x.
– times: die Sequenz wird n-mal wiederholt

3
– each: jedes Element wird n-mal wiederholt
• head(x, n = 6) Zeigt die n ersten Elemente von x an
• tail(x, n = 6) Zeigt die n letzten Elemente von x an
Beispiele von den bereits oben angeführten Funktionen:
# Erstelllung eines Vektors:
c(1,2,3,4,5,6)

## [1] 1 2 3 4 5 6
# Mittelwert eines Vektors
mean(c(1,2,3,4,5,6))

## [1] 3.5
# Mittelwert eines Vektors, wobei nicht verfügbare Werte gelöscht werden
mean(c(1, NA, 3, 4, 5, 6), na.rm = TRUE)

## [1] 3.8
# Mittelwert eines Vektors, wobei nicht verfügbare Werte dabei gelassen werden.
mean(c(1, NA, 3, 4, 5, 6), na.rm = FALSE)

## [1] NA
# Standardabweichung eines Vektors
sd(c(1, 2, 3, 4, 5, 6))

## [1] 1.870829
# Summe eines Vektors
sum(c(1, 2, 3, 4, 5, 6))

## [1] 21
# Kleinster Wert eines Vektors
min(c(1, 2, 3, 4, 5, 6))

## [1] 1
# Kleinster Wert + Größter Wert
range(c(1, 2, 3, 4, 5, 6))

## [1] 1 6
# Zentrieren
scale(c(1, 2, 3, 4, 5, 6), center = TRUE, scale = FALSE)

## [,1]
## [1,] -2.5
## [2,] -1.5
## [3,] -0.5
## [4,] 0.5
## [5,] 1.5
## [6,] 2.5
## attr(,"scaled:center")
## [1] 3.5
# 1 Zufallszahl eines Vektors, die noch einmal genommen werden kann
sample(c(1, 2, 3, 4, 5, 6), size = 1, replace = TRUE)

4
## [1] 4
# 12 Zufallszahlen, die noch einmal genommen werden können
sample(c(1, 2, 3, 4, 5, 6), size = 12, replace = TRUE)

## [1] 1 1 5 3 6 6 6 6 4 1 6 2
# 12 Zufallszahlenm, die noch einmal genommen werden können, wobei die Wahrscheinlichkeiten bereits fest
sample(c(1, 2, 3, 4, 5, 6), size = 12, replace = TRUE, prob = c(4/12, 1/12, 1/12, 2/12, 2/12, 2/12 ))

## [1] 2 3 6 4 5 6 1 1 1 3 6 5
# Sequenz zwischen 1 und 6, wobei der Abstand von jeder Zahl immer 1 ist
seq(from = 1, to = 6, by = 1)

## [1] 1 2 3 4 5 6
# Sequenz von 1 bis 6 in Einer-Schritten
1:6

## [1] 1 2 3 4 5 6
# Erstellung eines Vektors mit 2 gleichen Sequenzen von 1 bis 6
rep(1:6, times = 2)

## [1] 1 2 3 4 5 6 1 2 3 4 5 6
# Erstellung eines Vektors mit einer Squenz, wobei jede Zahl 2 Mal vorkommt
rep(1:6, each = 2)

## [1] 1 1 2 2 3 3 4 4 5 5 6 6
# Erstellung eines Vektors, der zwei gleiche Squenzen beinhaltet. Bei jeder Sequenz kommt jede Zahl 2 Ma
rep(1:6, times = 2, each = 2)

## [1] 1 1 2 2 3 3 4 4 5 5 6 6 1 1 2 2 3 3 4 4 5 5 6 6

1.1.2 Variable definieren

# den Zuweisungspfeil kann man auch mit ALT + - in RRtudio generieren lassen
my_var <- 4

# Ausgabe des Wertes von 'my_var'


my_var

## [1] 4
print(my_var)

## [1] 4

1.1.2.1 Variablennamen Der Name einer Variable kann aus Buchstaben, Zahlen und den Zeichen ’_’
und/oder ‘.’ erstellt werden. Der Anfang einer Variable, muss aber stets mit einem Buchstaben starten und
es dürfen Leerschläge enthalten sein.
Die Empfehlung des Tutorials ist snake_case, was bedeutet, dass alle Wörter durch einen Underscore *_*
getrennt werden.
Andere Möglichkeiten wären:
• camelCaseVariable
• variable.with.periods

5
• variable.With_noConventions
Die Variablen werden im Global Environment gespeichert. Sollte man die R Session schließen, werden auch
die Variablen gelöscht.

1.1.3 Funktionen aufrufen


Die untenangeführte Funktion besteht aus einem Namen, in diesem Falle hier “function_name” und zwei
Argumenten, arg1 und arg2. Wobei arg2 hier einen Default Value, val2, hat.
function_name(arg1, arg2 = val2)
Argumente ohne Default Werte müssen bei jedem Aufruf einer Funktion angegeben werden. Lässt man
Argumente mit Default Werten weg, übernehmen diese Default Werte den Platz des Arguments.

1.1.3.1 Verschachtelung von Funktionen Verschachtelung von Funktionen ist in R erlaubt und auch
nicht beschränkt. Anbei sind Beispiele, die diese Aussage erläutern sollen:
# 1. definiert einen Vektor:
c(34.444, 45.853, 21.912, 29.261, 31.558)

## [1] 34.444 45.853 21.912 29.261 31.558


# 2. berechnet den Mittelwert des Vektors:
mean(c(34.444, 45.853, 21.912, 29.261, 31.558))

## [1] 32.6056
# 3. rundet auf 2 Dezimalstellen vom Mittelwert vom Vektor:
round(mean(c(34.444, 45.853, 21.912, 29.261, 31.558)),
digits = 2)

## [1] 32.61

1.1.4 Datentypen
Vektoren können in folgende Datentypen unterschieden werden:
• numeric vectors: Unterteilung erfolgt weiters in a) integer (Ganze Zahlen) und b) double (Reelle
Zahlen)
• character vectors: umgeben von ’ oder “. z.B. ‘Wort’
• logical vectors: 3 Werte möglich -> TRUE, FALSE, NA
Vektoren können nur Werte eines Datentyps zu gleich speichern.
Es gibt drei Eigenschaften von Vektoren:
• Typ: typeof()
• Länge: length()
• Attribute: attributes()
numbers0 <- c("Text", 'Wörter')
typeof(numbers0)

## [1] "character"
length(numbers0)

## [1] 2
attributes(numbers0)

## NULL

6
Vektoren können mit c() (kurz für combine), seq() oder rep() erstellt werden.

1.1.4.1 Numeric vectors Entweder integer oder double.


numbers1 <- c(1, 2.5, 4.5)
typeof(numbers1)

## [1] "double"
Man jedes Element eines Vektors direkt ansprechen (Subsetting):
numbers2 <- c(1, 2.5, 4.5)
numbers2[1] # Das erste Element

## [1] 1
numbers2[length(numbers2)] # Das letzte Element

## [1] 4.5
numbers2[-1] # Alle ELemente außer das Erste

## [1] 2.5 4.5


numbers2[1:2] # Dier ersten zwei Elemente

## [1] 1.0 2.5

1.1.4.1.1 Matrizen Eine Matrix ist in fast gleich einem Vektoren, allerdings mit einem dimensionalen
Attribut (dim)
# Vektor
x <- 1:8

# Erstellen bzw. Umwandlung in eine Matrix


dim(x) <- c(2, 4)
x

## [,1] [,2] [,3] [,4]


## [1,] 1 3 5 7
## [2,] 2 4 6 8
# Hier ist ein anderer Weg, wie man Matrizen erstellen kann:
m <- matrix(1:8, nrow = 2, ncol = 4, byrow = FALSE)
m

## [,1] [,2] [,3] [,4]


## [1,] 1 3 5 7
## [2,] 2 4 6 8
# Das Argument byrow entscheidet, ob zuerst die Zeilen voll gefüllt werden sollen oder die Spalten

m <- matrix(1:8, nrow = 2, ncol = 4, byrow = TRUE)


m

## [,1] [,2] [,3] [,4]


## [1,] 1 2 3 4
## [2,] 5 6 7 8

7
# Transponieren von Matrizen
m_transponiert <- t(m)
m_transponiert

## [,1] [,2]
## [1,] 1 5
## [2,] 2 6
## [3,] 3 7
## [4,] 4 8
Weitere Funktionen:
• cbind(): kombiniert die Spalten (column-bind) von Vektoren/Matrizen zu einem Objekt
• rbind(): kombiniert die Zeilen (row-bind) von Vektoren/Matrizen zu einem Objekt
cbind():
x1 <- 1:3
# x1 ist ein Vektor
x1

## [1] 1 2 3
x2 <- 10:12
# x2 ist ein Vektor
x2

## [1] 10 11 12
m1 <- cbind(x1, x2)
# m1 ist eine Matrix mit den Dimensionen [3, 2]
m1

## x1 x2
## [1,] 1 10
## [2,] 2 11
## [3,] 3 12
Nun hat man ein Objekt m1 mit den den Vektoren als Spalten
rbind():
m2 <- rbind(x1, x2)
# m2 ist eine Matrix mit den Dimensionen [2, 3]
m2

## [,1] [,2] [,3]


## x1 1 2 3
## x2 10 11 12
rbind erstellt nun eine Matrix mit x1 und x2 als Rows.
Auch Werte aus Matrizen kann man spezifisch ansprechen. Man gibt dabei die Zeilennummer und die
Spaltennummer in Klammern wie folgt an:
# m1[zeilennummer, spaltennummer]
m1[1,1]

## x1
## 1

8
# Zeile 1, Spalte 2
m1[1,2]

## x2
## 10
# Zeile 2 bis 3, Spalte 1
m1[2:3,1]

## [1] 2 3
# Wenn man eine Nummer leer lässt, werden alle Werte genommen
m1[,1]

## [1] 1 2 3
# Zeile 1 alle Spalten
m1[1,]

## x1 x2
## 1 10
m1[,]

## x1 x2
## [1,] 1 10
## [2,] 2 11
## [3,] 3 12
Vektorisierung
x1 <- 1:10
x1

## [1] 1 2 3 4 5 6 7 8 9 10
x1 + 2

## [1] 3 4 5 6 7 8 9 10 11 12
x2 <- 11:20
x1 + x2

## [1] 12 14 16 18 20 22 24 26 28 30
x1 * x2

## [1] 11 24 39 56 75 96 119 144 171 200


x1 <- 1:10
x1^2

## [1] 1 4 9 16 25 36 49 64 81 100
exp(x1)

## [1] 2.718282 7.389056 20.085537 54.598150 148.413159


## [6] 403.428793 1096.633158 2980.957987 8103.083928 22026.465795
Recycling
Vektor-Recycling funktioniert so: Addiert man einen kürzeren Vektor mit einem längeren, so wird der kürzere
so oft wiederholt, bis man jeden Wert addieren kann.
Ein Beispiel ist hier:

9
1:10 + 1:2

## [1] 2 4 4 6 6 8 8 10 10 12
Die genaue Berechnung schaut so aus:
1 2 3 4 5 6 7 8 9 10 1 2 1 2 1 2 1 2 1 2
Also wird 1:2, sprich der kürzere Vektor, so oft wiederholt, bis man ihn vollständig mit dem anderen addieren
kann.
Wenn man nun allerdings einen kürzeren Vektor nimmt, wo der längere kein Vielfaches ist, funktioniert bzw.
macht R das so:
1:10 + 1:3

## Warning in 1:10 + 1:3: longer object length is not a multiple of shorter object
## length
## [1] 2 4 6 5 7 9 8 10 12 11
Hier schaut die Berechnung so aus:
1 2 3 4 5 6 7 8 9 10 1 2 3 1 2 3 1 2 3 1
Missing Values
Nicht benutzbare Werte bzw. Werte die fehlen sind als NA (not available) gekennzeichnet.
zahlen <- c(12, 13, 15, 11, NA, 10)
zahlen

## [1] 12 13 15 11 NA 10
Es gibt eine Funktion, mit der man testen kann, ob ein Wert valid ist: is.na()
is.na(zahlen)

## [1] FALSE FALSE FALSE FALSE TRUE FALSE

1.1.4.2 Charater vectors Character vectors oder auch “Strings” verwendet man als Datentyp für Buch-
staben und ganze Wörter, so wie Sätze.
text <- c("text als", "ein string")
text

## [1] "text als" "ein string"


typeof(text)

## [1] "character"
length(text)

## [1] 2
Es gibt gewisse Built-in Constants, die einfach ein paar Konstante sind, die man oft gebrauchen kann. Zwei
davon sind letters und LETTERS, die das englische abc in Klein- als auch Großbuchstaben gespeichert
haben. Man kann sie wie folgt benutzen.
?letters # gibt Informationen zu der Konstante
letters[1:3]

## [1] "a" "b" "c"

10
LETTERS[24:26]

## [1] "X" "Y" "Z"


Es gibt die Funktion paste(), mit der man Strings zusammenführen kann. Sie funktioniert so:
paste(LETTERS[1:3], letters[24:26], sep = "_")

## [1] "A_x" "B_y" "C_z"


paste0(1:3, letters[1:3]) # paste0 ist für sep = "" zuständig

## [1] "1a" "2b" "3c"


zahl <- 7
# zahl ist zwar eine ganze Zahl, wird aber durch paste() zu einem character
paste(zahl, "ist eine Zahl", sep = " ")

## [1] "7 ist eine Zahl"

1.1.4.3 Logical vectors Man unterscheidet zwischen drei logischen Operatoren: TRUE, FALSE und
NA. Diese werden vor allem benutzt, wenn man Zahlen beurteilen möchte. Beispielsweise könnte es sein,
dass man alle negativen Zahlen weglassen möchte. Dafür kann man mit logischen Operatoren dann arbeiten
und diese in die logischen Vektoren einspeichern.
Ein Beispiel ist anbei:
x <- rnorm(24) # generiert pseudo-zufällige Zahlen
x

## [1] 0.50552843 2.32222185 1.39076338 -0.48431401 0.75760679 0.06712960


## [7] -1.23756105 -1.70793571 0.61167193 1.78091321 -2.04367780 1.60687627
## [13] -0.28214238 -0.55668571 -0.48274825 -0.59861769 0.20182780 0.86248932
## [19] 0.07218622 -1.11276688 1.14956179 1.21191841 -0.02228014 1.19054240
x > 0

## [1] TRUE TRUE TRUE FALSE TRUE TRUE FALSE FALSE TRUE TRUE FALSE TRUE
## [13] FALSE FALSE FALSE FALSE TRUE TRUE TRUE FALSE TRUE TRUE FALSE TRUE
# Nun kann man nur alle positven Zahlen von x ausgeben
x[x>0]

## [1] 0.50552843 2.32222185 1.39076338 0.75760679 0.06712960 0.61167193


## [7] 1.78091321 1.60687627 0.20182780 0.86248932 0.07218622 1.14956179
## [13] 1.21191841 1.19054240
x[x > (mean(x) + sd(x))]

## [1] 2.322222 1.390763 1.780913 1.606876


which(x > (mean(x) + sd(x))) # Which hilft mir herauszufinden, wo meine Aussage zutrifft

## [1] 2 3 10 12

1.1.4.4 Factors Man unterscheidet zwischen atomic vectors (numeric, logical und character) und anderen.
Ein anderer ist factor. Man kann ihn benutzen um nach gewissen Sachen zu kategorisieren.
geschlecht <- c("male", "female", "male", "male", "female")
geschlecht

## [1] "male" "female" "male" "male" "female"

11
typeof(geschlecht)

## [1] "character"
class(geschlecht)

## [1] "character"
attributes(geschlecht)

## NULL
Wenn man nun einen Faktor mit factor() definiert, kann man später auch die erstellten Attribute sehen.
geschlecht <- factor(geschlecht, levels = c("female", "male")) # definieren eines Faktors
geschlecht

## [1] male female male male female


## Levels: female male
typeof(geschlecht)

## [1] "integer"
class(geschlecht)

## [1] "factor"
attributes(geschlecht)

## $levels
## [1] "female" "male"
##
## $class
## [1] "factor"
Man kann auch die Faktorstufen wieder ändern.
levels(geschlecht)

## [1] "female" "male"


geschlecht <- relevel(geschlecht, ref = "male")
levels(geschlecht)

## [1] "male" "female"


Mit factor() kann man die Reihenfolge genau angeben:
geschlecht <- factor(geschlecht, levels = c("male", "female"))
geschlecht

## [1] male female male male female


## Levels: male female
levels(geschlecht)

## [1] "male" "female"


Mit table() kann man nun eine Häufigkeitstabelle erstellen.
table(geschlecht)

12
## geschlecht
## male female
## 3 2

1.1.4.5 Lists Der nächste Datentyp ist list. Der Unterschied zu normalen Vektoren ist, dass man in
Listen mehrere verschiedene Datentypen speichern kann.
x <- list(1:3, "a", c(TRUE, FALSE, TRUE), c(2.3, 5.9))
x

## [[1]]
## [1] 1 2 3
##
## [[2]]
## [1] "a"
##
## [[3]]
## [1] TRUE FALSE TRUE
##
## [[4]]
## [1] 2.3 5.9
Diese Liste hat nun mehrere Vektoren für jeden Datentypen. Man kann ebenfalls Listen mit Indexen
ansprechen:
x[1]

## [[1]]
## [1] 1 2 3
x[2]

## [[1]]
## [1] "a"
x[3]

## [[1]]
## [1] TRUE FALSE TRUE
x[4]

## [[1]]
## [1] 2.3 5.9
Nun kann man ebenfalls auch named lists erstellen. Man braucht dabei für jeden Vektor einen Namen und
das schaut so aus:
x <- list(int = 1:3,
string = "a",
log = c(TRUE, FALSE, TRUE),
double = c(2.3, 5.9))
x

## $int
## [1] 1 2 3
##
## $string
## [1] "a"
##

13
## $log
## [1] TRUE FALSE TRUE
##
## $double
## [1] 2.3 5.9
typeof(x)

## [1] "list"
# Zugreifen auf die Werte einer Kategorie mit dem $ (Dollar Zeichen)
x$string

## [1] "a"
x$double

## [1] 2.3 5.9

1.1.4.6 Data Frames Data Frames werden für das Speichern von Daten benutzt. Man kann sie sich
als eine Matrix vorstellen von vielen gleichlangen Vektoren. Jeder Vektor kann einen anderen Datentypen
haben. Standardmäßig werden die Data Frames in R mit der Funktion data.frame() erstellt.
Allerdings kann man die Data Frames auch mit dem tidyverse-Package erstellen. Das geht dann so:
# install.packages("dplyr") - for installation of the library
library(dplyr)

##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
df <- tibble(geschlecht = factor(c("male", "female",
"male", "male",
"female")),
alter = c(22, 45, 33, 27, 30))
df

## # A tibble: 5 x 2
## geschlecht alter
## <fct> <dbl>
## 1 male 22
## 2 female 45
## 3 male 33
## 4 male 27
## 5 female 30
Ein Data Frame hat mehrere Attribute. Darunter: names(), colnames() und rownames.
attributes(df)

## $class
## [1] "tbl_df" "tbl" "data.frame"
##

14
## $row.names
## [1] 1 2 3 4 5
##
## $names
## [1] "geschlecht" "alter"
# Anzahl der Spalten
ncol(df)

## [1] 2
# Anzahl der Zeilen
nrow(df)

## [1] 5
Data Frame Subsetting
Es gibt folgende Möglichkeiten Daten abzufragen:
• Wie eine Liste: die einzelnen Spalten können mit $ ausgewählt werden
• Wie eine Matrix: die Elemente können mit [ ausgewählt werden
df$geschlecht

## [1] male female male male female


## Levels: female male
df$alter

## [1] 22 45 33 27 30
df["geschlecht"]

## # A tibble: 5 x 1
## geschlecht
## <fct>
## 1 male
## 2 female
## 3 male
## 4 male
## 5 female
df["alter"]

## # A tibble: 5 x 1
## alter
## <dbl>
## 1 22
## 2 45
## 3 33
## 4 27
## 5 30
df[1]

## # A tibble: 5 x 1
## geschlecht
## <fct>
## 1 male
## 2 female

15
## 3 male
## 4 male
## 5 female
df[2]

## # A tibble: 5 x 1
## alter
## <dbl>
## 1 22
## 2 45
## 3 33
## 4 27
## 5 30
df[1,1]

## # A tibble: 1 x 1
## geschlecht
## <fct>
## 1 male
df[1,]

## # A tibble: 1 x 2
## geschlecht alter
## <fct> <dbl>
## 1 male 22
df[,1]

## # A tibble: 5 x 1
## geschlecht
## <fct>
## 1 male
## 2 female
## 3 male
## 4 male
## 5 female
df[,]

## # A tibble: 5 x 2
## geschlecht alter
## <fct> <dbl>
## 1 male 22
## 2 female 45
## 3 male 33
## 4 male 27
## 5 female 30
df[1:3,]

## # A tibble: 3 x 2
## geschlecht alter
## <fct> <dbl>
## 1 male 22
## 2 female 45
## 3 male 33

16
df$geschlecht[1]

## [1] male
## Levels: female male
df$alter[2:3]

## [1] 45 33

17
1.2 Datensätze
1.2.1 Datensätze selber erstellen
1.2.1.1 Ohne Messwiederholung Erstellen eines Datensatzers mit einem between-subjects Faktor:
library(dplyr)

# Kein Alkohol
kein_alkohol <- c(64, 58, 64)
kein_alkohol <- tibble(
aggressivitaet = kein_alkohol,
alkoholbedingung = "kein_alkohol"
)
kein_alkohol

## # A tibble: 3 x 2
## aggressivitaet alkoholbedingung
## <dbl> <chr>
## 1 64 kein_alkohol
## 2 58 kein_alkohol
## 3 64 kein_alkohol
#Placebo
placebo <- c(74, 79, 72)
placebo <- tibble(
aggressivitaet = placebo,
alkoholbedingung = "placebo"
)
placebo

## # A tibble: 3 x 2
## aggressivitaet alkoholbedingung
## <dbl> <chr>
## 1 74 placebo
## 2 79 placebo
## 3 72 placebo
#Anti Placebo
anti_placebo <- c(71, 69, 67)
anti_placebo <- tibble(
aggressivitaet = anti_placebo,
alkoholbedingung = "anti_placebo"
)
anti_placebo

## # A tibble: 3 x 2
## aggressivitaet alkoholbedingung
## <dbl> <chr>
## 1 71 anti_placebo
## 2 69 anti_placebo
## 3 67 anti_placebo
#Alkohol
alkohol <- c(69, 73, 74)
alkohol <- tibble(
aggressivitaet = alkohol,
alkoholbedingung = "alkohol"

18
)
alkohol

## # A tibble: 3 x 2
## aggressivitaet alkoholbedingung
## <dbl> <chr>
## 1 69 alkohol
## 2 73 alkohol
## 3 74 alkohol
# Zusammenführen
alk_aggr <- bind_rows(
kein_alkohol,
placebo,
anti_placebo,
alkohol
)

alk_aggr

## # A tibble: 12 x 2
## aggressivitaet alkoholbedingung
## <dbl> <chr>
## 1 64 kein_alkohol
## 2 58 kein_alkohol
## 3 64 kein_alkohol
## 4 74 placebo
## 5 79 placebo
## 6 72 placebo
## 7 71 anti_placebo
## 8 69 anti_placebo
## 9 67 anti_placebo
## 10 69 alkohol
## 11 73 alkohol
## 12 74 alkohol
# Faktor für alkoholbedingung festlegen:
alk_aggr$alkoholbedingung <- factor(alk_aggr$alkoholbedingung)

# Der Datensatz ist nun komplett


alk_aggr

## # A tibble: 12 x 2
## aggressivitaet alkoholbedingung
## <dbl> <fct>
## 1 64 kein_alkohol
## 2 58 kein_alkohol
## 3 64 kein_alkohol
## 4 74 placebo
## 5 79 placebo
## 6 72 placebo
## 7 71 anti_placebo
## 8 69 anti_placebo
## 9 67 anti_placebo
## 10 69 alkohol

19
## 11 73 alkohol
## 12 74 alkohol

1.2.1.2 MIt Messwiederholung Bei Messwiederholungen kann das Format im Gegensatz zu SPSS oder
jamovi “wide” statt “long” sein, wenn Stufen in separaten Spalten sind.
Vpn <- c("VP_1", "VP_2", "VP_3", "VP_4")
Vpn <- factor(Vpn)
# N ist die Anzahl Vpn
N <- length(Vpn)

zufriedenheit_t1 <- round(rnorm(N, mean = 60, sd = 10), digits = 2)


zufriedenheit_t1

## [1] 58.14 73.87 60.42 58.22


zufriedenheit_t2 <- round(rnorm(N, mean = 75, sd = 10), digits = 2)
zufriedenheit_t2

## [1] 64.77 59.67 79.98 84.39


# Zusammenfügen der Variablen zu einem Datensatz

zufriedenheit <- tibble(


Vpn = Vpn,
zufriedenheit_t1 = zufriedenheit_t1,
zufriedenheit_t2 = zufriedenheit_t2
)
zufriedenheit

## # A tibble: 4 x 3
## Vpn zufriedenheit_t1 zufriedenheit_t2
## <fct> <dbl> <dbl>
## 1 VP_1 58.1 64.8
## 2 VP_2 73.9 59.7
## 3 VP_3 60.4 80.0
## 4 VP_4 58.2 84.4
In R bevorzugen viele statistische Verfahren das “long” Format gegenüber dem “wide” Format. Die Datenkon-
vertierung, auch als Reshaping bezeichnet, ist wichtig und wird im nächsten Kapitel behandelt. Tidy Data,
also das “long” Format, erleichtert die Arbeit mit R und die Verwendung der tidyverse-Pakete.
Manuelle Konversion erfolgt wie folgt:
zufriedenheit_wide <- zufriedenheit
Vpn <- rep(zufriedenheit_wide$Vpn, each = 2)
Vpn

## [1] VP_1 VP_1 VP_2 VP_2 VP_3 VP_3 VP_4 VP_4


## Levels: VP_1 VP_2 VP_3 VP_4
Erstellen einer rating Variable und messzeitpunkt:
messzeitpunkt <- rep(c("t1", "t2"), times = N)
messzeitpunkt <- as.factor(messzeitpunkt)

messzeitpunkt

## [1] t1 t2 t1 t2 t1 t2 t1 t2

20
## Levels: t1 t2
rating <- c(rbind(
zufriedenheit_wide$zufriedenheit_t1,
zufriedenheit_wide$zufriedenheit_t2
))

# oder

rating <- as.vector(rbind(


zufriedenheit_wide$zufriedenheit_t1,
zufriedenheit_wide$zufriedenheit_t2
))

rating

## [1] 58.14 64.77 73.87 59.67 60.42 79.98 58.22 84.39


# Zusammenfügen der drei Variablen
zufriedenheit_long <- tibble(
Vpn = Vpn,
messzeitpunkt = messzeitpunkt,
rating = rating
)

zufriedenheit_long

## # A tibble: 8 x 3
## Vpn messzeitpunkt rating
## <fct> <fct> <dbl>
## 1 VP_1 t1 58.1
## 2 VP_1 t2 64.8
## 3 VP_2 t1 73.9
## 4 VP_2 t2 59.7
## 5 VP_3 t1 60.4
## 6 VP_3 t2 80.0
## 7 VP_4 t1 58.2
## 8 VP_4 t2 84.4
# Grafische Darstellung
library(ggplot2)
zufriedenheit_long |>
ggplot(aes(
x = messzeitpunkt,
y = rating,
group = Vpn, colour = Vpn
)) +
geom_point(size = 4) +
geom_line(size = 2) +
theme_bw() # macht den Hintergrund weiss

## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## i Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

21
85

80

75 Vpn
VP_1
rating

VP_2
70 VP_3
VP_4

65

60

t1 t2
messzeitpunkt
# Konvertierung von wide zu long
library(tidyr)
library(stringr)

zufriedenheit_wide

## # A tibble: 4 x 3
## Vpn zufriedenheit_t1 zufriedenheit_t2
## <fct> <dbl> <dbl>
## 1 VP_1 58.1 64.8
## 2 VP_2 73.9 59.7
## 3 VP_3 60.4 80.0
## 4 VP_4 58.2 84.4
zufriedenheit_long <- zufriedenheit_wide |>
pivot_longer(-Vpn, names_to = "messzeitpunkt", values_to = "rating")

zufriedenheit_long

## # A tibble: 8 x 3
## Vpn messzeitpunkt rating
## <fct> <chr> <dbl>
## 1 VP_1 zufriedenheit_t1 58.1
## 2 VP_1 zufriedenheit_t2 64.8
## 3 VP_2 zufriedenheit_t1 73.9
## 4 VP_2 zufriedenheit_t2 59.7
## 5 VP_3 zufriedenheit_t1 60.4
## 6 VP_3 zufriedenheit_t2 80.0

22
## 7 VP_4 zufriedenheit_t1 58.2
## 8 VP_4 zufriedenheit_t2 84.4
# Entfernen von zufriedenheit von den Faktorstufen:

zufriedenheit_long$messzeitpunkt <- zufriedenheit_long$messzeitpunkt |>


str_replace(".*_", "") |>
as.factor()

zufriedenheit_long

## # A tibble: 8 x 3
## Vpn messzeitpunkt rating
## <fct> <fct> <dbl>
## 1 VP_1 t1 58.1
## 2 VP_1 t2 64.8
## 3 VP_2 t1 73.9
## 4 VP_2 t2 59.7
## 5 VP_3 t1 60.4
## 6 VP_3 t2 80.0
## 7 VP_4 t1 58.2
## 8 VP_4 t2 84.4
Unterschied wide Datensatz und long Datensatz
# wide
zufriedenheit_wide

## # A tibble: 4 x 3
## Vpn zufriedenheit_t1 zufriedenheit_t2
## <fct> <dbl> <dbl>
## 1 VP_1 58.1 64.8
## 2 VP_2 73.9 59.7
## 3 VP_3 60.4 80.0
## 4 VP_4 58.2 84.4
# long
zufriedenheit_long

## # A tibble: 8 x 3
## Vpn messzeitpunkt rating
## <fct> <fct> <dbl>
## 1 VP_1 t1 58.1
## 2 VP_1 t2 64.8
## 3 VP_2 t1 73.9
## 4 VP_2 t2 59.7
## 5 VP_3 t1 60.4
## 6 VP_3 t2 80.0
## 7 VP_4 t1 58.2
## 8 VP_4 t2 84.4

1.2.2 Daten importieren


Es gibt in RStudio zwei Möglichkeiten, Datensätze zu importieren:
Mit Funktionsaufrufen: read_csv(), read_csv2() (für ‘;’), read_sav() und read_excel().
Mit dem GUI: Das Menu kann entweder via ‘File > Import Dataset’ oder im Environment-Bereich aufgerufen

23
werden.

# install.packages("readr")
library(readr)
data <- read_csv("daten.csv")

1.2.2.1 CSV
## Rows: 100 Columns: 9
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr (6): Organization Id, Name, Website, Country, Description, Industry
## dbl (3): Index, Founded, Number of employees
##
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.
View(data)

# Gibt mir die obersten Werte


head(data)

## # A tibble: 6 x 9
## Index `Organization Id` Name Website Country Description Founded Industry
## <dbl> <chr> <chr> <chr> <chr> <chr> <dbl> <chr>
## 1 1 FAB0d41d5b5d22c Ferrell ~ https:~ Papua ~ Horizontal~ 1990 Plastics
## 2 2 6A7EdDEA9FaDC52 Mckinney~ http:/~ Finland User-centr~ 2015 Glass /~
## 3 3 0bFED1ADAE4bcC1 Hester L~ http:/~ China Switchable~ 1971 Public ~
## 4 4 2bFC1Be8a4ce42f Holder-S~ https:~ Turkme~ De-enginee~ 2004 Automot~
## 5 5 9eE8A6a4Eb96C24 Mayer Gr~ http:/~ Maurit~ Synchroniz~ 1991 Transpo~
## 6 6 cC757116fe1C085 Henry-Th~ http:/~ Bahamas Face-to-fa~ 1992 Primary~
## # i 1 more variable: `Number of employees` <dbl>
# Gibt mir eine gute Übersicht über die Datei
summary(data)

## Index Organization Id Name Website


## Min. : 1.00 Length:100 Length:100 Length:100
## 1st Qu.: 25.75 Class :character Class :character Class :character
## Median : 50.50 Mode :character Mode :character Mode :character
## Mean : 50.50
## 3rd Qu.: 75.25
## Max. :100.00
## Country Description Founded Industry
## Length:100 Length:100 Min. :1970 Length:100
## Class :character Class :character 1st Qu.:1984 Class :character
## Mode :character Mode :character Median :1995 Mode :character
## Mean :1995
## 3rd Qu.:2010
## Max. :2021
## Number of employees
## Min. : 236
## 1st Qu.:2741
## Median :4942
## Mean :4965

24
## 3rd Qu.:7558
## Max. :9995

# install.packages("haven")
library(haven)
zufriedenheit_spss <- read_sav("beispieldaten.sav")

zufriedenheit_spss$Vpn

1.2.2.2 SPSS
## Warning: Unknown or uninitialised column: `Vpn`.
## NULL
head(zufriedenheit_spss)

## # A tibble: 6 x 98
## ID westost geschlecht alter swk1 swk2 swk3 swk4 swk5 swk6 swk7 swk8
## <dbl> <dbl+l> <dbl+lbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 0 [Wes~ 1 [weibli~ 13 2 5 6 4 7 5 5 6
## 2 2 0 [Wes~ 0 [männli~ 14 4 6 4 4 6 5 5 6
## 3 10 0 [Wes~ 1 [weibli~ 14 5 4 5 6 5 7 7 6
## 4 11 0 [Wes~ 1 [weibli~ 14 3 6 6 5 7 7 6 6
## 5 12 0 [Wes~ 1 [weibli~ 14 5 6 6 5 7 6 5 5
## 6 14 0 [Wes~ 0 [männli~ 14 3 5 5 4 5 7 5 6
## # i 86 more variables: swk9 <dbl>, swk10 <dbl>, swk11 <dbl>, swk12 <dbl>,
## # swk13 <dbl>, swk14 <dbl>, swk15 <dbl>, swk16 <dbl>, swk17 <dbl>,
## # swk18 <dbl>, swk19 <dbl>, swk20 <dbl>, swk21 <dbl>, swk22 <dbl>,
## # swk23 <dbl>, swk24 <dbl>, swk25 <dbl>, swk26 <dbl>, swk27 <dbl>,
## # swk28 <dbl>, swk29 <dbl>, swk30 <dbl>, swk31 <dbl>, swk32 <dbl>,
## # swk33 <dbl>, swk34 <dbl>, swk35 <dbl>, swk36 <dbl>, unteltern1 <dbl>,
## # unteltern2 <dbl>, unteltern3 <dbl>, unteltern4 <dbl>, unteltern5 <dbl>, ...
summary(zufriedenheit_spss)

## ID westost geschlecht alter swk1


## Min. : 1.00 Min. :0.0 Min. :0.0000 Min. :13.0 Min. :1.000
## 1st Qu.: 94.25 1st Qu.:0.0 1st Qu.:0.0000 1st Qu.:14.0 1st Qu.:4.000
## Median :191.50 Median :0.5 Median :0.0000 Median :15.0 Median :5.000
## Mean :187.76 Mean :0.5 Mean :0.4685 Mean :14.7 Mean :5.045
## 3rd Qu.:281.75 3rd Qu.:1.0 3rd Qu.:1.0000 3rd Qu.:15.0 3rd Qu.:6.000
## Max. :367.00 Max. :1.0 Max. :1.0000 Max. :17.0 Max. :7.000
##
## swk2 swk3 swk4 swk5
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:4.000 1st Qu.:5.000 1st Qu.:4.000 1st Qu.:6.000
## Median :5.000 Median :6.000 Median :5.000 Median :6.000
## Mean :5.211 Mean :5.572 Mean :5.014 Mean :6.173
## 3rd Qu.:6.000 3rd Qu.:7.000 3rd Qu.:6.000 3rd Qu.:7.000
## Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000
## NA's :1 NA's :3 NA's :1 NA's :2
## swk6 swk7 swk8 swk9
## Min. :3.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:6.000 1st Qu.:4.000 1st Qu.:5.000 1st Qu.:5.000
## Median :6.000 Median :5.000 Median :6.000 Median :6.000

25
## Mean :6.165 Mean :4.972 Mean :5.498 Mean :5.762
## 3rd Qu.:7.000 3rd Qu.:6.000 3rd Qu.:6.000 3rd Qu.:7.000
## Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000
## NA's :1 NA's :2 NA's :5
## swk10 swk11 swk12 swk13
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:5.000 1st Qu.:4.000 1st Qu.:4.000 1st Qu.:5.000
## Median :6.000 Median :5.000 Median :5.000 Median :6.000
## Mean :5.796 Mean :4.954 Mean :5.155 Mean :5.577
## 3rd Qu.:7.000 3rd Qu.:6.000 3rd Qu.:6.000 3rd Qu.:6.000
## Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000
## NA's :1 NA's :1 NA's :2 NA's :2
## swk14 swk15 swk16 swk17
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:4.000 1st Qu.:4.000 1st Qu.:5.000 1st Qu.:4.000
## Median :5.000 Median :5.000 Median :6.000 Median :6.000
## Mean :4.936 Mean :4.736 Mean :5.751 Mean :5.238
## 3rd Qu.:6.000 3rd Qu.:5.000 3rd Qu.:7.000 3rd Qu.:6.000
## Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000
## NA's :3 NA's :2 NA's :1 NA's :25
## swk18 swk19 swk20 swk21
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:5.000 1st Qu.:5.000 1st Qu.:5.000 1st Qu.:3.000
## Median :6.000 Median :5.000 Median :6.000 Median :4.000
## Mean :5.445 Mean :5.226 Mean :5.589 Mean :4.184
## 3rd Qu.:6.000 3rd Qu.:6.000 3rd Qu.:6.000 3rd Qu.:5.000
## Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000
## NA's :3 NA's :3 NA's :1 NA's :3
## swk22 swk23 swk24 swk25
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:5.000 1st Qu.:4.000 1st Qu.:4.000 1st Qu.:4.000
## Median :6.000 Median :5.000 Median :5.000 Median :5.000
## Mean :5.658 Mean :4.547 Mean :4.828 Mean :4.689
## 3rd Qu.:7.000 3rd Qu.:6.000 3rd Qu.:6.000 3rd Qu.:6.000
## Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000
## NA's :2 NA's :8 NA's :7
## swk26 swk27 swk28 swk29
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:5.000 1st Qu.:4.000 1st Qu.:5.000 1st Qu.:4.000
## Median :5.000 Median :5.000 Median :6.000 Median :5.000
## Mean :5.312 Mean :4.936 Mean :5.582 Mean :5.112
## 3rd Qu.:6.000 3rd Qu.:6.000 3rd Qu.:6.000 3rd Qu.:6.000
## Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000
## NA's :1 NA's :5 NA's :1
## swk30 swk31 swk32 swk33
## Min. :2.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:5.000 1st Qu.:4.000 1st Qu.:5.000 1st Qu.:5.000
## Median :6.000 Median :5.000 Median :6.000 Median :6.000
## Mean :5.618 Mean :4.724 Mean :5.786 Mean :5.604
## 3rd Qu.:6.000 3rd Qu.:6.000 3rd Qu.:6.000 3rd Qu.:6.000
## Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000
## NA's :3 NA's :3 NA's :5 NA's :3
## swk34 swk35 swk36 unteltern1
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000

26
## 1st Qu.:5.000 1st Qu.:6.000 1st Qu.:5.000 1st Qu.:5.000
## Median :5.000 Median :6.000 Median :6.000 Median :6.000
## Mean :5.208 Mean :6.071 Mean :5.671 Mean :5.835
## 3rd Qu.:6.000 3rd Qu.:7.000 3rd Qu.:6.000 3rd Qu.:7.000
## Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000
## NA's :3 NA's :5 NA's :3 NA's :2
## unteltern2 unteltern3 unteltern4 unteltern5 unteltern6
## Min. :1.000 Min. :1.000 Min. :1 Min. :1.000 Min. :1.000
## 1st Qu.:5.000 1st Qu.:5.000 1st Qu.:5 1st Qu.:6.000 1st Qu.:5.000
## Median :6.000 Median :6.000 Median :6 Median :6.000 Median :6.000
## Mean :5.482 Mean :5.947 Mean :6 Mean :6.021 Mean :5.944
## 3rd Qu.:6.250 3rd Qu.:7.000 3rd Qu.:7 3rd Qu.:7.000 3rd Qu.:7.000
## Max. :7.000 Max. :7.000 Max. :7 Max. :7.000 Max. :7.000
## NA's :2 NA's :1 NA's :2 NA's :2 NA's :2
## untfreunde1 untfreunde2 untfreunde3 untfreunde4 untfreunde5
## Min. :1.00 Min. :1.000 Min. :3.000 Min. :1.000 Min. :1.000
## 1st Qu.:5.00 1st Qu.:6.000 1st Qu.:6.000 1st Qu.:5.000 1st Qu.:5.000
## Median :6.00 Median :6.000 Median :6.000 Median :6.000 Median :6.000
## Mean :5.88 Mean :6.112 Mean :6.081 Mean :5.858 Mean :5.699
## 3rd Qu.:7.00 3rd Qu.:7.000 3rd Qu.:7.000 3rd Qu.:7.000 3rd Qu.:7.000
## Max. :7.00 Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000
## NA's :2 NA's :1 NA's :1 NA's :4 NA's :4
## untfreunde6 leben1 leben2 leben3
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:5.000 1st Qu.:4.000 1st Qu.:5.000 1st Qu.:4.000
## Median :6.000 Median :5.000 Median :5.000 Median :5.000
## Mean :5.933 Mean :4.761 Mean :5.189 Mean :4.811
## 3rd Qu.:7.000 3rd Qu.:6.000 3rd Qu.:6.000 3rd Qu.:6.000
## Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000
## NA's :1 NA's :2 NA's :1 NA's :1
## leben4 leben5 leben6 leben7
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:4.000 1st Qu.:5.000 1st Qu.:5.000 1st Qu.:6.000
## Median :5.000 Median :6.000 Median :6.000 Median :6.000
## Mean :4.447 Mean :5.597 Mean :5.677 Mean :6.213
## 3rd Qu.:5.000 3rd Qu.:6.000 3rd Qu.:6.000 3rd Qu.:7.000
## Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000
## NA's :2 NA's :3 NA's :1 NA's :4
## leben8 leben9 leben10 leben11 stress1
## Min. :1.000 Min. :1.00 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:5.000 1st Qu.:5.00 1st Qu.:5.000 1st Qu.:5.000 1st Qu.:1.000
## Median :6.000 Median :6.00 Median :6.000 Median :6.000 Median :1.000
## Mean :5.845 Mean :5.63 Mean :5.802 Mean :5.628 Mean :2.121
## 3rd Qu.:7.000 3rd Qu.:6.00 3rd Qu.:7.000 3rd Qu.:6.000 3rd Qu.:3.000
## Max. :7.000 Max. :7.00 Max. :7.000 Max. :7.000 Max. :7.000
## NA's :3 NA's :2 NA's :3 NA's :1 NA's :5
## stress2 stress3 stress4 stress5
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:2.000
## Median :1.000 Median :3.000 Median :3.000 Median :4.000
## Mean :2.174 Mean :3.057 Mean :3.604 Mean :3.877
## 3rd Qu.:3.000 3rd Qu.:4.000 3rd Qu.:6.000 3rd Qu.:5.000
## Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000
## NA's :4 NA's :3 NA's :3 NA's :2

27
## stress6 stress7 stress8 stress9
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:1.000
## Median :3.000 Median :3.000 Median :2.500 Median :3.000
## Mean :3.292 Mean :3.166 Mean :2.778 Mean :2.937
## 3rd Qu.:5.000 3rd Qu.:5.000 3rd Qu.:4.000 3rd Qu.:4.000
## Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000
## NA's :5 NA's :3 NA's :2 NA's :2
## stress10 stress11 stress12 Deutschnote Mathenote
## Min. :1.000 Min. :1.000 Min. :1.00 Min. :2.000 Min. :2.000
## 1st Qu.:2.000 1st Qu.:1.000 1st Qu.:1.00 1st Qu.:4.000 1st Qu.:4.000
## Median :3.000 Median :3.000 Median :3.00 Median :4.000 Median :4.000
## Mean :3.082 Mean :3.095 Mean :2.88 Mean :4.261 Mean :4.173
## 3rd Qu.:4.000 3rd Qu.:5.000 3rd Qu.:4.00 3rd Qu.:5.000 3rd Qu.:5.000
## Max. :7.000 Max. :7.000 Max. :7.00 Max. :6.000 Max. :6.000
## NA's :4 NA's :3 NA's :2 NA's :3 NA's :2
## Fremdsprachenote Gesamtnote bildung_vater bildung_mutter
## Min. :2.000 Min. :3.000 Min. :1.000 Min. :1.000
## 1st Qu.:4.000 1st Qu.:4.000 1st Qu.:2.000 1st Qu.:2.000
## Median :4.000 Median :4.500 Median :2.000 Median :2.000
## Mean :4.309 Mean :4.462 Mean :2.691 Mean :2.643
## 3rd Qu.:5.000 3rd Qu.:5.000 3rd Qu.:4.000 3rd Qu.:4.000
## Max. :6.000 Max. :6.000 Max. :4.000 Max. :4.000
## NA's :11 NA's :6 NA's :17 NA's :14
## bildung_vater_binaer bildung_mutter_binaer swk_neueslernen swk_lernregulation
## Min. :0.0000 Min. :0.0000 Min. :2.429 Min. :2.875
## 1st Qu.:0.0000 1st Qu.:0.0000 1st Qu.:4.571 1st Qu.:4.750
## Median :0.0000 Median :0.0000 Median :5.143 Median :5.250
## Mean :0.4981 Mean :0.4926 Mean :5.098 Mean :5.246
## 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:5.571 3rd Qu.:5.875
## Max. :1.0000 Max. :1.0000 Max. :7.000 Max. :7.000
## NA's :17 NA's :14
## swk_motivation swk_durchsetzung swk_sozialkomp swk_beziehung
## Min. :3.200 Min. :1.000 Min. :1.571 Min. :3.333
## 1st Qu.:5.000 1st Qu.:4.667 1st Qu.:4.857 1st Qu.:5.167
## Median :5.400 Median :5.333 Median :5.381 Median :5.667
## Mean :5.447 Mean :5.285 Mean :5.280 Mean :5.616
## 3rd Qu.:6.000 3rd Qu.:6.000 3rd Qu.:5.857 3rd Qu.:6.167
## Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000
## NA's :1
## unt_eltern unt_freunde leben_selbst leben_familie
## Min. :1.500 Min. :2.000 Min. :1.000 Min. :1.000
## 1st Qu.:5.333 1st Qu.:5.500 1st Qu.:5.000 1st Qu.:5.333
## Median :6.167 Median :6.000 Median :5.500 Median :6.000
## Mean :5.872 Mean :5.928 Mean :5.433 Mean :5.760
## 3rd Qu.:6.667 3rd Qu.:6.667 3rd Qu.:6.000 3rd Qu.:6.667
## Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000
## NA's :1 NA's :1 NA's :1 NA's :2
## leben_schule leben_freunde leben_gesamt stress_somatisch
## Min. :1.333 Min. :2.000 Min. :2.909 Min. :1.000
## 1st Qu.:4.000 1st Qu.:5.500 1st Qu.:5.000 1st Qu.:2.167
## Median :4.667 Median :6.000 Median :5.455 Median :3.000
## Mean :4.670 Mean :5.898 Mean :5.417 Mean :3.020
## 3rd Qu.:5.333 3rd Qu.:6.500 3rd Qu.:5.909 3rd Qu.:3.667

28
## Max. :7.000 Max. :7.000 Max. :6.909 Max. :7.000
## NA's :1 NA's :1 NA's :1 NA's :3
## stress_psychisch
## Min. :1.000
## 1st Qu.:2.167
## Median :2.917
## Mean :2.989
## 3rd Qu.:3.667
## Max. :6.833
## NA's :2

# install.packages("readxl")
library(readxl)

zufriedenheit_xls <- read_excel("data.xlsx",


sheet = "zufriedenheit"
)

zufriedenheit_xls$Vpn <- as.factor(zufriedenheit_xls$Vpn)


zufriedenheit_xls$messzeitpunkt <- as.factor(zufriedenheit_xls$messzeitpunkt)

1.2.2.3 Excel Files

#Einlesen von RData

save(zufriedenheit, file = "data.Rda")

# Übergabe von einer Liste von Objekten


save(zufriedenheit, zufriedenheit_spss, zufriedenheit_xls,
file = "data.Rda"
)

load(file = "data.Rda")

1.2.2.4 RData Files

29
1.3 Daten transformieren
1.3.1 Tidy data
In einem long Datensatz würde die Struktur wie folgt aussehen:

Person Zeitpunkt Wert


Person 1 t1 Wert 1
Person 1 t2 Wert 2
Person 1 t3 Wert 3
Person 2 t1 Wert 4
Person 2 t2 Wert 5
Person 2 t3 Wert 6

In einem wide Datensatz würden die Daten so angeordnet sein:

Person Wert_t1 Wert_t2 Wert_t3


Person 1 Wert 1 Wert 2 Wert 3
Person 2 Wert 4 Wert 5 Wert 6

Ein long Datensatz hat also mehr Zeilen und weniger Spalten, während ein wide Datensatz weniger Zeilen
und mehr Spalten hat. Die Wahl zwischen den beiden Formaten hängt von der Art der Analyse und den
Anforderungen des jeweiligen Projekts ab.
Hier ist die Tabelle in Markdown-Format:

Package Funktion Verwendung


tidyr pivot_longer() erhöht die Anzahl der Zeilen, verringert die Anzahl der Spalten
tidyr pivot_wider() verringert die Anzahl der Zeilen, erhöht die Anzahl der Spalten
tidyr drop_na() löscht alle Zeilen eines Datensatzes, die missing values (NA)
enthalten
dplyr rename() zum Umbenennen von Variablen
dplyr select() wählt Variablen (Spalten) aus
dplyr filter() wählt Beobachtungen (Zeilen) aus
dplyr arrange() sortiert einen Datensatz nach einer bestimmten Variablen
dplyr mutate() erstellt neue Variablen und ändert bereits vorhandene Variablen
dplyr recode() rekodiert numerische Variablen
forcats fct_recode() zum Rekodieren/Umbenennen von Faktorstufen
dplyr group_by() ermöglicht Operationen an Teilmengen der Daten
dplyr summarize() / fasst Daten zusammen
summarise()

Die Funktionen filter(), select(), summarize() und mutate() haben so genannte scoped Versionen, mit
denen die gleiche Transformation auf mehrere Variablen gleichzeitig angewendet werden kann. Von jeder
dieser Funktionen gibt es drei Varianten:
• *_all wendet die Funktion auf alle Variablen im Datensatz an (z.B. mutate_all())
• *_at wendet die Funktion auf Variablen an, die mit einem character vector oder mit der Hilfsfunktion
vars() ausgewählt wurden (z.B. mutate_at())
• *_if wendet die Funktion auf Variablen an, die mit einer Bedingungsfunktion ausgewählt wurden (z.B.
mutate_if())

30
Mit diesen Funktionen können sehr komplexe Datenmanipulationen durchgeführt werden und trotzdem bleibt
der R Code relativ übersichtlich. Neben den oben genannten enthält dplyr noch viele weitere Funktionen.
Dazu gehören z.B. Funktionen, die es ermöglichen, verschiedene Datensätze miteinander zu verbinden (zu
“mergen”).

1.3.2 Der Pipe Operator


Es kann schnell unübersichtlich werden, wenn wir eine Sequenz von Operationen auf Daten durchführen.
Dies führt oft zu verschachtelten Funktionsaufrufen.
Als Beispiel betrachten wir einen numerischen Vektor mit n = 10 Messwerten. Wir generieren diese Messwerte
zu Übungszwecken mit rnorm(), um normalverteilte Zufallszahlen zu erhalten. Unsere Zielsetzung ist es,
diese Daten zuerst zu zentrieren, dann die Standardabweichung zu berechnen und schließlich die Ergebnisse
auf zwei Nachkommastellen zu runden.
Die Code-Sequenz könnte wie folgt aussehen:
stichprobe <- rnorm(10, 24, 5)
stichprobe

## [1] 18.69043 36.21177 18.57939 17.04897 30.54510 28.63910 23.65141 18.92735


## [9] 22.39786 23.70375
# Verschachtelter Funktionsaufruf!
round(sd(scale(stichprobe,
center = TRUE,
scale = FALSE)),
digits = 2)

## [1] 6.21
Alternative:
stichprobe_z <- scale(stichprobe, center = TRUE,
scale = FALSE)

sd_stichprobe_z <- sd(stichprobe_z)


sd_stichprobe_z_gerundet <- round(sd_stichprobe_z,
digits = 2)

sd_stichprobe_z_gerundet

## [1] 6.21
Eine Möglichkeit, um Code übersichtlicher zu gestalten, besteht darin, jeden Teilschritt in einer eigenen Zeile
darzustellen, um den Code leichter verständlich zu machen. Allerdings kann diese Methode dazu führen, dass
wir unnötige Zwischenvariablen definieren müssen.
Es gibt jedoch eine elegante Methode, um Funktionen nacheinander aufzurufen, ohne sie ineinander ver-
schachtelt schreiben zu müssen. Hierbei verwenden wir den sogenannten “pipe Operator”, der wie folgt
aussieht:
|>
Das Beispiel von oben:
library(dplyr)
sd_stichprobe_z_gerundet <- stichprobe |>
scale(center = TRUE, scale = FALSE) |>
sd() |>

31
round(digits = 2)

sd_stichprobe_z_gerundet

## [1] 6.21
Syntax des Pipe Operators
Der |> Operator wird im Allgemeinen wie folgt verwendet. Angenommen, f(), g() und h() sind Funktionen,
dann gilt:
Grundlegende Verwendung
• x |> f() ist äquivalent zu f(x).
• Wenn f() ein weiteres Argument y hat, dann ist x |> f(y) äquivalent zu f(x, y).
• Chained Verwendung: x |> f() |> g() |> h() ist äquivalent zu h(g(f(x))).
Platzhalter verwenden
• Wir können das Objekt x an einer beliebigen Stelle verwenden, indem wir den Argument-Platzhalter
_ nutzen.
• Dabei muss immer der Name des Arguments angegeben werden, bei dem der Platzhalter eingesetzt
werden soll. Zum Beispiel: x |> f(y, argument = _) ist äquivalent zu f(y, x).

1.3.3 Reshaping: tidyr

library(tidyr)

1.3.3.1 pivot_longer() Wide zu Long Datensatz: pivot_longer()


Syntax:
pivot_longer(data, cols, names_to, values_to)
oder mit |>
data |> pivot_longer(cols, names_to, values_to)
# wir benutzen hier eine Variante der tibble-Funktion speziell zur Bildung
# einfacher Demonstrationsdatensätze, auf die wir aber nicht weiter eingehen
df <- tribble(
~Name, ~t1, ~t2, ~t3,
"Marshall", 4, 5, 7,
"Skye", 3, 6, 7
) |> mutate_if(is.character, as_factor)

Die Spalten t1, t2 und t3 repräsentieren Zeitpunkte in einer Messung, aber sie sollten als eine einzige
Zeitvariable “Zeit” mit der Messung “Punkte” in einem langen Datensatz dargestellt werden, wobei die
“Name”-Variable ignoriert wird.
library(tidyr)
df_long <- df |>
pivot_longer(-Name, names_to = "Zeit", values_to = "Punkte")

df_long

## # A tibble: 6 x 3
## Name Zeit Punkte
## <fct> <chr> <dbl>
## 1 Marshall t1 4

32
## 2 Marshall t2 5
## 3 Marshall t3 7
## 4 Skye t1 3
## 5 Skye t2 6
## 6 Skye t3 7
# Zeit als Faktor:

df_long$Zeit <- as_factor(df_long$Zeit)

df_long

## # A tibble: 6 x 3
## Name Zeit Punkte
## <fct> <fct> <dbl>
## 1 Marshall t1 4
## 2 Marshall t2 5
## 3 Marshall t3 7
## 4 Skye t1 3
## 5 Skye t2 6
## 6 Skye t3 7
# Explizite Schreibweise:

df |>
pivot_longer(cols = -Name,
names_to = "Zeit",
values_to = "Punkte")

## # A tibble: 6 x 3
## Name Zeit Punkte
## <fct> <chr> <dbl>
## 1 Marshall t1 4
## 2 Marshall t2 5
## 3 Marshall t3 7
## 4 Skye t1 3
## 5 Skye t2 6
## 6 Skye t3 7
Beispiel
library(haven)
Therapy <- read_sav("Therapy.sav")
Therapy$Vpnr <- as_factor(Therapy$Vpnr)
Therapy$Gruppe <- as_factor(Therapy$Gruppe)

Therapy

## # A tibble: 100 x 4
## Vpnr Gruppe Pretest Posttest
## <fct> <fct> <dbl> <dbl>
## 1 1 Kontrollgruppe 4.29 3.21
## 2 2 Kontrollgruppe 6.18 5.99
## 3 3 Kontrollgruppe 3.93 4.17
## 4 4 Kontrollgruppe 5.06 4.76
## 5 5 Kontrollgruppe 6.45 5.64
## 6 6 Kontrollgruppe 4.49 4.67

33
## 7 7 Kontrollgruppe 4.60 4.24
## 8 8 Kontrollgruppe 4.46 3.34
## 9 9 Kontrollgruppe 4.76 4.11
## 10 10 Kontrollgruppe 5.12 5.29
## # i 90 more rows
# Transformation

Therapy_long <- Therapy |>


pivot_longer(c("Pretest", "Posttest"),
names_to = "Zeit",
values_to = "Punkte")

# Zeit sollte ein Faktor sein


Therapy_long$Zeit <- factor(Therapy_long$Zeit,
levels = c("Pretest", "Posttest"))

Therapy_long

## # A tibble: 200 x 4
## Vpnr Gruppe Zeit Punkte
## <fct> <fct> <fct> <dbl>
## 1 1 Kontrollgruppe Pretest 4.29
## 2 1 Kontrollgruppe Posttest 3.21
## 3 2 Kontrollgruppe Pretest 6.18
## 4 2 Kontrollgruppe Posttest 5.99
## 5 3 Kontrollgruppe Pretest 3.93
## 6 3 Kontrollgruppe Posttest 4.17
## 7 4 Kontrollgruppe Pretest 5.06
## 8 4 Kontrollgruppe Posttest 4.76
## 9 5 Kontrollgruppe Pretest 6.45
## 10 5 Kontrollgruppe Posttest 5.64
## # i 190 more rows

1.3.3.2 pivot_wider() Dies hier ist nun das Gegenteil zu der Funktion vorher.
Die Syntax sieht wie folgt aus:
pivot_wider(data, names_from, values_from)
oder
data |> pivot_wider(names_from, values_from)
df_long

## # A tibble: 6 x 3
## Name Zeit Punkte
## <fct> <fct> <dbl>
## 1 Marshall t1 4
## 2 Marshall t2 5
## 3 Marshall t3 7
## 4 Skye t1 3
## 5 Skye t2 6
## 6 Skye t3 7
df_wide <- df_long |>
pivot_wider(names_from = Zeit, values_from = Punkte)

34
df_wide

## # A tibble: 2 x 4
## Name t1 t2 t3
## <fct> <dbl> <dbl> <dbl>
## 1 Marshall 4 5 7
## 2 Skye 3 6 7
# Jetzt sieht df_wide genauso wie der ursprüngliche Datensatz aus. Lasst uns das auch noch überprüfen, o

all.equal(df, df_wide)

## [1] TRUE
Beispiel
Therapy_long

## # A tibble: 200 x 4
## Vpnr Gruppe Zeit Punkte
## <fct> <fct> <fct> <dbl>
## 1 1 Kontrollgruppe Pretest 4.29
## 2 1 Kontrollgruppe Posttest 3.21
## 3 2 Kontrollgruppe Pretest 6.18
## 4 2 Kontrollgruppe Posttest 5.99
## 5 3 Kontrollgruppe Pretest 3.93
## 6 3 Kontrollgruppe Posttest 4.17
## 7 4 Kontrollgruppe Pretest 5.06
## 8 4 Kontrollgruppe Posttest 4.76
## 9 5 Kontrollgruppe Pretest 6.45
## 10 5 Kontrollgruppe Posttest 5.64
## # i 190 more rows
Therapy_wide <- Therapy_long |>
pivot_wider(names_from = Zeit, values_from = Punkte)

Therapy_wide

## # A tibble: 100 x 4
## Vpnr Gruppe Pretest Posttest
## <fct> <fct> <dbl> <dbl>
## 1 1 Kontrollgruppe 4.29 3.21
## 2 2 Kontrollgruppe 6.18 5.99
## 3 3 Kontrollgruppe 3.93 4.17
## 4 4 Kontrollgruppe 5.06 4.76
## 5 5 Kontrollgruppe 6.45 5.64
## 6 6 Kontrollgruppe 4.49 4.67
## 7 7 Kontrollgruppe 4.60 4.24
## 8 8 Kontrollgruppe 4.46 3.34
## 9 9 Kontrollgruppe 4.76 4.11
## 10 10 Kontrollgruppe 5.12 5.29
## # i 90 more rows

1.3.3.3 Fehlende Werte ausschließen: drop_na() Mit dieser Funktion kann man alle Werte we-
glassen, die nicht benutzbar sind.

35
df_1 <- tibble(var1 = c(1, 2, NA), var2 = c("a", NA, "b"))
df_1

## # A tibble: 3 x 2
## var1 var2
## <dbl> <chr>
## 1 1 a
## 2 2 <NA>
## 3 NA b
df_2 <- df_1 |>
drop_na()
df_2

## # A tibble: 1 x 2
## var1 var2
## <dbl> <chr>
## 1 1 a

1.3.4 Daten manipulieren: dplyr


1.3.4.1 Variablen umbennen mit rename() Syntax:
df |> rename(neuer_name = alter_name)

1.3.4.2 Variablen auswählen mit select() Syntax:


select(df, variable1, variable2, -variable3)
oder
df |> select(variable1, variable2, -variable3)

1.3.4.3 Beobachtungen (Fälle auswählen mit filter()) df |> filter(variable1 < WERT1 & variable2
== WERT2)

1.3.4.4 Beobachtungen (Fälle) sortieren mit arrange() Aufsteigend: Therapy_long |> ar-
range(Vpnr)
Absteigend: Therapy_long |> arrange(desc(Vpnr))

1.3.4.5 Neue Variablen erstellen mit mutate() Man kann aus bereits bestehenden Variablen neue
bilden.
Syntax: df |> mutate(neue_variable_1 = FORMEL_1, neue_variable_2 = FORMEL_2)

1.3.4.6 Werte und Faktorstufen rekordieren mit recode() und fct_recode() Numerische Vari-
ablen kann man in R mit mutate() und recode() rekodieren:
Syntax:
recode(variable, alter_wert_1 = “neuer_wert_1”, alter_wert_2 = “neuer_wert_2”)
Syntax:
fct_recode(variable, neuer_wert_1 = “alter_wert_1”, neuer_wert_2 = “alter_wert_2”)

36
1.3.4.7 Daten gruppieren mit group_by() group_by() in R teilt einen Datensatz in Gruppen auf,
basierend auf einer Gruppierungsvariable. Dies ermöglicht die Anwendung von Funktionen auf spezifische
Gruppen innerhalb des Datensatzes und wird häufig in Kombination mit anderen Funktionen verwendet.
Syntax:
df <- group_by(gruppierung_1, gruppierung_2, gruppierung_3)

1.3.4.8 Variablen zusammenfassen mit summarize() Mit summarize() oder summarise() in R


können wir Variablen zusammenfassen und deskriptive Statistiken berechnen. Im Unterschied zu mutate()
gibt summarize() keinen Wert für jede einzelne Beobachtung aus, sondern einen Wert pro Gruppe. Häufig
wird summarize() in Kombination mit group_by() verwendet, um Gruppenbasierte Zusammenfassungen
durchzuführen.
Syntax:
df |> summarize(kennzahl = FUNKTION(variable))

37
1.4 Grafiken mit ggplot2
• Grafiken sind in der Datenanalyse äußerst wichtig:
– Erkunden von Daten
– Darstellung von Ergebnissen
• In R gibt es verschiedene Methoden zur Grafikerstellung.
– ggplot2 basiert auf einer intuitiven “Grammar of graphics”.
– Vorteile von ggplot2:
∗ Elegant und konsistent
∗ Arbeitet mit “tidy data” im long Format
• Schritte zur Erstellung von Grafiken mit ggplot2:
1. Daten vorbereiten:
– Beginne mit einem Datensatz.
2. Plot-Objekt erstellen:
– Verwende ggplot().
3. Ästhetische Zuordnungen definieren:
– Benutze aes() für X- und Y-Achsen sowie Gruppierung.
4. “Layers” hinzufügen:
– Definiere, wie die Daten dargestellt werden sollen, z.B. mit geom_line() oder geom_histogram().
5. Elemente zusammenfügen:
– Verwende den +-Operator, um die Teile des Plot-Objekts zusammenzuführen.
• ggplot2 ermöglicht die Erstellung komplexer Grafiken auf elegante Weise.
library(tidyverse)

## -- Attaching core tidyverse packages ------------------------ tidyverse 2.0.0 --


## v forcats 1.0.0 v purrr 1.0.2
## v lubridate 1.9.3 v tibble 3.2.1
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
## i Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(haven)
jugendliche <- read_sav("beispieldaten.sav") |>
# Faktoren konvertieren und SPSS-Labels zuweisen
mutate(ID = as_factor(ID)) |>
mutate_at(
vars(
geschlecht, westost, bildung_vater, bildung_mutter,
bildung_vater_binaer, bildung_mutter_binaer
),
as_factor,
levels = "default"
) |>
# Labels der Bildungsfaktoren vereinfachen
mutate_at(vars(bildung_vater, bildung_mutter), fct_recode,
"Hauptschule" = "Hauptschulabschluss oder niedriger",
"Realschule" = "Realschulabschluss (mittlere Reife)",
"Abitur" = "Fachabitur, Abitur",
"Hochschule" = "Fachhochschulabschluss, Universitätsabschluss"
)

38
# Nun können wir einen Datensatz erstellen mit entsprechenden Variablen
stress <- jugendliche |>
select(ID, geschlecht, stress_psychisch) |>
drop_na()
stress

## # A tibble: 284 x 3
## ID geschlecht stress_psychisch
## <fct> <fct> <dbl>
## 1 1 weiblich 1.67
## 2 2 männlich 3.5
## 3 10 weiblich 3.67
## 4 11 weiblich 1.5
## 5 12 weiblich 2.5
## 6 14 männlich 1
## 7 15 männlich 2.5
## 8 16 weiblich 3.5
## 9 17 männlich 1.67
## 10 18 männlich 2.5
## # i 274 more rows
In unserem Datensatz untersuchen wir die Beziehung zwischen einer numerischen Variable namens
“stress_psychisch” und einer Gruppierungsvariable namens “geschlecht”. Wir können diese Beziehung auf
verschiedene Weisen grafisch darstellen:
1. Punkte (Streudiagramm):
• Verwenden Sie geom_point() für ein einfaches Streudiagramm.
2. Boxplot:
• Verwenden Sie geom_boxplot() für die Darstellung eines Boxplots.
3. Violin-Plot:
• Verwenden Sie geom_violin() für die Darstellung eines Violin-Plots.
4. Punkte mit leichtem Versatz (Jitter):
• Verwenden Sie geom_jitter() für ein Punktdiagramm, bei dem die Punkte leicht versetzt sind
(“jittering”).
Diese verschiedenen Geometrien (geoms) in ggplot2 ermöglichen es uns, den Zusammenhang zwischen den
Variablen “stress_psychisch” und “geschlecht” auf unterschiedliche Weisen grafisch zu visualisieren.
library(ggplot2)

# oder

library(tidyverse)

1.4.1 Schritt 1: Plot-Objekt erstellen

# 1. Variante
p <- ggplot(data = stress)

# 2. Variante
p <- stress |>
ggplot()

39
1.4.2 Schritt 2: Aesthetic mappings
Jetzt definieren wir mit dem zweiten Argument, mapping, die “aesthetic mappings” mithilfe der Funktion
aes(). Diese bestimmen, wie die Variablen verwendet werden, um die Daten grafisch darzustellen.
In diesem Fall möchten wir die Gruppierungsvariable “geschlecht” auf der X-Achse darstellen und die Vari-
able “stress_psychisch” auf der Y-Achse. Zusätzlich können wir aes() weitere Argumente hinzufügen, wie
z.B. fill, color, shape, linetype und group. Diese dienen dazu, den verschiedenen Kategorien der Grup-
pierungsvariable unterschiedliche Farben, Formen, Linientypen usw. zuzuweisen.
In unserem Beispiel verwenden wir die Gruppierungsvariable “geschlecht”, und wir möchten, dass die beiden
Geschlechterkategorien verschiedene Farben haben und diese Farben sollen die Darstellung der Daten auf
der Grafik beeinflussen.
p <- stress |>
ggplot(mapping = aes(
x = geschlecht,
y = stress_psychisch,
color = geschlecht,
fill = geschlecht
))

6
stress_psychisch

männlich weiblich
geschlecht

1.4.3 Schritt 3: geoms hinzufügen


‘Wir “addieren” zu dem Plot-Objekt p ein geom: p + geom_’

40
# die Funktion geom_point() hat ein size Argument
p + geom_point(size = 3)

stress_psychisch

ges
4

männlich weiblich
1.4.3.1 Punktdiagramm geschlecht
p + geom_jitter()

41
6
stress_psychisch

geschlecht
4 männlich
weiblich

männlich weiblich
geschlecht
p + geom_jitter(width = 0.2)

42
6
stress_psychisch

geschlecht
4 männlich
weiblich

männlich weiblich
geschlecht
p + geom_jitter(width = 0.2, size = 4, alpha = 0.6)

43
6
stress_psychisch

geschlecht
4 männlich
weiblich

männlich weiblich
geschlecht

p + geom_boxplot()

44
6

stress_psychisch
4

männlich weiblich
1.4.3.2 Verteilung grafisch darstellen geschlecht
Ein Boxplot zeigt statistische Werte wie folgt:
• Der Median wird durch eine Linie dargestellt.
• Das Rechteck repräsentiert die mittleren 50% der Daten.
• Die “Whiskers” zeigen 1,5-fache Interquartilsbereiche.
• Ausreißer werden oft mit Punkten gekennzeichnet.
Es ist oft besser, das fill-Attribut wegzulassen, um den Median klarer zu erkennen.
p <- stress |>
ggplot(mapping = aes(
x = geschlecht,
y = stress_psychisch,
color = geschlecht
))

p + geom_boxplot()

45
6
stress_psychisch

geschlecht
4 männlich
weiblich

männlich weiblich
geschlecht
Ein Violin-Plot ähnelt einem Boxplot, zeigt jedoch nicht Quantile, sondern eine “kernel density estimate”.
Ein Violin-Plot sieht am besten aus, wenn wir das fill-Attribut verwenden.
p <- stress |>
ggplot(mapping = aes(
x = geschlecht,
y = stress_psychisch,
fill = geschlecht
))
p + geom_violin()

46
6
stress_psychisch

geschlecht
4 männlich
weiblich

männlich weiblich
geschlecht
Wenn ein Mapping nicht für alle “Layers” gelten soll, kann es individuell für jede “Layer” anstatt in der
ggplot()-Funktion definiert werden.
p <- stress |>
ggplot(mapping = aes(
x = geschlecht,
y = stress_psychisch
))

p + geom_boxplot(aes(color = geschlecht))

47
6
stress_psychisch

geschlecht
4 männlich
weiblich

männlich weiblich
geschlecht
p + geom_violin(aes(fill = geschlecht))

48
6
stress_psychisch

geschlecht
4 männlich
weiblich

männlich weiblich
geschlecht

p +
geom_violin(aes(fill = geschlecht)) +
geom_jitter(width = 0.2, alpha = 0.6)

49
6

stress_psychisch
4

männlich weiblich
1.4.3.3 Mehrere Layers kombinieren geschlecht
In den bisherigen Beispielen haben wir kein eigenes Plot-Objekt erstellt, sondern den Datensatz mit dem
Pipe-Operator (%>%) an die ggplot()-Funktion weitergegeben und dann mit + direkt die geometrischen
Darstellungen (geoms) hinzugefügt. Zudem haben wir weitere Funktionen wie theme_classic() verwendet,
um den Hintergrund weiß darzustellen.
stress |>
ggplot(mapping = aes(
x = geschlecht,
y = stress_psychisch,
fill = geschlecht
)) +
geom_violin() +
geom_jitter(width = 0.2, alpha = 0.6) +
theme_classic()

50
6
stress_psychisch

geschlecht
4 männlich
weiblich

männlich weiblich
geschlecht

1.4.4 Geoms für verschiedene Datentypen


Zusammengefasst haben wir bisher gelernt, dass die Erstellung eines Plots in ggplot2 in mehreren Schritten
erfolgt. Wir starten mit einem Dataframe und erstellen ein ggplot2-Objekt mit der ggplot()-Funktion.
Mit der aes()-Funktion weisen wir Variablen des Dataframes den Achsen (X oder Y) zu und definieren
weitere “aesthetic mappings”, wie z.B. die farbliche Codierung basierend auf einer Gruppierungsvariable.
Anschließend fügen wir dem Plot-Objekt Grafikelemente mit den geom_*-Funktionen als “Layers” hinzu.
Wir haben auch gelernt, dass es verschiedene geom_*-Funktionen gibt, die für unterschiedliche Kombinationen
von Variablen verwendet werden können. Diese Variablen können auf der X-Achse oder auf beiden Achsen
(X und Y) dargestellt werden und sie können sowohl kontinuierlich als auch kategorial sein.
kinderwunsch <- read_sav("Kinderwunsch_Schweiz.sav")

kinderwunsch <- kinderwunsch |>


mutate(geschl = as_factor(geschl, levels = "default"))

1.4.4.1 Eine Variable Um nur eine Variable auf der X-Achse darzustellen, müssen wir dennoch Werte
auf der Y-Achse anzeigen, oft in Form einer deskriptiven Zusammenfassung wie z.B. Häufigkeiten.
Für kategoriale Variablen verwenden wir oft einen Balkendiagramm (bar chart oder bar graph). Dieser
stellt die Häufigkeiten der verschiedenen Kategorien in Form von Rechtecken dar. Die Funktion dafür lautet
geom_bar().
Ein Beispiel wäre die Darstellung der Häufigkeiten von vier Bildungsstufen des Vaters.
p <- jugendliche |>
select(bildung_vater) |>
drop_na() |>

51
ggplot(aes(x = bildung_vater))
p + geom_bar(fill = "lightblue", color = "black")

75
count

50

25

Hauptschule Realschule Abitur Hochschule


bildung_vater
colors() |> sample(15)

## [1] "burlywood" "gray92" "tomato4" "navajowhite"


## [5] "gray57" "navajowhite2" "lightyellow2" "mediumpurple3"
## [9] "grey9" "grey" "indianred" "gray3"
## [13] "gray72" "orchid" "grey95"
p <- jugendliche |>
select(bildung_vater, westost) |>
drop_na() |>
ggplot(aes(x = bildung_vater, fill = westost))
p + geom_bar()

52
75

westost
count

50
West
Ost

25

Hauptschule Realschule Abitur Hochschule


bildung_vater
Standardmäßig erstellt ggplot2 ein gestapeltes Balkendiagramm, bei dem die Rechtecke aufeinander gestapelt
werden. Wenn dies nicht gewünscht ist, können wir das Argument position = "dodge" in der Funktion
geom_bar() verwenden. Damit wird angegeben, dass die Balken nebeneinander gezeichnet werden sollen.
p + geom_bar(position = "dodge")

53
60

40

westost
count

West
Ost

20

Hauptschule Realschule Abitur Hochschule


bildung_vater
Als dritte Option können wir position = "identity" verwenden, um die Balken übereinander zu zeichnen.
Um den hinteren Balken sichtbar zu machen, können wir das alpha-Argument verwenden, um die Balken
transparent zu gestalten.
p + geom_bar(position = "identity", alpha = 0.6)

54
60

40

westost
count

West
Ost

20

Hauptschule Realschule Abitur Hochschule


bildung_vater
Für kontinuierliche Variablen bietet sich die Verwendung eines Histogramms an, das mit geom_histogram()
erstellt wird. Ein Histogramm visualisiert die Verteilung einer numerischen Variable, indem die Werte in
diskrete Intervalle (bins) aufgeteilt werden. Auf der Y-Achse werden die Häufigkeiten in den jeweiligen
Intervallen ähnlich wie bei einem Balkendiagramm dargestellt. Die Festlegung der Intervallgröße (binwidth)
ist entscheidend. Wenn nichts angegeben wird, wählt ggplot2 automatisch eine binwidth aus, aber wir können
sie auch selbst mit dem Argument binwidth festlegen.
p <- jugendliche |>
select(stress_psychisch) |>
drop_na() |>
ggplot(mapping = aes(x = stress_psychisch))

# Wir lassen die binwidth automatisch auswählen


p + geom_histogram()

## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

55
30

20
count

10

2 4 6
stress_psychisch
p + geom_histogram(binwidth = 0.5)

56
40
count

20

2 4 6
stress_psychisch
Die Festlegung der binwidth sollte angemessen zur Skala der Variablen sein, weder zu fein noch zu grob.
Um relative Häufigkeiten anstelle absoluter auf der Y-Achse darzustellen, verwenden wir das Argument y =
after_stat(density) in der aes()-Funktion.
p <- jugendliche |>
select(stress_psychisch) |>
drop_na() |>
ggplot(mapping = aes(x = stress_psychisch, y = after_stat(density)))

p + geom_histogram(binwidth = 0.5)

57
0.4

0.3
density

0.2

0.1

0.0

2 4 6
stress_psychisch
p <- jugendliche |>
select(stress_psychisch, geschlecht) |>
drop_na() |>
ggplot(mapping = aes(x = stress_psychisch, fill = geschlecht))

p + geom_histogram(binwidth = 0.5)

58
40

geschlecht
count

männlich
weiblich

20

2 4 6
stress_psychisch
p <- jugendliche |>
select(stress_psychisch, geschlecht) |>
drop_na() |>
ggplot(mapping = aes(x = stress_psychisch, fill = geschlecht))

p + geom_histogram(
binwidth = 0.5,
position = "identity",
alpha = 0.6
)

59
30

20

geschlecht
count

männlich
weiblich

10

2 4 6
stress_psychisch
#Nebeneinander
p <- jugendliche |>
select(stress_psychisch, geschlecht) |>
drop_na() |>
ggplot(mapping = aes(x = stress_psychisch, fill = geschlecht))

p + geom_histogram(
binwidth = 0.5,
position = "dodge"
)

60
30

20

geschlecht
count

männlich
weiblich

10

2 4 6
stress_psychisch

1.4.4.2 Zwei Variablen Wenn beide Variablen kontinuierlich sind, können wir ihren Zusammenhang
mit einem Scatterplot oder einem Liniendiagramm darstellen. Hierfür verwenden wir die Funktionen
geom_point() für Scatterplots und geom_line() für Liniendiagramme.
Ein Beispiel wäre die Visualisierung des Zusammenhangs zwischen psychischem Stress und Lebenszufrieden-
heit.
p <- jugendliche |>
select(stress_psychisch, leben_gesamt) |>
drop_na() |>
ggplot(mapping = aes(x = stress_psychisch, y = leben_gesamt))

p + geom_point(size = 2, alpha = 0.6)

61
7

6
leben_gesamt

2 4 6
stress_psychisch
Wir haben bereits die size- und alpha-Argumente kennengelernt, sowie die Verwendung von geom_jitter()
zur Vermeidung von “overplotting”. Sowohl geom_jitter() als auch geom_point() verfügen auch über ein
colour oder color-Argument.
p + geom_jitter(colour = "purple")

62
7

6
leben_gesamt

2 4 6
stress_psychisch
Die Gruppierung anhand einer kategorialen Variablen funktioniert auch hier. Wir können sowohl die Farbe
als auch die Form der Punkte verwenden, um die Kategorien besser voneinander zu unterscheiden.
p <- jugendliche |>
select(stress_psychisch, leben_gesamt, geschlecht) |>
drop_na() |>
ggplot(mapping = aes(
x = stress_psychisch,
y = leben_gesamt,
color = geschlecht,
shape = geschlecht
))

p + geom_jitter(size = 3, alpha = 0.9)

63
7

6
leben_gesamt

geschlecht
5
männlich
weiblich

2 4 6
stress_psychisch
Mit geom_line() erstellen wir Liniendiagramme. Als Beispiel berechnen wir im neuen Dataframe den
Durchschnitt der Schulnoten für verschiedene Bildungsniveaus des Vaters und stellen sie grafisch dar. Vor
dem Plotten konvertieren wir den Faktor “bildung_vater” in eine numerische Variable.
bildung_vater <- jugendliche |>
select(Gesamtnote, bildung_vater) |>
drop_na() |>
group_by(bildung_vater) |>
summarise(Gesamtnote = mean(Gesamtnote)) |>
mutate(bildung_vater_num = as.numeric(bildung_vater))

bildung_vater

## # A tibble: 4 x 3
## bildung_vater Gesamtnote bildung_vater_num
## <fct> <dbl> <dbl>
## 1 Hauptschule 4.05 1
## 2 Realschule 4.38 2
## 3 Abitur 4.50 3
## 4 Hochschule 4.69 4
p <- bildung_vater |>
ggplot(aes(
x = bildung_vater_num,
y = Gesamtnote
))

p + geom_line()

64
4.6
Gesamtnote

4.4

4.2

1 2 3 4
bildung_vater_num
Wir können das Liniendiagramm, wie im “Honeymoon oder Hangover”-Beispiel, durch Hinzufügen von Punk-
ten ergänzen:
p + geom_line() +
geom_point(size = 4)

65
4.6
Gesamtnote

4.4

4.2

1 2 3 4
bildung_vater_num
Auch geom_line() verfügt über Argumente zur Anpassung der Darstellung. Hier verwenden wir das Argu-
ment linetype, das Werte wie “blank”, “solid”, “dashed”, “dotted”, “dotdash”, “longdash” oder “twodash”
annehmen kann.
p + geom_line(linetype = "dashed", linewidth = 2) +
geom_point(size = 8)

66
4.6
Gesamtnote

4.4

4.2

1 2 3 4
bildung_vater_num
Wenn eine der Variablen kategorial ist, können wir diese auf einer Achse darstellen, anstatt sie als
Gruppierungsvariable zu verwenden. Wir haben bereits Beispiele gesehen, in denen wir die Funktionen
geom_boxplot() und geom_violin() für solche Darstellungen verwendet haben. Wir können auch
geom_bar() für zwei Variablen verwenden, wobei die Y-Achse die Summe der Beobachtungen in den
Kategorien auf der X-Achse darstellt. In diesem Fall verwenden wir das Argument stat = 'identity', da
keine statistische Transformation erforderlich ist.
Ein Beispiel wäre der Kinderwunsch-Datensatz, in dem die absolute Häufigkeit einer “Ja”-Antwort auf der
Y-Achse dargestellt wird.
p <- kinderwunsch |>
ggplot(aes(
x = geschl,
y = kind_d,
fill = geschl
))

p + geom_bar(stat = "identity")

67
40

30

geschl
kind_d

maennlich
20
weiblich

10

maennlich weiblich
geschl
Um die Grafik besser zu verstehen, berechnen wir auch die relativen Häufigkeiten von “Ja”-Antworten pro
Geschlecht.
kinderwunsch |>
group_by(geschl) |>
summarise(
N = length(kind_d),
Ja = sum(kind_d),
prop_Ja = sum(kind_d) / N
)

## # A tibble: 2 x 4
## geschl N Ja prop_Ja
## <fct> <int> <dbl> <dbl>
## 1 maennlich 44 30 0.682
## 2 weiblich 56 44 0.786
Wenn sowohl die X- als auch die Y-Achse kategorial sind, können wir die gemeinsamen Häufigkeiten grafisch
mit der Funktion geom_count() darstellen. Als Beispiel betrachten wir die gemeinsame Häufigkeitsverteilung
der Bildung des Vaters und der Bildung der Mutter.
p <- jugendliche |>
select(starts_with("bildung")) |>
drop_na() |>
ggplot(aes(
x = bildung_vater,
y = bildung_mutter
))

68
p + geom_count()

Hochschule

Abitur
bildung_mutter

n
20
40
60
Realschule

Hauptschule

Hauptschule Realschule Abitur Hochschule


bildung_vater
geom_count() zählt die gemeinsamen Häufigkeiten der Kategorien der beiden Variablen und stellt sie als
Durchmesser der Punkte dar.
bildung <- jugendliche |>
# Variablen auswählen
select(Gesamtnote, bildung_vater, bildung_mutter) |>
# Fehlende Werte ausschliessen
drop_na() |>
# wide zu long
pivot_longer(-Gesamtnote, names_to = "eltern", values_to = "bildung") |>
# Präfix bildung_ bei eltern-Variable entfernen
mutate(eltern = str_replace(eltern, ".*_", "")) |>
# zu Faktoren konvertieren
mutate(
eltern = factor(eltern, levels = c("mutter", "vater")),
bildung = factor(bildung, levels = c(
"Hauptschule", "Realschule",
"Abitur", "Hochschule"
))
) |>
# Gruppieren: zuerst Eltern, dann Bildungsniveaus
group_by(eltern, bildung) |>
# Mittlere Note berechnen
summarise(Gesamtnote = mean(Gesamtnote))

## `summarise()` has grouped output by 'eltern'. You can override using the

69
## `.groups` argument.
bildung

## # A tibble: 8 x 3
## # Groups: eltern [2]
## eltern bildung Gesamtnote
## <fct> <fct> <dbl>
## 1 mutter Hauptschule 4.10
## 2 mutter Realschule 4.37
## 3 mutter Abitur 4.51
## 4 mutter Hochschule 4.73
## 5 vater Hauptschule 4.08
## 6 vater Realschule 4.38
## 7 vater Abitur 4.50
## 8 vater Hochschule 4.69

1.4.5 Facets
Bisher haben wir Gruppierungsvariablen verwendet, um unterschiedliche Farben, Formen oder Linientypen
für Kategorien der Gruppierungsvariable innerhalb eines Plots zu erzeugen. In manchen Fällen kann dies
jedoch zu einer unübersichtlichen Grafik führen. Zum Beispiel würde ein Histogramm der Schulnoten für
jede Bildungsstufe der Mutter die Grafik überladen.
p <- jugendliche |>
select(Gesamtnote, bildung_mutter) |>
drop_na() |>
ggplot(mapping = aes(
x = Gesamtnote,
fill = bildung_mutter
))

p + geom_histogram(
binwidth = 0.8,
position = "dodge"
)

70
40

30 bildung_mutter
Hauptschule
count

Realschule
20 Abitur
Hochschule

10

3 4 5 6
Gesamtnote
Eine klare Lösung für das Problem der Übersichtlichkeit wäre, die Histogramme für die verschiedenen Bil-
dungsniveaus der Mutter in separaten Grafiken darzustellen. Dies können wir mithilfe der Funktionen
facet_wrap() und facet_grid() erreichen.
Mit facet_wrap() erstellen wir separate Grafiken für jede Kategorie der Gruppierungsvariable:
p <- jugendliche |>
select(Gesamtnote, bildung_mutter) |>
drop_na() |>
ggplot(mapping = aes(
x = Gesamtnote,
fill = bildung_mutter
)) +
facet_wrap(~bildung_mutter)

p + geom_histogram(binwidth = 0.8)

71
Hauptschule Realschule

40

30

20

10
bildung_mutter
0 Hauptschule
count

Abitur Hochschule Realschule


Abitur
40 Hochschule

30

20

10

0
3 4 5 6 3 4 5 6
Gesamtnote
Wenn wir zwei Gruppierungsvariablen haben, können wir mit facet_grid() ein Raster von Grafiken er-
stellen.
p <- jugendliche |>
select(Gesamtnote, bildung_mutter, bildung_vater) |>
drop_na() |>
ggplot(mapping = aes(x = Gesamtnote)) +
facet_grid(bildung_mutter ~ bildung_vater)

p + geom_histogram(
binwidth = 0.8,
fill = "steelblue4"
)

72
Hauptschule Realschule Abitur Hochschule

Hauptschule
30
20
10
0

Realschule
30
20
10
count

30

Abitur
20
10
0

Hochschule
30
20
10
0
3 4 5 6 3 4 5 6 3 4 5 6 3 4 5 6
Gesamtnote
Bei facet_grid() werden die Stufen der Bildung der Mutter in den Zeilen und die Stufen der Bildung des
Vaters in den Spalten dargestellt.
Als zweites Beispiel können wir den Notenschnitt in Abhängigkeit von der Bildung der Eltern als Liniendi-
agramm darstellen, getrennt nach Vätern und Müttern. Wir können facet_grid() auch verwenden, wenn
wir nur eine Gruppierungsvariable haben, um die Anzahl der Zeilen oder Spalten festzulegen.
Wenn wir die Gruppierung in den Zeilen möchten, verwenden wir facet_grid(Gruppierungsvariable ~
.), wenn wir sie in den Spalten möchten, verwenden wir ‘facet_grid(. ~ Grupp
p <- bildung |>
ggplot(aes(
x = bildung,
y = Gesamtnote,
group = eltern
))

p + geom_line(linewidth = 2, color = "pink") +


geom_point(size = 4, color = "steelblue3") +
# Stufen von 'eltern' in die Zeilen
facet_grid(eltern ~ .)

73
4.6

mutter
4.4

4.2
Gesamtnote

4.6

vater
4.4

4.2

Hauptschule Realschule Abitur Hochschule


bildung
p <- bildung |>
ggplot(aes(
x = bildung,
y = Gesamtnote,
group = eltern
))

p + geom_line(linewidth = 2, color = "pink") +


geom_point(size = 4, color = "steelblue3") +
# Stufen von 'eltern' in die Spalten
facet_grid(. ~ eltern)

74
mutter vater

4.6
Gesamtnote

4.4

4.2

Hauptschule Realschule Abitur Hochschule Hauptschule Realschule Abitur Hochschule


bildung

1.4.6 Farben und Themes


Bisher hat ggplot2 automatisch Farben für uns ausgewählt, wenn wir Farben für eine Gruppierung benötigt
haben. Die Standard-Farbpalette ist jedoch für Farbenblinde nicht gut geeignet. Es gibt viele Farbpaletten,
die wir verwenden könnten. Hier definieren wir jedoch eine eigene Farbpalette, die für Farbenblinde geeignet
ist.
palette <- c(
"#000000", "#E69F00",
"#56B4E9", "#009E73",
"#F0E442", "#0072B2",
"#D55E00", "#CC79A7"
)

Benutzung:
• Formen ausfüllen:
scale_fill_manual(values = palette)

## <ggproto object: Class ScaleDiscrete, Scale, gg>


## aesthetics: fill
## axis_order: function
## break_info: function
## break_positions: function
## breaks: waiver
## call: call
## clone: function
## dimension: function

75
## drop: TRUE
## expand: waiver
## get_breaks: function
## get_breaks_minor: function
## get_labels: function
## get_limits: function
## guide: legend
## is_discrete: function
## is_empty: function
## labels: waiver
## limits: NULL
## make_sec_title: function
## make_title: function
## map: function
## map_df: function
## n.breaks.cache: NULL
## na.translate: TRUE
## na.value: grey50
## name: waiver
## palette: function
## palette.cache: NULL
## position: left
## range: environment
## rescale: function
## reset: function
## scale_name: manual
## train: function
## train_df: function
## transform: function
## transform_df: function
## super: <ggproto object: Class ScaleDiscrete, Scale, gg>
• Linien und Punkte:
scale_colour_manual(values = palette)

## <ggproto object: Class ScaleDiscrete, Scale, gg>


## aesthetics: colour
## axis_order: function
## break_info: function
## break_positions: function
## breaks: waiver
## call: call
## clone: function
## dimension: function
## drop: TRUE
## expand: waiver
## get_breaks: function
## get_breaks_minor: function
## get_labels: function
## get_limits: function
## guide: legend
## is_discrete: function
## is_empty: function
## labels: waiver

76
## limits: NULL
## make_sec_title: function
## make_title: function
## map: function
## map_df: function
## n.breaks.cache: NULL
## na.translate: TRUE
## na.value: grey50
## name: waiver
## palette: function
## palette.cache: NULL
## position: left
## range: environment
## rescale: function
## reset: function
## scale_name: manual
## train: function
## train_df: function
## transform: function
## transform_df: function
## super: <ggproto object: Class ScaleDiscrete, Scale, gg>
p <- jugendliche |>
select(stress_psychisch, leben_gesamt, geschlecht) |>
drop_na() |>
ggplot(mapping = aes(
x = stress_psychisch,
y = leben_gesamt,
color = geschlecht,
shape = geschlecht
))

p + geom_jitter(size = 3, alpha = 0.9) +


scale_colour_manual(values = palette)

77
7

6
leben_gesamt

geschlecht
5
männlich
weiblich

2 4 6
stress_psychisch
# Farben von Hand bestimmen:

p + geom_jitter(size = 3, alpha = 0.9) +


scale_colour_manual(values = c("pink2", "steelblue3"))

78
7

6
leben_gesamt

geschlecht
5
männlich
weiblich

2 4 6
stress_psychisch
# Hintergund (theme) ändern:

p <- jugendliche |>


select(stress_psychisch, leben_gesamt, geschlecht) |>
drop_na() |>
ggplot(mapping = aes(
x = stress_psychisch,
y = leben_gesamt,
color = geschlecht,
shape = geschlecht
))

p + geom_jitter(size = 3, alpha = 0.9) +


scale_colour_manual(values = palette) +
theme_bw()

79
7

6
leben_gesamt

geschlecht
5
männlich
weiblich

2 4 6
stress_psychisch
p <- jugendliche |>
select(stress_psychisch, leben_gesamt, geschlecht) |>
drop_na() |>
ggplot(mapping = aes(
x = stress_psychisch,
y = leben_gesamt,
color = geschlecht,
shape = geschlecht
))

p + geom_jitter(size = 3, alpha = 0.9) +


scale_colour_manual(values = palette) +
theme_classic()

80
7

6
leben_gesamt

geschlecht
5
männlich
weiblich

2 4 6
stress_psychisch

1.4.7 Beschriftungen
Beschriftungen der Achsen und Vergabe eines Titels, so wie das Ändern der Schriftgröße:
p <- jugendliche |>
select(stress_psychisch, leben_gesamt, geschlecht) |>
drop_na() |>
ggplot(mapping = aes(
x = stress_psychisch,
y = leben_gesamt,
color = geschlecht,
shape = geschlecht
))

p + geom_jitter(size = 3, alpha = 0.9) +


scale_colour_manual(values = palette) +
theme_classic(base_size = 14) +
ggtitle("Zusammenhang zwischen Stress und Zufriedenheit") +
xlab("Psychischer Stress") +
ylab("Zufriedenheit") +
# Titel der color- und shape-Legende ist "Geschlecht"
labs(
color = "Geschlecht",
shape = "Geschlecht"
)

81
Zusammenhang zwischen Stress und Zufriedenheit
7

6
Zufriedenheit

Geschlecht
5
männlich
weiblich

2 4 6
Psychischer Stress

1.4.8 Grafiken speichern


Speichern einer Grafik mittels ggsave():
p <- jugendliche |>
select(stress_psychisch, leben_gesamt, geschlecht) |>
drop_na() |>
ggplot(mapping = aes(
x = stress_psychisch,
y = leben_gesamt,
color = geschlecht,
shape = geschlecht
))

# Wir nennen die Grafik 'my_plot'


my_plot <- p + geom_jitter(size = 3, alpha = 0.9) +
scale_colour_manual(values = palette) +
theme_classic(base_size = 14) +
ggtitle("Zusammenhang zwischen Stress und Zufriedenheit") +
xlab("Psychischer Stress") +
ylab("Zufriedenheit") +
labs(
color = "Geschlecht",
shape = "Geschlecht"
)

# Speichern

82
ggsave(
filename = "my_plot.png",
plot = my_plot
)

## Saving 6.5 x 4.5 in image

83
2 W3schools’s R Tutorial - Zusammenfassung
2.1 Tutorial
2.1.1 Syntax
Für die Ausgabe von Text muss einfach nur den Text in Anführungszeichen setzen
Zahlen kann man einfach so hinschreiben.
Und simple Berechnungen macht man einfach so:
5 + 5

## [1] 10

2.1.1.1 Print Man kann Texte einfach so hinschreiben und sie werden ausgegeben. Allerdings kann man
auch die print()-Methode verwenden.
Man muss manchmal die print()-Methode verwenden. Zum Beispiel bei for-loops:
for (x in 1:10) {
print(x)
}

## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10

2.1.2 Comments
Kommentare werden mit einem Hashtag am Anfang eines Kommentars definiert:
# This is a comment
"Hello World!"

## [1] "Hello World!"


"Hello World!" # This is a comment

## [1] "Hello World!"


Es gibt jedoch keine Funktion für das Kommentieren von mehreren Zeilen, abgesehen vom Benutzen mehrerer
Hashtags.

2.1.3 Variables
Variablen müssen nicht extra deklariert werden. Sobald man ihnen einen Wert zuweißt, werden sie automa-
tisch erstellt.
Das Zuweisen von Werten gegenüber Variablen funktioniert über das <- Zeichen oder über das = Zeichen.
Allerdings wird <- meistens verwendet und auch präferiert, da = manchmal verboten ist.
name <- "John"
age <- 40

84
name

## [1] "John"
age

## [1] 40

2.1.3.1 Concatenate Elements Man kann mehrere Variablen in einanderführen mit der paste()-
Funktion.
text <- "awesome"

paste("R is", text)

## [1] "R is awesome"


text1 <- "R is"
text2 <- "awesome"

paste(text1, text2)

## [1] "R is awesome"


num1 <- 5
num2 <- 10
# Für Zahlen kann man auch das + Zeichen verwenden
num1 + num2

## [1] 15

2.1.3.2 Multiple Variables Man kann den gleichen Wert mehreren Variablen übergeben.
var1 <- var2 <- var3 <- "Orange"

var1

## [1] "Orange"
var2

## [1] "Orange"
var3

## [1] "Orange"

2.1.3.3 Variable Names Es gibt ein paar Regeln, wie der Name einer Variablen auszusehen hat:
• Ein Variablenname muss mit einem Buchstaben beginnen und kann eine Kombination aus Buchstaben,
Zahlen und Punkten, sowie Unterstrichen sein. Nach einem Punkt darf keine Zahl kommen
• Ein Variablenname darf nicht mit einem Punkt oder einem Unterstrich beginnen
• Variablennamen sind Case-sensitive, was bedeutet, dass “age”, “aGe”, “Age”, “aGE”, “AgE” und
“AGE” alle unterschiedliche Variablen sind.
• Reservierte Keywords dürfen nicht als Variablennamen benutzt werden. (TRUE, FALSE, if, NA, NULL,
…)
# Legal variable names:
myvar <- "John"
my_var <- "John"

85
myVar <- "John"
MYVAR <- "John"
myvar2 <- "John"
.myvar <- "John"

# Illegal variable names:


#2myvar <- "John"
#my-var <- "John"
#my var <- "John"
#_my_var <- "John"
#my_v@ar <- "John"
#TRUE <- "John"

2.1.4 Data Types


In R können Variablen ihren Datentypen dynamisch ändern.
my_var <- 30
my_var <- "Sally"

Basic Data Types:


• numeric - (10.5, 55, 787)
• integer - (1L, 55L, 100L, das “L” erstellt einen Integer)
• complex - (9 + 3i, wobei “i” der imaginäre Teil ist)
• character (a.k.a. string) - (“k”, “R is exciting”, “FALSE”, “11.5”)
• logical (a.k.a. boolean) - (TRUE or FALSE)
Beispiele:
# numeric
x <- 10.5
class(x)

## [1] "numeric"
# integer
x <- 1000L
class(x)

## [1] "integer"
# complex
x <- 9i + 3
class(x)

## [1] "complex"
# character/string
x <- "R is exciting"
class(x)

## [1] "character"
# logical/boolean
x <- TRUE
class(x)

## [1] "logical"

86
2.1.5 Numbers
Es gibt in R drei verschiedene Typen von Zahlen:
• numeric
• integer
• complex
x <- 10.5 # numeric
y <- 10L # integer
z <- 1i # complex

Der numeric Datentyp ist der häufigste in R. Er kann so wohl ganzzahlige Nummern beinhalten, als auch
Dezimalzahlen.
Der Integer kann nur ganzzahlige Werte haben. Wenn man eine Variable vom Datentyp Integer erstellen
möchte, muss man ein “L” hinten dranhängen.
Eine complex Zahl, ist jene Zahl, wo ein i (Imaginär) vorkommt.
Man kann auch zwischen den Datentypen wechseln mit:
• as.numeric()
• as.integer()
• as.complex()
x <- 5L
class(x)

## [1] "integer"
x <- as.numeric(x)
class(x)

## [1] "numeric"

2.1.6 Math
Normale Operator wie + und - können ganz einfach für leichte Berechnungen, als auch etwas komplexere
benutzt werden:
10 - 5

## [1] 5
2 + 7

## [1] 9
Außerdem hat R noch eingebaute Funktionen für das Berechnen von dem niedrigsten und höchsten Wert in
einem Set.
max(5, 10, 15)

## [1] 15
min(5, 10, 15)

## [1] 5
# Berechnen der 2. Wurzel einer Zahl
sqrt(16)

## [1] 4

87
# Ausgeben des Betrags einer Zahl
abs(-4.7)

## [1] 4.7
# Runden nach oben
ceiling(1.4)

## [1] 2
# Runden nach unten
floor(1.4)

## [1] 1

2.1.7 Strings
Man kann einen String mit “ ” oder ’ ’ anschreiben.
"hello"

## [1] "hello"
'hello'

## [1] "hello"
# Zuweisung
str <- "Hello"

# Multiline String
str <- "Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua."

str

## [1] "Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit,\nsed do eiusmod tempor incididunt\nut
# R will put \n's where the return is pressed
# We can use the cat function to avoid this

cat(str)

## Lorem ipsum dolor sit amet,


## consectetur adipiscing elit,
## sed do eiusmod tempor incididunt
## ut labore et dolore magna aliqua.
# Hol dir die Länge eines Strings
nchar(str)

## [1] 123
# Man kann mit grepl überprüfen ob Characters in einem String vorhanden sind
grepl("Lorem", str)

## [1] TRUE
grepl("ipsum", str)

88
## [1] TRUE
grepl("X", str)

## [1] FALSE
# Man kann die paste Funktion benutzen, um Strings zusammenzuführen
str1 <- "Hello"
str2 <- "World"

paste(str1, str2)

## [1] "Hello World"

2.1.7.1 Escape Characters Wenn man Zeichen in einem String benutzen möchte, die bereits eine andere
Funktion haben oder illegal sind, wie “\” oder “””, muss man diese “escapen”. Das bedeutet, man muss ein
“\” davor schreiben und nun werden sie escaped.
str <- "We are the so-called \"Vikings\", from the north."

str

## [1] "We are the so-called \"Vikings\", from the north."


cat(str)

## We are the so-called "Vikings", from the north.


Andere Escaped character sind hier:
• \\ - Backslash
• \n - New Line
• \r - Carriage Return
• \t - Tab
• \b - Backspace

2.1.8 Booleans
Wenn man in seinem Code wissen möchte, ob ein Operator wahr oder falsch ist, benötigt man logische
Operatoren, kurz: Booleans.
10 < 9

## [1] FALSE
11 > 2

## [1] TRUE
4 == 3

## [1] FALSE
# Dies kann man auch mit Variablen machen

a <- 2
b <- 5

a < b

## [1] TRUE

89
# Man kann eben falls logische Operatoren in einem if-Statement verwenden, bzw. muss man auch

if (b > a) {
print("b ist größer als a")
} else {
print("b ist nicht größer als a")
}

## [1] "b ist größer als a"

2.1.9 Operators
Operatoren werden benötigt, um gewisse Operationen durchzuführen, wie das addieren mit dem Addition-
soperator +.
Hier ist eine Liste an arithmetischen Operatoren in R:
• + Addition x + y

• - Subtraction x - y

• * Multiplication x * y

• / Division x / y
• ^ Exponent x ^ y

• %% Modulus (Remainder from division) x %% y

• %/% Integer Division x%/%y


Hier ist eine Liste an Vergleichsoperatoren in R:
• == Equal x == y

• != Not equal x != y

• > Greater than x > y

• < Less than x < y

• >= Greater than or equal to x >= y

• <= Less than or equal to x <= y


Hier ist eine Liste an logischen Operatoren in R:
• & Element-wise Logical AND operator. It returns TRUE if both elements are TRUE
• && Logical AND operator - Returns TRUE if both statements are TRUE
• | Elementwise- Logical OR operator. It returns TRUE if one of the statement is TRUE
• || Logical OR operator. It returns TRUE if one of the statement is TRUE.
• ! Logical NOT - returns FALSE if statement is TRUE
Hier ist eine Liste an sonstigen Operatoren in R:
• : Creates a series of numbers in a sequence x <- 1:10
• %in% Find out if an element belongs to a vector x %in% y
• %*% Matrix Multiplication x <- Matrix1 %*% Matrix2

90
2.1.10 If…Else
If Statements unterstützen an und für sich alle Vergleichsoperatoren.
Man benutzt If-Statements, wenn man eine Verzweigung haben möchte. Sprich, wenn eine Bedingung erfüllt
ist, soll etwas gemacht werden. Mit dem else geben wir dann an, was passieren soll, wenn diese Bedingung
nicht erfüllt ist.
a <- 33
b <- 200

if (b > a) {
print("b is greater than a")
} else if (a == b) {
print ("a and b are equal")
}

## [1] "b is greater than a"


Dann kann man zusätzlich zu dem if am Anfang und dem else am Ende auch noch ein else if einfügen. Dies
wird ausgeführt, wenn die erste Bedingung nicht erfüllt ist, deshalb zuerst else, und dann die nachstehende
Bedingung erfüllt ist, das if.
a <- 200
b <- 33

if (b > a) {
print("b is greater than a")
} else if (a == b) {
print("a and b are equal")
} else {
print("a is greater than b")
}

## [1] "a is greater than b"

2.1.10.1 Nested If Man ebenfalls auch ein If-Statement in einem anderen If-Statement verwenden.
x <- 41

if (x > 10) {
print("Above ten")
if (x > 20) {
print("and also above 20!")
} else {
print("but not above 20.")
}
} else {
print("below 10.")
}

## [1] "Above ten"


## [1] "and also above 20!"

2.1.10.2 AND OR Operators Das & Symbol steht für AND und kann auch bei Bedingungen verwendet
werden. SO können mehrere kombiniert werden und nur wenn beide erfüllt werden, wird auch der Code
ausgeführt.

91
a <- 200
b <- 33
c <- 500

if (a > b & c > a) {


print("Both conditions are true")
}

## [1] "Both conditions are true"


Das Gegenstück zum & ist das | Zeichen, welches nichts anderes als ein logisches ODER ist. Das bedeutet,
dass nur eine der beiden Bedingungen wahr sein müssen.
a <- 200
b <- 33
c <- 500

if (a > b | a > c) {
print("At least one of the conditions is true")
}

## [1] "At least one of the conditions is true"

2.1.11 While Loops


Schleifen werden benötigt, um eine gewisse Tätigkeit für eine größere Anzahl durchzuführen.
Es gibt in R 2 Schleigen:
• while loop
• for loop
Die while loop funktioniert so, dass der Code innerhalb der Schleife so lange ausgeführt wird, bis die Bedin-
gung nicht mehr TRUE ist.
i <- 1
while (i < 6) {
print(i)
i <- i + 1
}

## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
Dann gibt es noch das Keyword break. Mit break kann man aus einer Schleife raus gehen.
i <- 1
while (i < 6) {
print(i)
i <- i + 1
if (i == 4) {
break
}
}

## [1] 1

92
## [1] 2
## [1] 3
Jetzt wurde die Schleife 3 mal ausgeführt und das if Statement war TRUE und wir haben die Schleife
verlassen.
Mit next kann man zur nächsten Iteration springen aber den Code darunter nicht ausführen.
i <- 0
while (i < 6) {
i <- i + 1
if (i == 3) {
next
}
print(i)
}

## [1] 1
## [1] 2
## [1] 4
## [1] 5
## [1] 6
NUn wurde die Zahl nicht in die Konsole geschrieben.

2.1.12 For Loops


Eine For Loop wird benutzt, wenn man über eine Sequenz iterieren möchte und dann mit jedem Element
aus der Sequenz weiterarbeiten möchte.
for (x in 1:10) {
print(x)
}

## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
fruits <- list("apple", "banana", "cherry")

for (x in fruits) {
print(x)
}

## [1] "apple"
## [1] "banana"
## [1] "cherry"
dice <- c(1, 2, 3, 4, 5, 6)

for (x in dice) {

93
print(x)
}

## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
Wie bereits vorher erwähnt gibt es das Break Keyword, welches aus der Schleife heraus geht. Next funktion-
iert hier genau gleich.

2.1.12.1 Nested Loops Nun, kann man auch Schleifen in Schleifen durchgehen lassen. So kann man
beispielsweise eine Matrix durchgehen, man geht zuerst alle Spalten durch und dann alle Zeilen.
adj <- list("red", "big", "tasty")

fruits <- list("apple", "banana", "cherry")


for (x in adj) {
for (y in fruits) {
print(paste(x, y))
}
}

## [1] "red apple"


## [1] "red banana"
## [1] "red cherry"
## [1] "big apple"
## [1] "big banana"
## [1] "big cherry"
## [1] "tasty apple"
## [1] "tasty banana"
## [1] "tasty cherry"

2.1.13 Functions
Eine Funktion fungiert so, dass man einen gewissen Blockteil schreibt, der immer beim Ausführen der
Funktion.
Eine Funktion kann man mit dem function() keyword erstellen:
my_function <- function() { # create a function with the name my_function
print("Hello World!")
}

Um eine Funktion aufzurufen, muss man lediglich den Namen mit Klammern aufrufen:
my_function()

## [1] "Hello World!"


Nun kann man auch Argumente definieren. Diese können Werte beinhalten, die man später für Rechnungen
nutzen kann.
my_function <- function(fname) {
paste(fname, "Griffin")
}

94
my_function("Peter")

## [1] "Peter Griffin"


my_function("Lois")

## [1] "Lois Griffin"


my_function("Stewie")

## [1] "Stewie Griffin"


Die Anzahl der Argumente müssen immer gleich sein. Sprich: Wenn zwei angefordert sind, dann muss man
auch zwei Argumente übergeben.
my_function <- function(fname, lname) {
paste(fname, lname)
}

my_function("Peter", "Griffin")

## [1] "Peter Griffin"


Man kann aber auch Default Parameter erstellen, wodurch man beim Aufrufen der Funktion das Argument
nicht angeben muss. Wenn nun das Argument nicht angegeben wird, wird der Default Value genommen.
my_function <- function(country = "Norway") {
paste("I am from", country)
}

my_function("Sweden")

## [1] "I am from Sweden"


my_function("India")

## [1] "I am from India"


my_function() # will get the default value, which is Norway

## [1] "I am from Norway"


my_function("USA")

## [1] "I am from USA"


Man kann ebenfalls bei einer Funktion einen Wert zurückgeben.
my_function <- function(x) {
return (5 * x)
}

print(my_function(3))

## [1] 15
print(my_function(5))

## [1] 25
print(my_function(9))

95
## [1] 45

2.1.13.1 Nested Functions Es gibt an und für sich 2 Wege, wie man eine Nested Function in R
definieren kann:
• Entweder ruft man eine Funktion in einer anderen Funktion auf oder
• man schreibt eine Funktion in einr anderen Funktion
# 1.
Nested_function <- function(x, y) {
a <- x + y
return(a)
}

# 2.
Outer_func <- function(x) {
Inner_func <- function(y) {
a <- x + y
return(a)
}
return (Inner_func)
}
output <- Outer_func(3) # To call the Outer_func
output(5)

## [1] 8

2.1.13.2 Function Recursion In R darf man, bzw. ist Rekursion in Funktionen erlaubt. Das bedeutet,
dass eine Funktion sich selber aufrufen kann.
In folgendem Beispiel wird dies demonstriert:
tri_recursion <- function(k) {
if (k > 0) {
result <- k + tri_recursion(k - 1)
print(result)
} else {
result = 0
return(result)
}
}
tri_recursion(6)

## [1] 1
## [1] 3
## [1] 6
## [1] 10
## [1] 15
## [1] 21

2.1.13.3 Global Variables Globale Variablen sind Variablen, die außerhalb von Funktionen erstellt
wurden. Diese kann man außerhalb, als auch innerhalb einer Funktion verwenden.
txt <- "awesome"
my_function <- function() {
paste("R is", txt)
}

96
my_function()

## [1] "R is awesome"


Folgendes Beispiel demonstriert gut, wie sich globalle Variablen verhalten, wenn man diese in Funktionen
verändert.
txt <- "global variable"
my_function <- function() {
txt = "fantastic"
paste("R is", txt)
}

my_function()

## [1] "R is fantastic"


txt # print txt

## [1] "global variable"


Wenn man «- statt <- benutzt, dann wird der Wert der globalen Variable zugewiesen.
txt <- "awesome"
my_function <- function() {
txt <<- "fantastic"
paste("R is", txt)
}

my_function()

## [1] "R is fantastic"


print(txt)

## [1] "fantastic"

97
2.2 Data Structures
2.2.1 Vectors
Ein Vektor ist eine Liste von Werten von einem gleichen Datentypen. Um einen Vektor zu erstellen aus
mehrern Items, kann man die Funktion c() benutzen.
# Vector of strings
fruits <- c("banana", "apple", "orange")

# Print fruits
fruits

## [1] "banana" "apple" "orange"


#Speichern des Vektors in eine Variable

# Vector of numerical values


numbers <- c(1, 2, 3)

# Print numbers
numbers

## [1] 1 2 3
# Man kann aber auch mit einem : eine Sequenz von bis erstellen:
# Vector with numerical values in a sequence
numbers <- 1:10

numbers

## [1] 1 2 3 4 5 6 7 8 9 10
# Wenn man Vektoren voon Dezimalzahlen erstellt und der letzte Wert nicht in die Reihe passt, dann wird

# Vector with numerical decimals in a sequence


numbers1 <- 1.5:6.5
numbers1

## [1] 1.5 2.5 3.5 4.5 5.5 6.5


# Vector with numerical decimals in a sequence where the last element is not used
numbers2 <- 1.5:6.3
numbers2

## [1] 1.5 2.5 3.5 4.5 5.5


# Bestimmen der Länge eines Vektors:
fruits <- c("banana", "apple", "orange")

length(fruits)

## [1] 3
Mit der sort() Funktion kann man die Elemente der Vektoren sortieren:
fruits <- c("banana", "apple", "orange", "mango", "lemon")
numbers <- c(13, 3, 5, 7, 20, 2)

sort(fruits) # Sort a string

## [1] "apple" "banana" "lemon" "mango" "orange"

98
sort(numbers) # Sort numbers

## [1] 2 3 5 7 13 20
Das Zugreifen der Elemente erfolgt spezifisch durch Indexe:
fruits <- c("banana", "apple", "orange")

# Access the first item (banana)


fruits[1]

## [1] "banana"
fruits <- c("banana", "apple", "orange", "mango", "lemon")

# Access the first and third item (banana and orange)


fruits[c(1, 3)]

## [1] "banana" "orange"


# Ändern des Wertes eines Elements:
# Change "banana" to "pear"
fruits[1] <- "pear"

# Print fruits
fruits

## [1] "pear" "apple" "orange" "mango" "lemon"


Man kann auch Vektoren wiederholen mit rep().
repeat_each <- rep(c(1,2,3), each = 3)

repeat_each

## [1] 1 1 1 2 2 2 3 3 3
Hier wird für jedes Element das Element noch 2 weitere Male wiederholt.
Und jetzt wird der ganze Vektor 3 mal wiederholt.
repeat_times <- rep(c(1,2,3), times = 3)

repeat_times

## [1] 1 2 3 1 2 3 1 2 3
# nun wird die Wiederholung konkret angegeben
repeat_indepent <- rep(c(1,2,3), times = c(5,2,1))

repeat_indepent

## [1] 1 1 1 1 1 2 2 3
Man kann außerdem mit seq() Sequenced Vectors erstellen. Diese kann man etwas genauer definieren, als
lediglich mit einem Doppelpunkt.
numbers <- seq(from = 0, to = 100, by = 20)

numbers

## [1] 0 20 40 60 80 100

99
2.2.2 Lists
Eine Liste kann mehrere Datentypen beinhalten. Man kreirt eine Liste mit dem Keyword list().
# List of strings
# Erstellen einer Liste
thislist <- list("apple", "banana", "cherry")

# Print the list


thislist

## [[1]]
## [1] "apple"
##
## [[2]]
## [1] "banana"
##
## [[3]]
## [1] "cherry"
# Zugreifen auf das erste Element der Liste
thislist[1]

## [[1]]
## [1] "apple"
# Ändern des ersten Element der Liste
thislist[1] <- "blackcurrant"

# Print the updated list


thislist

## [[1]]
## [1] "blackcurrant"
##
## [[2]]
## [1] "banana"
##
## [[3]]
## [1] "cherry"
# Länge der Liste
length(thislist)

## [1] 3
# Überprüfen, ob "apple" in der Liste vorhanden ist.
"apple" %in% thislist

## [1] FALSE
# Hinzufügen eines neuen Elements
append(thislist, "orange")

## [[1]]
## [1] "blackcurrant"
##
## [[2]]
## [1] "banana"

100
##
## [[3]]
## [1] "cherry"
##
## [[4]]
## [1] "orange"
# Hinzufügen eines Elements an einer bestimmten Stelle

append(thislist, "kiwi", after = 2)

## [[1]]
## [1] "blackcurrant"
##
## [[2]]
## [1] "banana"
##
## [[3]]
## [1] "kiwi"
##
## [[4]]
## [1] "cherry"
# Entfernen von "apple":
thislist <- list("apple", "banana", "cherry")

newlist <- thislist[-1]

# Print the new list


newlist

## [[1]]
## [1] "banana"
##
## [[2]]
## [1] "cherry"
Man kann einen Raum von Indexen festlegen, wie folgt:
thislist <- list("apple", "banana", "cherry", "orange", "kiwi", "melon", "mango")

(thislist)[2:5]

## [[1]]
## [1] "banana"
##
## [[2]]
## [1] "cherry"
##
## [[3]]
## [1] "orange"
##
## [[4]]
## [1] "kiwi"
Man kann dann durch diese Liste loopen und jedes Element printen.

101
for (x in thislist) {
print(x)
}

## [1] "apple"
## [1] "banana"
## [1] "cherry"
## [1] "orange"
## [1] "kiwi"
## [1] "melon"
## [1] "mango"
Jetzt können wir auch zwei Listen in eine zusammenführen:
list1 <- list("a", "b", "c")
list2 <- list(1,2,3)
list3 <- c(list1,list2)

list3

## [[1]]
## [1] "a"
##
## [[2]]
## [1] "b"
##
## [[3]]
## [1] "c"
##
## [[4]]
## [1] 1
##
## [[5]]
## [1] 2
##
## [[6]]
## [1] 3

102

Das könnte Ihnen auch gefallen