3.2 Datenstrukturen
Figure 3.6: Vergleich eines Skalars und eines Vektors
Der einfachste Datentyp in R ist ein Skalar (Mathematische Größe, die allein durch die Angabe eines Zahlenwertes charakterisiert ist). Im Gegensatz zu der mathematischen Beschreibung, kann in R ein Skalar jedoch character sein und muss nicht zwangsläufig als numeric definiert sein. Mathematische Operationen sind mit numerischen Skalaren möglich, nicht jedoch wenn diese in R als character gespeichert sind.
a <- "1"
b <- "2"
a + bFehler in a + b : nicht-numerisches Argument für binären Operator
Bisher haben wir einfache Objekte in R erzeugt, wie eben genau Skalare oder kürzere Vektoren. Es gibt jedoch noch weitere Datenstrukturen, die sich hinsichtlich der Dimensionalität unterscheiden (1D und 2D) und ob die Objekttypen homogen (nur ein Objekttyp) und heterogen (unterschiedliche Objekttypen) beinhalten:
|Datenstruktur | Dimensionalität | Objekttypen| |Vektor | eindimensional | homogen| |Liste | eindimensional |heterogen| |Matrix | zweidimensional | homogen| |Dataframe | zweidimensional |heterogen|
Table: Datenstrukturen in R.
3.2.1 Vektor
Ein Vektor ist eine Ansammlung von Skalaren, die als ein R Objekt gespeichert wurden. Die Zahlen von 1 bis 10 bspw. bilden einen numerischen Vektor mit der Länge 10. Die Buchstaben im Alphabet sind ein Vektor mit der Länge 26.
🚨 Vektoren können nur numeric oder character sein…nicht beides!
Es gibt verschiedene Möglichkeiten einen Vektor selber zu bilden.
| Funktion | Beispiel | Ergebnis |
|---|---|---|
c(a, b, ...) |
c(1, 5, 9) |
1, 5, 9 |
a:b |
1:5 |
1, 2, 3, 4, 5 |
seq(from, to, by, length.out) |
seq(from = 0, to = 6, by = 2) |
0, 2, 4, 6 |
rep(x, times, each, length.out) |
rep(c(7, 8), times = 2, each = 2) |
7, 7, 8, 8, 7, 7, 8, 8 |
Die einfachste Möglichkeit einen Vektor zu erzeugen ist mit der c() Funktion. “c” leitet sich von dem englischen Wort concatenate ab und lässt sich frei übersetzen mit “zusammenbringen” oder “zusammenführen”.
# Speichere einen Vektor mit den Zahlen von 1 bis 10
a <- c(1,2,3,4,5,6,7,8,9,10)
# Stelle die Zahlen dar
a
## [1] 1 2 3 4 5 6 7 8 9 10Man kann auch Vektoren miteinander verknüpfen:
a <- c(1,2,3,4,5)
b <- c(6,7,8,9,10)
x <- c(a, b)
x
## [1] 1 2 3 4 5 6 7 8 9 10😎 Yeah! Das hat ja gut geklappt.
Man kann auch character Vektoren erstellen mit demselben Prinzip
wort_vec <- c("Beste", "Exkursion", "der", "Welt")
wort_vec
## [1] "Beste" "Exkursion" "der" "Welt"Wenn ihr allerdings einen Vektor von 1:1000 erstellen wollt… 🤯 Aber keine Sorge! Auch hierfür gibt es Funktionen in R um das Leben zu erleichtern.
3.2.1.1 a:b
Die Vektoren werden in Inkrementen von 1 aufgefüllt
1:10
## [1] 1 2 3 4 5 6 7 8 9 10
# Das ganze geht auch Rückwärts
10:1
## [1] 10 9 8 7 6 5 4 3 2 1
# Oder mit nicht runden Zahlen (non-integers)
2.5:8.5
## [1] 2.5 3.5 4.5 5.5 6.5 7.5 8.53.2.1.2 seq()
Diese Funktion musste ich für Zeitreihenuntersuchungen schon öfter verwenden und ist ein wahrer Retter in der Not.
| Argument | Definition |
|---|---|
from |
Beginn der Sequenz |
to |
Ende der Sequenz |
by |
Die Inkremente |
length.out |
Die gewünschte Länge der Sequent (nur wichtig wenn by festgelegt wurde) |
# Erstelle Nummer von 1 bis 10 in einer Schritten
seq(from = 1, to = 10, by = 1)
## [1] 1 2 3 4 5 6 7 8 9 10
# Erstelle ganze Zahlen von 0 bis 100 in 10er Schritten
seq(from = 0, to = 100, by = 10)
## [1] 0 10 20 30 40 50 60 70 80 90 100Wenn das Argument length.out verwendet wird, entspricht die Länge des Vektors dem Wert von length.out.
# Erstelle 10 Zahlen von 1 bis 5
seq(from = 1, to = 5, length.out = 10)
## [1] 1.000000 1.444444 1.888889 2.333333 2.777778 3.222222 3.666667 4.111111
## [9] 4.555556 5.000000
# Erstelle 3 Zahlen von 0 bis 100
seq(from = 0, to = 100, length.out = 3)
## [1] 0 50 1003.2.1.3 rep()
| Argument | Definition |
|---|---|
x |
Ein Skalar oder Vektor der wiederholt werden soll |
times |
Die Anzahl wie häufig x wiederholt werden soll |
each |
Die Anzahl wie häufig jeder Wert in x wiederholt werden soll |
length.out |
Die gewünschte Länge der Sequenz |
Die rep() Funktion erlaubt es also einen Skalar oder Vektor beliebig oft zu wiederholen.
rep(x = 3, times = 10)
## [1] 3 3 3 3 3 3 3 3 3 3
rep(x = c(1, 2), each = 3)
## [1] 1 1 1 2 2 2
rep(x = 1:3, length.out = 10)
## [1] 1 2 3 1 2 3 1 2 3 1💡 Man kann eine a:b Funktion mit einer rep() Funktion verknüpfen.
💡 Sogar das times und each Argument lassen sich in die rep() Funktion integrieren
rep(x = 1:3, each = 2, times = 2)
## [1] 1 1 2 2 3 3 1 1 2 2 3 33.2.1.4 Vektorelemente auswählen
Um auf eine Zahl in einem Vektor zuzugreifen können wir dies über eine eckige Klammer [] tun.
a <- c(1,2,3,4,5)
a[2]
## [1] 2
a[5]
## [1] 5Wenn wir mehrere Elemente des Vektors auswählen möchten, dann müssen wir einen neuen Vektor über die Positionen erzeugen, beispielsweise um das erste, dritte und fünfte Element des Vektors auszugeben:
a[c(1,3,5)]
## [1] 1 3 5Eine weitere Möglichkeite die ersten drei Elemente eines Vektors auszuwählen ist mit dem Doppelpunkt : was so viel bedeutet wie von bis.
a[1:4]
## [1] 1 2 3 4Elemente in einem Vektor können auch mit = benannt werden. Bei der Benennung von Spaltennamen in einer Tabelle (dataframe oder Matrix in R) ist der Befehl ähnlich.
namen <- c(eins = "Dies", zwei = "ist", drei = "ein", vier = "Test")
namen
## eins zwei drei vier
## "Dies" "ist" "ein" "Test"
namen["vier"]
## vier
## "Test"3.2.2 Liste
Listen ähneln Vektoren und können über die Funktion list() erzeugt werden. Beispielsweise der Standort Speicherkoog kann als Liste wie folgt erzeugt werden:
koog <- list(country = "Germany", state = "Schleswig-Holstein", city = "Meldorf", name = "Speicherkoog")
koog
## $country
## [1] "Germany"
##
## $state
## [1] "Schleswig-Holstein"
##
## $city
## [1] "Meldorf"
##
## $name
## [1] "Speicherkoog"Die Darstellung gegenüber Vektoren ist jedoch eine andere. Anstelle der Darstellung nebeneinander werden die Listen Elemente untereinander dargestellt.
3.2.3 Matrix und dataframe
Figure 3.7: Darstellung von Datenstrukturen
3.2.3.1 Matrix
Eine Matrix ist eine zweidimensionale Struktur und kann mit der Funktion matrix() erzeugt werden.
# Erstelle einen Vektor von 1 bis 10
a <- c(1:10)
# Teile den Vektor auf zwei Spalten auf
b <- matrix(a, ncol = 2)
b
## [,1] [,2]
## [1,] 1 6
## [2,] 2 7
## [3,] 3 8
## [4,] 4 9
## [5,] 5 10
# Teile den Vektor auf zwei Zeilen auf
c <- matrix(a, nrow = 2)
c
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 3 5 7 9
## [2,] 2 4 6 8 10Mit der Funktion rbind() (row = Zeile) oder cbind() (column = Spalte) können wir mehrere Vektoren auch zusammenführen.
a <- c(1:10)
b <- c(11:20)
c <- c(21:30)
# Erstelle eine Matrix mit drei Spalten
cbind(a,b,c)
## a b c
## [1,] 1 11 21
## [2,] 2 12 22
## [3,] 3 13 23
## [4,] 4 14 24
## [5,] 5 15 25
## [6,] 6 16 26
## [7,] 7 17 27
## [8,] 8 18 28
## [9,] 9 19 29
## [10,] 10 20 30
# Erstelle eine Matrix mit drei Zeilen
rbind(a,b,c)
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## a 1 2 3 4 5 6 7 8 9 10
## b 11 12 13 14 15 16 17 18 19 20
## c 21 22 23 24 25 26 27 28 29 30Die Spalten- oder Zeilennamen einer Matrix können auch benannt oder umbenannt werden mit der Funktion colnames() oder rownames().
mat <- rbind(a,b,c)
mat
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## a 1 2 3 4 5 6 7 8 9 10
## b 11 12 13 14 15 16 17 18 19 20
## c 21 22 23 24 25 26 27 28 29 30
rownames(mat) <- c("Zeile 1", "Zeile 2", "Zeile 3")
mat
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## Zeile 1 1 2 3 4 5 6 7 8 9 10
## Zeile 2 11 12 13 14 15 16 17 18 19 20
## Zeile 3 21 22 23 24 25 26 27 28 29 30Eine nützliche Funktion lautet t() um eine Matrix oder dataframe zu transponieren, also umzuwandeln und um 90° zu vertauschen.
# Transponiere die Matrix mat
t(mat)
## Zeile 1 Zeile 2 Zeile 3
## [1,] 1 11 21
## [2,] 2 12 22
## [3,] 3 13 23
## [4,] 4 14 24
## [5,] 5 15 25
## [6,] 6 16 26
## [7,] 7 17 27
## [8,] 8 18 28
## [9,] 9 19 29
## [10,] 10 20 30Unsere Zeilennamen machen jetzt natürlich keinen Sinn mehr 🙃 Versuche mal die Spaltennamen richtig zu beschriften.
3.2.3.2 Dataframe
Eine Matrix ähnelt der Datenstruktur wie man sie aus Excel, SPSS etc. kennt. Großer Unterschied ist aber, dass eine Matrix nur einen Datentyp erlaubt und ein dataframe mehrere Typen. Mit der Funktion data.frame() können wir gleich lange Vektoren unterschiedlichen Typs kombinieren.
# Erstelle einen dataframe
beatles_data <- data.frame(
name = c("John", "Paul", "George", "Ringo"),
surname = c("Lennon", "McCartney", "Harrison", "Starr"),
born = c(1940, 1942, 1943, 1940)
)
beatles_data
## name surname born
## 1 John Lennon 1940
## 2 Paul McCartney 1942
## 3 George Harrison 1943
## 4 Ringo Starr 1940Die händische Eingabe von tabellarischen Daten wäre natürlich umständlich. In R gibt es einfache Möglichkeiten diese aus externen Datenquellen (z.B. CSV, Excel, txt, …) einzulesen und zu verarbeiten.
3.2.3.3 tibble
tibble haben dieselbe Datenstruktur wie data.frame, nur das Attribut class in einem tibble ist länger:
# create a data frame
df1 <- data.frame(
x = c("a", "b", "c"),
y = c(1,2,3)
)
typeof(df1)
## [1] "list"
attributes(df1)
## $names
## [1] "x" "y"
##
## $class
## [1] "data.frame"
##
## $row.names
## [1] 1 2 3
# create a tibble
df2 <- tibble(
x = c("a", "b", "c"),
y = c(1,2,3)
)
typeof(df2)
## [1] "list"
attributes(df2)
## $class
## [1] "tbl_df" "tbl" "data.frame"
##
## $row.names
## [1] 1 2 3
##
## $names
## [1] "x" "y"