3.2 Datenstrukturen
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.
<- "1"
a <- "2"
b + b a
Fehler 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
<- c(1,2,3,4,5,6,7,8,9,10)
a # Stelle die Zahlen dar
a## [1] 1 2 3 4 5 6 7 8 9 10
Man kann auch Vektoren miteinander verknüpfen:
<- c(1,2,3,4,5)
a <- c(6,7,8,9,10)
b <- c(a, b)
x
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
<- c("Beste", "Exkursion", "der", "Welt")
wort_vec
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.5
3.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 100
Wenn 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 100
3.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 3
3.2.1.4 Vektorelemente auswählen
Um auf eine Zahl in einem Vektor zuzugreifen können wir dies über eine eckige Klammer []
tun.
<- c(1,2,3,4,5)
a 2]
a[## [1] 2
5]
a[## [1] 5
Wenn 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:
c(1,3,5)]
a[## [1] 1 3 5
Eine weitere Möglichkeite die ersten drei Elemente eines Vektors auszuwählen ist mit dem Doppelpunkt :
was so viel bedeutet wie von bis.
1:4]
a[## [1] 1 2 3 4
Elemente 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.
<- c(eins = "Dies", zwei = "ist", drei = "ein", vier = "Test")
namen
namen## eins zwei drei vier
## "Dies" "ist" "ein" "Test"
"vier"]
namen[## 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:
<- list(country = "Germany", state = "Schleswig-Holstein", city = "Meldorf", name = "Speicherkoog")
koog
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
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
<- c(1:10)
a # Teile den Vektor auf zwei Spalten auf
<- matrix(a, ncol = 2)
b
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
<- matrix(a, nrow = 2)
c
c## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 3 5 7 9
## [2,] 2 4 6 8 10
Mit der Funktion rbind()
(row = Zeile) oder cbind()
(column = Spalte) können wir mehrere Vektoren auch zusammenführen.
<- c(1:10)
a <- c(11:20)
b <- c(21:30)
c # 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 30
Die Spalten- oder Zeilennamen einer Matrix können auch benannt oder umbenannt werden mit der Funktion colnames()
oder rownames()
.
<- rbind(a,b,c)
mat
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 30
Eine 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 30
Unsere 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
<- data.frame(
beatles_data 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 1940
Die 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
<- data.frame(
df1 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
<- tibble(
df2 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"