Objekte (R Objects)

Objekte in R

R verwendet Objekte, um Informationen zu speichern. Hier ist ein einfaches Objekt, das nur den numerischen Wert 1 speichert:

my_number <- 1

Wir haben ein Objekt mit dem Namen my_number erstellt und ihm den Wert 1 zugewiesen. Die Zuweisung des Wertes 1 erfolgte mit den Symbolen <-, die als the assignment operator bezeichnet werden, auf Deutsch Zuweisungsoperator. Man sagt, dass my_number den Wert 1 erhält. Das Objekt my_number enthält nun Informationen in Form eines numerischen Wertes. Fragen wir R, welcher Typ von Objekt my_number ist:

class(my_number)
[1] "numeric"

Demnach interpretiert R my_number als numerisches Objekt, was plausibel erscheint. Wiederholen wir dasselbe Vorgehen stattdessen mit einer Zeichenkette:

my_string <- "Hej! Mitt namn är Salvador."
class(my_string)
[1] "character"

Das Objekt my_string ist ein character-Objekt, das heißt, es besteht aus Zeichen und Symbolen. Diese beiden Beispiele zeigen, dass R in dem Moment, in dem wir ein Objekt erstellen, zu erraten versucht, welche Art von Information das Objekt enthält. Sehen wir uns an, wie R einen numerischen Wert interpretiert, der in Anführungszeichen steht:

my_object <- "1"
class(my_object)
[1] "character"

R interpretiert my_object als Zeichenkette (character-Objekt). Das liegt daran, dass die Ziffer 1 in Anführungszeichen eingeschlossen war, weshalb R annimmt, dass wir eine Zeichenkette speichern wollen.

Alle Informationen, die Sie in Ihrem Environment speichern, sind Objekte. Beispiele für Objekte sind:

  • Tabellen (Data Frames) sind Objekte.
  • Gespeicherte Einzelwerte (wie etwa my_object oben) sind Objekte.
  • Ergebnisse von Regressionsmodellen sind Objekte.

Im Prinzip ist alles, was Sie in R erstellen, ein Objekt. Im Folgenden gehen wir die verschiedenen Typen von Objekten in R durch.

4.1 Atomic Vectors (Atomare Vektoren)

Der einfachste Objekttyp in R ist der atomic vector (atomare Vektor). Atomic Vectors verwenden Sie bei der Arbeit in R ständig. Erstellen wir einen atomaren Vektor mithilfe der Funktion [c()](https://rdrr.io/r/base/c.html). Diese Funktion kombiniert mehrere Elemente zu einem Vektor. Wir nennen das Objekt my_first_vector, und es wird sechs numerische Werte enthalten:

my_first_vector <- c(1, 2, 3, 4, 5, 6)

Mit der Funktion [is.vector()](https://rdrr.io/r/base/vector.html) können wir prüfen, ob R my_first_vector als Atomic Vector betrachtet:

## is.vector() prüft, ob ein Objekt ein Atomic Vector ist
is.vector(my_first_vector)
[1] TRUE

Die Funktion [is.vector()](https://rdrr.io/r/base/vector.html) hat den Wert TRUE zurückgegeben, das heißt, my_first_vector ist ein Atomic Vector. Da my_first_vector ausschließlich numerische Werte enthält, betrachtet R ihn als numerischen Vektor, was sich mit der Funktion [is.numeric()](https://rdrr.io/r/base/numeric.html) überprüfen lässt:

## is.numeric() prüft, ob ein Atomic Vector numerisch ist
is.numeric(my_first_vector)
[1] TRUE

Atomic Vectors haben nur eine Dimension. Jeder Vektor kann nur einen Datentyp speichern. Um alle Arten von Daten handhaben zu können, gibt es daher sechs grundlegende Typen von Atomic Vectors:

  • double: numerische Werte mit oder ohne Dezimalstellen
  • integer: numerische Ganzzahlen (keine Dezimalstellen)
  • character: Zeichen, Symbole, Text
  • logical: JA/NEIN, 0/1, TRUE/FALSE
    • Synonyme: logische Werte (dt.), boolean (engl.), boolesche Werte (dt.).
  • complex- und raw-Vektoren existieren, werden aber praktisch nie verwendet.
my_doubles <- c(1.2, 2.4, 32.1)

my_integers <- c(1L, 2L, 3L)

my_characters <- c("A", "B", "Hello", "My phone is dead")

my_logicals <- c(TRUE, TRUE, FALSE, TRUE, FALSE)

Ob ein Vektor einem der oben genannten Typen entspricht, können Sie mit den Funktionen [is.double()](https://rdrr.io/r/base/double.html), [is.numereric()](https://rdrr.io/r/base/numeric.html), [is.character()](https://rdrr.io/r/base/character.html), [is.logical()](https://rdrr.io/r/base/logical.html) prüfen. Diese Funktionen geben den Wert TRUE oder FALSE zurück.

Wenn Sie prüfen müssen, welcher Vektortyp ein Objekt ist, können Sie die Funktion [typeof()](https://rdrr.io/r/base/typeof.html) verwenden. Unten erstellen wir einen numerischen Vektor mit Dezimalstellen und fragen anschließend, welche Klasse bzw. welchen Typ der Vektor hat.

my_doubles <- c(1.2, 2.4, 32.1)
class(my_doubles)
[1] "numeric"
typeof(my_doubles)
[1] "double"

4.1.0.1 Länge von Vektoren

Die Länge eines Vektors ist schlicht die Anzahl seiner Elemente. Erstellen wir einen atomaren Vektor mit 5 numerischen Werten und prüfen seine Länge:

my_values <- c(1, 2, 3, 4, 5)
length(my_values)
[1] 5

Erstellen wir einen Vektor mit einer langen Zeichenkette, um die Länge zu prüfen:

my_string <- c("Det är roligt att lära sig R!")
length(my_string)
[1] 1

Die Länge dieses Vektors war 1, da er 1 Element enthält, nämlich den Satz “Det är roligt att lära sig R!”. Erstellen wir einen Vektor mit zwei Zeichenketten:

my_string <- c("Det är roligt att lära sig R!", "Det kommer ta en vecka att lära sig R")
length(my_string)
[1] 2

Nun enthält my_string 2 Zeichenketten, und der Vektor hat daher die Länge 2.

Ein Atomic Vector kann nur einen Datentyp speichern. Testen wir dies, indem wir einen Vektor erstellen, der sowohl numerische Werte als auch Zeichenketten und logische Werte enthält.

## Einen Vektor mit Zeichenketten, numerischen Werten und booleschen Werten erstellen
mixed <- c("Det är roligt att lära sig R!", 1, 2, TRUE, FALSE)

Wir geben das Ergebnis aus:

mixed
[1] "Det är roligt att lära sig R!" "1"
[3] "2"                             "TRUE"
[5] "FALSE"

Wir prüfen die Klasse des Vektors:

## Die Klasse des Vektors prüfen
class(mixed)
[1] "character"

Beachten Sie Folgendes:

  1. Alle Elemente wurden mit Anführungszeichen ausgegeben, das heißt, R hat alle Elemente in Zeichenketten umgewandelt, auch die Ziffern, TRUE und FALSE. Dies wird als coercion (erzwungene Umwandlung) bezeichnet: Ein Datentyp wurde automatisch in einen anderen umgewandelt. Die Ziffer 1 ist somit kein numerischer Wert mehr; sie stellt nur noch das Zeichen 1 dar. TRUE und FALSE sind keine booleschen Werte mehr; sie sind nur noch die Wörter TRUE und FALSE.
  2. Dies erklärt, warum die Funktion [class()](https://rdrr.io/r/base/class.html) angibt, dass der Vektor vom Typ character ist.
  3. Da der Typ nun character ist, können Sie mit diesem Vektor keine mathematischen Berechnungen (z. B. Berechnung des Mittelwerts) mehr durchführen.

Beim Erstellen von Vektoren in R müssen Sie explizit sein. Die Zahlen von 1 bis 4 lassen sich sowohl als numerischer Vektor als auch als character-Vektor erstellen. Um einen character-Vektor zu erstellen, muss jedes Element in Anführungszeichen angegeben werden:

Beispiel 1: Numerischen Vektor erstellen

my_numbers <- c(1, 2, 3, 4)
my_numbers
[1] 1 2 3 4

Beispiel 2: character-Vektor erstellen

my_characters <- c("1", "2", "3", "4")
my_characters
[1] "1" "2" "3" "4"

Mit den Funktionen [as.character()](https://rdrr.io/r/base/character.html), [as.numeric()](https://rdrr.io/r/base/numeric.html) usw. können Sie Vektoren zwischen verschiedenen Typen umwandeln.

Beispiel 3: Numerisch in character umwandeln

## Erstellt einen numerischen Vektor
my_numbers <- c(1, 2, 3, 4)

## Wandelt den numerischen Vektor in character um

my_characters <- as.character(my_numbers)
## Gibt das Ergebnis aus
my_characters
[1] "1" "2" "3" "4"

Sie können Vektoren also zwischen Typen umwandeln. Versuchen wir das Gegenteil, also von Zeichen zu numerisch: Beispiel 4: Zeichen in numerisch umwandeln

my_characters <- c("1", "2", "3", "4")
my_numbers <- as.numeric(my_characters)

## Print it
my_numbers
[1] 1 2 3 4

Dies ist gelungen, weil die Ziffern in der richtigen Reihenfolge und ohne Anführungszeichen vorlagen. Wenn es sich jetzt tatsächlich um numerische Werte handelt, sollten wir einen Mittelwert der Zahlen berechnen können:

mean(my_numbers)
[1] 2.5

Nun sind wir sicher, dass es richtig funktioniert hat. Beachten Sie, dass Umwandlungen mitunter unerwartete Ergebnisse liefern können. Deshalb ist es wichtig, eine Art Kontrolle durchzuführen, um sicherzustellen, dass die Umwandlung wie erwartet verläuft.

Versuchen wir, die Zeichenkette “Hej” in einen numerischen Wert umzuwandeln:

## character-Vektor erstellen
my_characters <- c("Hej")

## In einen numerischen Vektor umwandeln
my_numbers <- as.numeric(my_characters)
Warning: NAs introduced by coercion
## Das Ergebnis ausgeben
my_numbers
[1] NA

Hier erhielten wir stattdessen die Warnung “NAs introduced by coercion”. NA steht je nach Kontext für “Not Available” oder “Not Applicable”. In diesem Fall bedeutet es Not Available, das heißt, der Wert fehlt. Die Umwandlung hat also dazu geführt, dass R den Wert zwangsweise in NA umgewandelt hat. Wenn wir das Objekt my_numbers ausgeben, enthält es nur einen einzigen Wert, und dieser ist NA. Mit anderen Worten: R kann “Hej” nicht in einen numerischen Wert umwandeln.

4.1.1 Double vector

Ein double speichert numerische Werte. Die Werte können Dezimalstellen haben. R speichert numerische Vektoren praktisch immer als double, auch wenn sie keine Dezimalstellen haben. Das können wir jetzt überprüfen:

## Numerischen Vektor ohne Dezimalstellen erstellen
my_numbers <- c(1, 2, 3)
## Prüfen, ob er ein double ist
is.double(my_numbers)
[1] TRUE
## Numerischen Vektor mit Dezimalstellen erstellen
your_numbers <- c(1.1, 2.2, 3.3)

## Prüfen, ob er ein double ist
is.double(your_numbers)
[1] TRUE

Obwohl das Objekt my_numbers nur aus Ganzzahlen besteht, speichert R es als double. Wir können prüfen, dass der Vektor kein Integer ist:

is.integer(my_numbers)
[1] FALSE

4.1.2 Integer vector (Ganzzahlen)

Ein integer vector speichert nur Ganzzahlen. Eine Ganzzahl ist ein numerischer Wert ohne Dezimalstellen. Sie werden diesen Vektortyp kaum benötigen, da der double-Vektor ebenfalls Ganzzahlen verarbeiten kann. Im Prinzip können Sie immer double statt integer verwenden. Sie müssen dies nur äußerst selten berücksichtigen, da R es automatisch erledigt. Wenn Sie einen Vektor dennoch als integer definieren möchten, hängen Sie den Buchstaben L an die Zahlen an:

my_integers <- c(1L, 5L, 3L, 10L)
is.integer(my_integers)
[1] TRUE

Sie können einen double auch zwangsweise in einen integer umwandeln (erzwingen):

## Einen double-Vektor erstellen
my_doubles <- c(1, 2, 3, 4)

## Prüfen, ob er ein double ist
is.double(my_doubles)
[1] TRUE
## double in integer umwandeln und das Ergebnis in einem neuen Objekt namens my_integers speichern
my_integers <- as.integer(my_doubles)

## Prüfen, ob my_integers ein integer-Vektor ist
is.integer(my_integers)
[1] TRUE

Verschiedene Vektortypen zu haben ist sehr nützlich. Unterschiedliche Vektoren dienen unterschiedlichen Zwecken. Mathematische Operationen sind nur mit numerischen Vektoren und logicals möglich. Wir demonstrieren dies mit der Funktion [mean()](https://rdrr.io/r/base/mean.html), die den arithmetischen Mittelwert einer Reihe numerischer Werte berechnet:

## Erstellt einen double
my_values <- c(5, 10, 15, 20)

## Berechnet den Mittelwert und speichert das Ergebnis in einem neuen Objekt namens my_mean
my_mean <- mean(my_values)

## Gibt das Objekt aus
my_mean
[1] 12.5

Wir haben bereits erwähnt, dass man Funktionen in Funktionen verschachteln kann, was viel Platz sparen kann. Nun berechnen wir den Mittelwert erneut, ohne neue Objekte zu speichern. Beachten Sie, dass die Funktion [c()](https://rdrr.io/r/base/c.html) in die Funktion [mean()](https://rdrr.io/r/base/mean.html) eingebettet wird.

mean(c(5, 10, 15, 20))
[1] 12.5

4.1.3 Character vector (Zeichenketten)

Text und Symbole werden in character-Vektoren gespeichert. Der folgende Befehl speichert eine Zeichenkette, indem er sie in Anführungszeichen einschließt:

my_string <- c("Detta är en textsträng. Den kan innehålla symboler (@, *, /) och siffror (1, 2, 3)")
my_string
[1] "Detta är en textsträng. Den kan innehålla symboler (@, *, /) och siffror (1, 2, 3)"

Der Vektor my_string speichert eine Zeichenkette, die Symbole, Buchstaben und Ziffern enthält. Es folgt ein character-Vektor mit zwei Zeichenketten, von denen die zweite Ziffern und Symbole enthält:

my_string <- c("Detta är den första strängen", "Detta är den andra strängen")
my_string
[1] "Detta är den första strängen" "Detta är den andra strängen"

Wie oben erwähnt, werden Ziffern in Anführungszeichen als Zeichen (nicht als numerische Werte) interpretiert. Das zeigt das folgende Beispiel, in dem wir außerdem die Funktion [paste()](https://rdrr.io/r/base/paste.html) verwenden, um Kommentare in den Ergebnissen auszugeben:

paste("UTAN CITATTECKEN:")
[1] "UTAN CITATTECKEN:"
my_numbers <- c(1, 2, 3)
typeof(my_numbers)
[1] "double"
my_numbers
[1] 1 2 3
paste("MED CITATTECKEN:")
[1] "MED CITATTECKEN:"
your_numbers <- c("1", "2", "3")
typeof(your_numbers)
[1] "character"
your_numbers
[1] "1" "2" "3"

R zeigt bei der Ausgabe von your_numbers Anführungszeichen an, um deutlich zu machen, dass die Elemente Zeichenketten sind! Alle character-Vektoren werden in R mit Anführungszeichen ausgegeben.

Eine Zeichenkette enthält Zeichen und Symbole. Mit Zeichenketten lassen sich keine mathematischen Operationen durchführen, selbst wenn sie Ziffern enthalten. Sehen wir uns zwei Beispiele an:

Beispiel 1: Eine Zeichenkette mit Buchstaben erstellen

my_string <- "Detta är en sträng"

## Mit 2 multiplizieren
my_string*2
## Error in my_string * 2 : non-numeric argument to binary operator

Beispiel 2: Eine Zeichenkette mit einer Zahl erstellen

my_string <- "100"

## Mit 2 multiplizieren
my_string*2
## Error in my_string * 2 : non-numeric argument to binary operator

In beiden Beispielen antwortet R, dass die Operation nicht ausgeführt werden kann, weil der Vektor nicht numerisch ist. character-Vektoren können also Ziffern enthalten, diese werden aber nicht als numerische Werte behandelt.

Wenn Sie sich auf Elemente in einem character vector beziehen, müssen Sie Anführungszeichen verwenden. Im Folgenden werden zwei Vektoren erstellt, die anschließend zu einem Data Frame kombiniert werden. Danach versuchen wir, unseren Data Frame so zu filtern, dass er nur Frauen enthält.

## Einen Vektor erstellen, der das Geschlecht enthält<
sex <- c("Man", "Woman", "Man", "Woman")

## Einen Vektor mit gemessenen Blutdruckwerten erstellen
blood_pressure <- c(140, 130, 120, 150)

## Die Vektoren mit der Funktion data.frame() zu einem Data Frame zusammenführen
my_data_frame <- data.frame(sex, blood_pressure)

## Unseren Data Frame anzeigen
my_data_frame
    sex blood_pressure
1   Man            140
2 Woman            130
3   Man            120
4 Woman            150

Nun filtern wir so, dass nur Frauen übrig bleiben. Dazu verwenden wir die Funktion [subset()](https://rdrr.io/r/base/subset.html):

only_women <- subset(my_data_frame, sex=="Woman")
## Unseren Data Frame anzeigen
only_women
    sex blood_pressure
2 Woman            130
4 Woman            150

Beachten Sie, dass Woman oben (in der Funktion [subset()](https://rdrr.io/r/base/subset.html)) in Anführungszeichen angegeben ist; dies ist erforderlich, weil der Vektor ein character ist. Wenn wir nach Blutdruck filtern wollen, der ein double ist, verwenden wir keine Anführungszeichen. Im Folgenden filtern wir so, dass nur Zeilen mit normalem Blutdruck (kleiner oder gleich 130) erhalten bleiben:

only_normal_blood_pressure <- subset(my_data_frame, blood_pressure <= 130)

## Unseren Data Frame anzeigen
only_normal_blood_pressure
    sex blood_pressure
2 Woman            130
3   Man            120

4.1.4 Logicals (boolean values, boolesche Werte)

Manche Variablen sind ihrer Natur nach binär. Wenn sich solche Variablen als TRUE oder FALSE charakterisieren lassen, nennt man sie logicals. Ob eine Person tot oder lebendig ist, kann als logical betrachtet werden. Ob eine Person an Krebs erkrankt oder nicht, lässt sich ebenfalls als TRUE oder FALSE klassifizieren. R kann außerdem Vergleiche auswerten und TRUE oder FALSE zurückgeben, wie das folgende Beispiel zeigt:

10>1
[1] TRUE

Es ist ohne Weiteres möglich, die Ziffern 1/0 anstelle von TRUE/FALSE zu verwenden. Die Wörter TRUE und FALSE nehmen in der Sprache R eine Sonderstellung ein. Kommen diese Wörter in Vektoren vor, werden die Vektoren automatisch als logicals interpretiert. R akzeptiert zudem die Abkürzungen T und F.

## Einen Vektor mit Namen erstellen
name <- c("Adam", "Umit", "Joanna", "Sarah")

## Einen booleschen Vektor mit TRUE/FALSE erstellen, ob die Person verstorben ist
dead <- c(TRUE, FALSE, TRUE, FALSE)

## Einen booleschen Vektor mit TRUE/FALSE erstellen, ob die Person verheiratet ist
married <- c(F, T, F, F)

## Die Vektoren zu einem Data Frame zusammenführen
my_data_frame <- data.frame(name, dead, married)

## Unseren Data Frame ausgeben
my_data_frame
    name  dead married
1   Adam  TRUE   FALSE
2   Umit FALSE    TRUE
3 Joanna  TRUE   FALSE
4  Sarah FALSE   FALSE

Wie oben ersichtlich, akzeptiert R die Abkürzungen T für TRUE und F für FALSE.

4.1.5 Complex vector, raw vector

Diese Vektoren werden Sie in R wahrscheinlich nie verwenden, weshalb wir sie nicht besprechen.

4.1.6 Datumsangaben, Uhrzeiten und Zeitintervalle

Die Arbeit mit Datumsangaben, Uhrzeiten und Zeitintervallen ist sehr häufig. R behandelt, wie mehrere andere Sprachen auch, Datum und Uhrzeit als numerische Werte. Das bedeutet, dass jedem Datum und jedem Zeitpunkt ein numerischer Wert zugeordnet wird, der dann in Analysen verwendet werden kann. Damit einem Datum ein numerischer Wert zugeordnet werden kann, muss es ein Referenzdatum geben (ein Datum, von dem ausgegangen wird). In der Sprache SAS ist das Referenzdatum 1960-01-01 00:00:00 GMT. In R ist das Referenzdatum 1970-01-01 00:00:00 UTC, dies kann jedoch vom Benutzer angepasst werden. Welches Referenzdatum verwendet wird, spielt in der Regel keine Rolle.

Datumsangaben werden in Vektoren der Klasse POSIXct oder POSIXlt gespeichert, die tatsächlich vom Typ double sind. Ist ein Vektor vom Typ POSIXct oder POSIXt, kann er wie ein character-Vektor aussehen (da das Datum “-” oder “/” enthalten kann), in Wirklichkeit handelt es sich aber um numerische Werte der Klasse POSIXct oder POSIXlt.

Versuchen wir nun, Vektoren zu erstellen, die aus Datumsangaben bestehen:

## Vektor mit Geburtsdaten erstellen
birth_date <- c("1990-01-01", "1999-01-04", "2002-05-05", "2001-12-12")

## Vektor mit Sterbedaten erstellen
death_date <- c("2005-02-02", "2009-11-14", "2018-01-01", "2011-11-09")
class(birth_date)
[1] "character"
class(death_date)
[1] "character"

Wie wir oben sehen, ist keiner der Vektoren vom Typ POSIXct oder POSIXlt (beide sind vom Typ character). Das ist zu erwarten, da wir die Vektoren erstellt haben, indem wir die Datumsangaben in Anführungszeichen gesetzt haben. Wir müssen R mitteilen, dass diese Vektoren Datumsangaben sind. Das können wir mit Funktionen aus der Standardinstallation von R tun oder mit dem Package lubridate, das einfache und effiziente Funktionen zum Umgang mit Datumsangaben enthält. Wir beginnen damit, die Vektoren mit Standardfunktionen in Datumsangaben umzuwandeln.

## Erstellt Datumsobjekte mit GMT (Greenwich Mean Time) als Zeitzone
birth_date <- as.POSIXct(birth_date)
death_date <- as.POSIXct(death_date)
class(birth_date)
[1] "POSIXct" "POSIXt"
class(death_date)
[1] "POSIXct" "POSIXt"

R hat den Vektor nun von character in Datum (POSIXct) umgewandelt. Wir verwenden jetzt die Funktion [difftime()](https://rdrr.io/r/base/difftime.html), um die Zeitdifferenz zwischen Geburtsdatum und Sterbedatum zu berechnen.

difftime(death_date, birth_date)
Time differences in days
[1] 5511.000 3967.000 5720.042 3619.000

Wie oben ersichtlich, wurde die Zeitdifferenz in Tagen berechnet. Wir können die Zeitdifferenz wie folgt in anderen Einheiten berechnen:

difftime(death_date, birth_date, units="secs")
Time differences in secs
[1] 476150400 342748800 494211600 312681600
difftime(death_date, birth_date, units="mins")
Time differences in mins
[1] 7935840 5712480 8236860 5211360
difftime(death_date, birth_date, units="hours")
Time differences in hours
[1] 132264  95208 137281  86856
difftime(death_date, birth_date, units="weeks")
Time differences in weeks
[1] 787.2857 566.7143 817.1488 517.0000

R verwendet auch Zeitzonen, auch wenn die meisten Benutzer dies nicht berücksichtigen. Beispiele für Zeitzonen sind:

  • CET: Central European Time.
  • CEST: Central European Summer Time.
  • GMT: Greenwich Mean Time

Der Umgang mit Datumsangaben, Zeitzonen und Zeitintervallen mit den Standardpaketen von R kann kompliziert sein. Deshalb haben Garrett Grolemund, Hadley Wickham und Vitalie Spinu das Package lubridate entwickelt, das den Umgang deutlich vereinfacht. Installieren Sie zunächst lubridate:

install.packages("lubridate")

Aktivieren Sie anschließend das Package:

library(lubridate)
Attaching package: 'lubridate'

The following objects are masked from 'package:base':
    date, intersect, setdiff, union

Lubridate speichert Datumsangaben als Anzahl der Tage seit dem Referenzdatum 1970-01-01 00:00:00 GMT. Das konkrete Datum 18000 Tage nach diesem Referenzdatum erhalten Sie mit der Funktion [as_date()](https://lubridate.tidyverse.org/reference/as_date.html):

as_date(18000)
[1] "2019-04-14"

Speichern wir einige Datumsangaben mithilfe der Funktionen von lubridate. Dafür gibt es viele Funktionen. Das Prinzip dieser Funktionen ist wie folgt:

  1. Ermitteln Sie, in welcher Reihenfolge die Zeitelemente Jahr (year, y), Monat (month, m), Tag (day, d), Stunde (hour, h), Minute (minute, m) und Sekunden (seconds, s) im Datum vorkommen.
  2. Verwenden Sie die Funktion, die zur Reihenfolge der Zeitelemente passt.

In der folgenden Tabelle sehen Sie einige Beispiele für verschiedene Schreibweisen des Datums 31. Dezember 2020 und welche lubridate-Funktion das Datum einlesen kann:

Datumsformat Reihenfolge der Zeitelemente Funktion in lubridate
2020-12-31 YYYY-MM-DD ymd()
2020/12/31 YYYY/MM/DD ymd()
20201231 YYYYMMDD ymd()
20-12-31 YY-MM-DD ymd()
201231 YYMMDD ymd()

Beispiele für Datumsformate und die entsprechenden Funktionen in lubridate.

Testen wir dies, indem wir einen Data Frame mit drei Personen erstellen, einschließlich ihres Namens, ihres Geburtsdatums, des Datums der ersten Untersuchung und des Sterbedatums. Alle Datumsangaben werden unterschiedlich geschrieben, um die Funktion [ymd()](https://lubridate.tidyverse.org/reference/ymd.html) zu testen:

## Vektoren erstellen
name <- c("David", "Mohammed", "Christina")
birth_date <- ymd("1990-01-01", "1999-01-04", "2002-05-05")
examination_date <- ymd("1990.01.01", "1999.01.04", "2002.05.05")
death_date <- ymd("2005/02/02", "2009/11/14", "2018/01/01")

## Vektoren zu einem Data Frame (Tabelle) zusammenführen
my_data <- data.frame(name, birth_date, examination_date, death_date)

## Data Frame ansehen
my_data
       name birth_date examination_date death_date
1     David 1990-01-01       1990-01-01 2005-02-02
2  Mohammed 1999-01-04       1999-01-04 2009-11-14
3 Christina 2002-05-05       2002-05-05 2018-01-01

R hat also verschiedene Datumsformate erkannt und alle Vektoren in Datumsangaben umgewandelt. Die Funktion [sapply()](https://rdrr.io/r/base/lapply.html) wird verwendet, um eine Funktion auf jede Spalte eines Data Frames anzuwenden. Wir verwenden [sapply()](https://rdrr.io/r/base/lapply.html) jetzt, um zu prüfen, welche Klasse die Spalten in my_data haben:

## sapply() verwenden, um die Funktion class() auf alle Spalten in my_data anzuwenden
sapply(my_data, class)
            name       birth_date examination_date       death_date
     "character"           "Date"           "Date"           "Date"

Ändern wir die Reihenfolge von Jahr, Monat und Tag in unseren Datumsangaben. Das ist unproblematisch, solange wir die Funktion in lubridate wechseln:

## Tag, Monat, Jahr
dmy("30-01-2000", "25-12-2001")
[1] "2000-01-30" "2001-12-25"
## Monat, Tag, Jahr
mdy("12-25-1999", "09-29-2004")
[1] "1999-12-25" "2004-09-29"
## Jahr, Monat, Tag
ymd("20181230", "20191129")
[1] "2018-12-30" "2019-11-29"

Im nächsten Beispiel speichern wir ein Datum, das eine Uhrzeit enthält. Um dieses korrekt einzulesen, fügen wir die Buchstaben h (Stunde), m (Minuten) und s (Sekunden) wie folgt hinzu:

ymd_hms("2011-06-04 12:00:00")
[1] "2011-06-04 12:00:00 UTC"

R hat dem Datum die Zeitzone UTC zugewiesen. R kann etwa 600 Zeitzonen handhaben, einschließlich der Sommerzeiten, Winterzeiten und historischen Kalendervariationen der Zonen. Eine Liste aller Zeitzonen erhalten Sie, indem Sie Folgendes eingeben:

OlsonNames()
  [1] "Africa/Abidjan"                   "Africa/Accra"
  [3] "Africa/Addis_Ababa"               "Africa/Algiers"
  [5] "Africa/Asmara"                    "Africa/Asmera"
  [7] "Africa/Bamako"                    "Africa/Bangui"
  [9] "Africa/Banjul"                    "Africa/Bissau"
 [11] "Africa/Blantyre"                  "Africa/Brazzaville"
 [13] "Africa/Bujumbura"                 "Africa/Cairo"
 [15] "Africa/Casablanca"                "Africa/Ceuta"
 [17] "Africa/Conakry"                   "Africa/Dakar"
 [19] "Africa/Dar_es_Salaam"             "Africa/Djibouti"
 [21] "Africa/Douala"                    "Africa/El_Aaiun"
 [23] "Africa/Freetown"                  "Africa/Gaborone"
 [25] "Africa/Harare"                    "Africa/Johannesburg"
 [27] "Africa/Juba"                      "Africa/Kampala"
 [29] "Africa/Khartoum"                  "Africa/Kigali"
 [31] "Africa/Kinshasa"                  "Africa/Lagos"
 [33] "Africa/Libreville"                "Africa/Lome"
 [35] "Africa/Luanda"                    "Africa/Lubumbashi"
 [37] "Africa/Lusaka"                    "Africa/Malabo"
 [39] "Africa/Maputo"                    "Africa/Maseru"
 [41] "Africa/Mbabane"                   "Africa/Mogadishu"
 [43] "Africa/Monrovia"                  "Africa/Nairobi"
 [45] "Africa/Ndjamena"                  "Africa/Niamey"
 [47] "Africa/Nouakchott"                "Africa/Ouagadougou"
 [49] "Africa/Porto-Novo"                "Africa/Sao_Tome"
 [51] "Africa/Timbuktu"                  "Africa/Tripoli"
 [53] "Africa/Tunis"                     "Africa/Windhoek"
 [55] "America/Adak"                     "America/Anchorage"
 [57] "America/Anguilla"                 "America/Antigua"
 [59] "America/Araguaina"                "America/Argentina/Buenos_Aires"
 [61] "America/Argentina/Catamarca"      "America/Argentina/ComodRivadavia"
 [63] "America/Argentina/Cordoba"        "America/Argentina/Jujuy"
 [65] "America/Argentina/La_Rioja"       "America/Argentina/Mendoza"
 [67] "America/Argentina/Rio_Gallegos"   "America/Argentina/Salta"
 [69] "America/Argentina/San_Juan"       "America/Argentina/San_Luis"
 [71] "America/Argentina/Tucuman"        "America/Argentina/Ushuaia"
 [73] "America/Aruba"                    "America/Asuncion"
 [75] "America/Atikokan"                 "America/Atka"
 [77] "America/Bahia"                    "America/Bahia_Banderas"
 [79] "America/Barbados"                 "America/Belem"
 [81] "America/Belize"                   "America/Blanc-Sablon"
 [83] "America/Boa_Vista"                "America/Bogota"
 [85] "America/Boise"                    "America/Buenos_Aires"
 [87] "America/Cambridge_Bay"            "America/Campo_Grande"
 [89] "America/Cancun"                   "America/Caracas"
 [91] "America/Catamarca"                "America/Cayenne"
 [93] "America/Cayman"                   "America/Chicago"
 [95] "America/Chihuahua"                "America/Coral_Harbour"
 [97] "America/Cordoba"                  "America/Costa_Rica"
 [99] "America/Creston"                  "America/Cuiaba"
[101] "America/Curacao"                  "America/Danmarkshavn"
[103] "America/Dawson"                   "America/Dawson_Creek"
[105] "America/Denver"                   "America/Detroit"
[107] "America/Dominica"                 "America/Edmonton"
[109] "America/Eirunepe"                 "America/El_Salvador"
[111] "America/Ensenada"                 "America/Fort_Nelson"
[113] "America/Fort_Wayne"               "America/Fortaleza"
[115] "America/Glace_Bay"                "America/Godthab"
[117] "America/Goose_Bay"                "America/Grand_Turk"
[119] "America/Grenada"                  "America/Guadeloupe"
[121] "America/Guatemala"                "America/Guayaquil"
[123] "America/Guyana"                   "America/Halifax"
[125] "America/Havana"                   "America/Hermosillo"
[127] "America/Indiana/Indianapolis"     "America/Indiana/Knox"
[129] "America/Indiana/Marengo"          "America/Indiana/Petersburg"
[131] "America/Indiana/Tell_City"        "America/Indiana/Vevay"
[133] "America/Indiana/Vincennes"        "America/Indiana/Winamac"
[135] "America/Indianapolis"             "America/Inuvik"
[137] "America/Iqaluit"                  "America/Jamaica"
[139] "America/Jujuy"                    "America/Juneau"
[141] "America/Kentucky/Louisville"      "America/Kentucky/Monticello"
[143] "America/Knox_IN"                  "America/Kralendijk"
[145] "America/La_Paz"                   "America/Lima"
[147] "America/Los_Angeles"              "America/Louisville"
[149] "America/Lower_Princes"            "America/Maceio"
[151] "America/Managua"                  "America/Manaus"
[153] "America/Marigot"                  "America/Martinique"
[155] "America/Matamoros"                "America/Mazatlan"
[157] "America/Mendoza"                  "America/Menominee"
[159] "America/Merida"                   "America/Metlakatla"
[161] "America/Mexico_City"              "America/Miquelon"
[163] "America/Moncton"                  "America/Monterrey"
[165] "America/Montevideo"               "America/Montreal"
[167] "America/Montserrat"               "America/Nassau"
[169] "America/New_York"                 "America/Nipigon"
[171] "America/Nome"                     "America/Noronha"
[173] "America/North_Dakota/Beulah"      "America/North_Dakota/Center"
[175] "America/North_Dakota/New_Salem"   "America/Nuuk"
[177] "America/Ojinaga"                  "America/Panama"
[179] "America/Pangnirtung"              "America/Paramaribo"
[181] "America/Phoenix"                  "America/Port_of_Spain"
[183] "America/Port-au-Prince"           "America/Porto_Acre"
[185] "America/Porto_Velho"              "America/Puerto_Rico"
[187] "America/Punta_Arenas"             "America/Rainy_River"
[189] "America/Rankin_Inlet"             "America/Recife"
[191] "America/Regina"                   "America/Resolute"
[193] "America/Rio_Branco"               "America/Rosario"
[195] "America/Santa_Isabel"             "America/Santarem"
[197] "America/Santiago"                 "America/Santo_Domingo"
[199] "America/Sao_Paulo"                "America/Scoresbysund"
[201] "America/Shiprock"                 "America/Sitka"
[203] "America/St_Barthelemy"            "America/St_Johns"
[205] "America/St_Kitts"                 "America/St_Lucia"
[207] "America/St_Thomas"                "America/St_Vincent"
[209] "America/Swift_Current"            "America/Tegucigalpa"
[211] "America/Thule"                    "America/Thunder_Bay"
[213] "America/Tijuana"                  "America/Toronto"
[215] "America/Tortola"                  "America/Vancouver"
[217] "America/Virgin"                   "America/Whitehorse"
[219] "America/Winnipeg"                 "America/Yakutat"
[221] "America/Yellowknife"              "Antarctica/Casey"
[223] "Antarctica/Davis"                 "Antarctica/DumontDUrville"
[225] "Antarctica/Macquarie"             "Antarctica/Mawson"
[227] "Antarctica/McMurdo"               "Antarctica/Palmer"
[229] "Antarctica/Rothera"               "Antarctica/South_Pole"
[231] "Antarctica/Syowa"                 "Antarctica/Troll"
[233] "Antarctica/Vostok"                "Arctic/Longyearbyen"
[235] "Asia/Aden"                        "Asia/Almaty"
[237] "Asia/Amman"                       "Asia/Anadyr"
[239] "Asia/Aqtau"                       "Asia/Aqtobe"
[241] "Asia/Ashgabat"                    "Asia/Ashkhabad"
[243] "Asia/Atyrau"                      "Asia/Baghdad"
[245] "Asia/Bahrain"                     "Asia/Baku"
[247] "Asia/Bangkok"                     "Asia/Barnaul"
[249] "Asia/Beirut"                      "Asia/Bishkek"
[251] "Asia/Brunei"                      "Asia/Calcutta"
[253] "Asia/Chita"                       "Asia/Choibalsan"
[255] "Asia/Chongqing"                   "Asia/Chungking"
[257] "Asia/Colombo"                     "Asia/Dacca"
[259] "Asia/Damascus"                    "Asia/Dhaka"
[261] "Asia/Dili"                        "Asia/Dubai"
[263] "Asia/Dushanbe"                    "Asia/Famagusta"
[265] "Asia/Gaza"                        "Asia/Harbin"
[267] "Asia/Hebron"                      "Asia/Ho_Chi_Minh"
[269] "Asia/Hong_Kong"                   "Asia/Hovd"
[271] "Asia/Irkutsk"                     "Asia/Istanbul"
[273] "Asia/Jakarta"                     "Asia/Jayapura"
[275] "Asia/Jerusalem"                   "Asia/Kabul"
[277] "Asia/Kamchatka"                   "Asia/Karachi"
[279] "Asia/Kashgar"                     "Asia/Kathmandu"
[281] "Asia/Katmandu"                    "Asia/Khandyga"
[283] "Asia/Kolkata"                     "Asia/Krasnoyarsk"
[285] "Asia/Kuala_Lumpur"                "Asia/Kuching"
[287] "Asia/Kuwait"                      "Asia/Macao"
[289] "Asia/Macau"                       "Asia/Magadan"
[291] "Asia/Makassar"                    "Asia/Manila"
[293] "Asia/Muscat"                      "Asia/Nicosia"
[295] "Asia/Novokuznetsk"                "Asia/Novosibirsk"
[297] "Asia/Omsk"                        "Asia/Oral"
[299] "Asia/Phnom_Penh"                  "Asia/Pontianak"
[301] "Asia/Pyongyang"                   "Asia/Qatar"
[303] "Asia/Qostanay"                    "Asia/Qyzylorda"
[305] "Asia/Rangoon"                     "Asia/Riyadh"
[307] "Asia/Saigon"                      "Asia/Sakhalin"
[309] "Asia/Samarkand"                   "Asia/Seoul"
[311] "Asia/Shanghai"                    "Asia/Singapore"
[313] "Asia/Srednekolymsk"               "Asia/Taipei"
[315] "Asia/Tashkent"                    "Asia/Tbilisi"
[317] "Asia/Tehran"                      "Asia/Tel_Aviv"
[319] "Asia/Thimbu"                      "Asia/Thimphu"
[321] "Asia/Tokyo"                       "Asia/Tomsk"
[323] "Asia/Ujung_Pandang"               "Asia/Ulaanbaatar"
[325] "Asia/Ulan_Bator"                  "Asia/Urumqi"
[327] "Asia/Ust-Nera"                    "Asia/Vientiane"
[329] "Asia/Vladivostok"                 "Asia/Yakutsk"
[331] "Asia/Yangon"                      "Asia/Yekaterinburg"
[333] "Asia/Yerevan"                     "Atlantic/Azores"
[335] "Atlantic/Bermuda"                 "Atlantic/Canary"
[337] "Atlantic/Cape_Verde"              "Atlantic/Faeroe"
[339] "Atlantic/Faroe"                   "Atlantic/Jan_Mayen"
[341] "Atlantic/Madeira"                 "Atlantic/Reykjavik"
[343] "Atlantic/South_Georgia"           "Atlantic/St_Helena"
[345] "Atlantic/Stanley"                 "Australia/ACT"
[347] "Australia/Adelaide"               "Australia/Brisbane"
[349] "Australia/Broken_Hill"            "Australia/Canberra"
[351] "Australia/Currie"                 "Australia/Darwin"
[353] "Australia/Eucla"                  "Australia/Hobart"
[355] "Australia/LHI"                    "Australia/Lindeman"
[357] "Australia/Lord_Howe"              "Australia/Melbourne"
[359] "Australia/North"                  "Australia/NSW"
[361] "Australia/Perth"                  "Australia/Queensland"
[363] "Australia/South"                  "Australia/Sydney"
[365] "Australia/Tasmania"               "Australia/Victoria"
[367] "Australia/West"                   "Australia/Yancowinna"
[369] "Brazil/Acre"                      "Brazil/DeNoronha"
[371] "Brazil/East"                      "Brazil/West"
[373] "Canada/Atlantic"                  "Canada/Central"
[375] "Canada/Eastern"                   "Canada/Mountain"
[377] "Canada/Newfoundland"              "Canada/Pacific"
[379] "Canada/Saskatchewan"              "Canada/Yukon"
[381] "CET"                              "Chile/Continental"
[383] "Chile/EasterIsland"               "CST6CDT"
[385] "Cuba"                             "EET"
[387] "Egypt"                            "Eire"
[389] "EST"                              "EST5EDT"
[391] "Etc/GMT"                          "Etc/GMT-0"
[393] "Etc/GMT-1"                        "Etc/GMT-10"
[395] "Etc/GMT-11"                       "Etc/GMT-12"
[397] "Etc/GMT-13"                       "Etc/GMT-14"
[399] "Etc/GMT-2"                        "Etc/GMT-3"
[401] "Etc/GMT-4"                        "Etc/GMT-5"
[403] "Etc/GMT-6"                        "Etc/GMT-7"
[405] "Etc/GMT-8"                        "Etc/GMT-9"
[407] "Etc/GMT+0"                        "Etc/GMT+1"
[409] "Etc/GMT+10"                       "Etc/GMT+11"
[411] "Etc/GMT+12"                       "Etc/GMT+2"
[413] "Etc/GMT+3"                        "Etc/GMT+4"
[415] "Etc/GMT+5"                        "Etc/GMT+6"
[417] "Etc/GMT+7"                        "Etc/GMT+8"
[419] "Etc/GMT+9"                        "Etc/GMT0"
[421] "Etc/Greenwich"                    "Etc/UCT"
[423] "Etc/Universal"                    "Etc/UTC"
[425] "Etc/Zulu"                         "Europe/Amsterdam"
[427] "Europe/Andorra"                   "Europe/Astrakhan"
[429] "Europe/Athens"                    "Europe/Belfast"
[431] "Europe/Belgrade"                  "Europe/Berlin"
[433] "Europe/Bratislava"                "Europe/Brussels"
[435] "Europe/Bucharest"                 "Europe/Budapest"
[437] "Europe/Busingen"                  "Europe/Chisinau"
[439] "Europe/Copenhagen"                "Europe/Dublin"
[441] "Europe/Gibraltar"                 "Europe/Guernsey"
[443] "Europe/Helsinki"                  "Europe/Isle_of_Man"
[445] "Europe/Istanbul"                  "Europe/Jersey"
[447] "Europe/Kaliningrad"               "Europe/Kiev"
[449] "Europe/Kirov"                     "Europe/Kyiv"
[451] "Europe/Lisbon"                    "Europe/Ljubljana"
[453] "Europe/London"                    "Europe/Luxembourg"
[455] "Europe/Madrid"                    "Europe/Malta"
[457] "Europe/Mariehamn"                 "Europe/Minsk"
[459] "Europe/Monaco"                    "Europe/Moscow"
[461] "Europe/Nicosia"                   "Europe/Oslo"
[463] "Europe/Paris"                     "Europe/Podgorica"
[465] "Europe/Prague"                    "Europe/Riga"
[467] "Europe/Rome"                      "Europe/Samara"
[469] "Europe/San_Marino"                "Europe/Sarajevo"
[471] "Europe/Saratov"                   "Europe/Simferopol"
[473] "Europe/Skopje"                    "Europe/Sofia"
[475] "Europe/Stockholm"                 "Europe/Tallinn"
[477] "Europe/Tirane"                    "Europe/Tiraspol"
[479] "Europe/Ulyanovsk"                 "Europe/Uzhgorod"
[481] "Europe/Vaduz"                     "Europe/Vatican"
[483] "Europe/Vienna"                    "Europe/Vilnius"
[485] "Europe/Volgograd"                 "Europe/Warsaw"
[487] "Europe/Zagreb"                    "Europe/Zaporozhye"
[489] "Europe/Zurich"                    "Factory"
[491] "GB"                               "GB-Eire"
[493] "GMT"                              "GMT-0"
[495] "GMT+0"                            "GMT0"
[497] "Greenwich"                        "Hongkong"
[499] "HST"                              "Iceland"
[501] "Indian/Antananarivo"              "Indian/Chagos"
[503] "Indian/Christmas"                 "Indian/Cocos"
[505] "Indian/Comoro"                    "Indian/Kerguelen"
[507] "Indian/Mahe"                      "Indian/Maldives"
[509] "Indian/Mauritius"                 "Indian/Mayotte"
[511] "Indian/Reunion"                   "Iran"
[513] "Israel"                           "Jamaica"
[515] "Japan"                            "Kwajalein"
[517] "Libya"                            "MET"
[519] "Mexico/BajaNorte"                 "Mexico/BajaSur"
[521] "Mexico/General"                   "MST"
[523] "MST7MDT"                          "Navajo"
[525] "NZ"                               "NZ-CHAT"
[527] "Pacific/Apia"                     "Pacific/Auckland"
[529] "Pacific/Bougainville"             "Pacific/Chatham"
[531] "Pacific/Chuuk"                    "Pacific/Easter"
[533] "Pacific/Efate"                    "Pacific/Enderbury"
[535] "Pacific/Fakaofo"                  "Pacific/Fiji"
[537] "Pacific/Funafuti"                 "Pacific/Galapagos"
[539] "Pacific/Gambier"                  "Pacific/Guadalcanal"
[541] "Pacific/Guam"                     "Pacific/Honolulu"
[543] "Pacific/Johnston"                 "Pacific/Kanton"
[545] "Pacific/Kiritimati"               "Pacific/Kosrae"
[547] "Pacific/Kwajalein"                "Pacific/Majuro"
[549] "Pacific/Marquesas"                "Pacific/Midway"
[551] "Pacific/Nauru"                    "Pacific/Niue"
[553] "Pacific/Norfolk"                  "Pacific/Noumea"
[555] "Pacific/Pago_Pago"                "Pacific/Palau"
[557] "Pacific/Pitcairn"                 "Pacific/Pohnpei"
[559] "Pacific/Ponape"                   "Pacific/Port_Moresby"
[561] "Pacific/Rarotonga"                "Pacific/Saipan"
[563] "Pacific/Samoa"                    "Pacific/Tahiti"
[565] "Pacific/Tarawa"                   "Pacific/Tongatapu"
[567] "Pacific/Truk"                     "Pacific/Wake"
[569] "Pacific/Wallis"                   "Pacific/Yap"
[571] "Poland"                           "Portugal"
[573] "PRC"                              "PST8PDT"
[575] "ROC"                              "ROK"
[577] "Singapore"                        "Turkey"
[579] "UCT"                              "Universal"
[581] "US/Alaska"                        "US/Aleutian"
[583] "US/Arizona"                       "US/Central"
[585] "US/East-Indiana"                  "US/Eastern"
[587] "US/Hawaii"                        "US/Indiana-Starke"
[589] "US/Michigan"                      "US/Mountain"
[591] "US/Pacific"                       "US/Samoa"
[593] "UTC"                              "W-SU"
[595] "WET"                              "Zulu"
attr(,"Version")
[1] "2022f"

Setzen wir die Zeitzone auf GMT (Greenwich Mean Time):

ymd_hms("2011-06-04 12:00:00", tz="GMT")
[1] "2011-06-04 12:00:00 GMT"

Datumsangaben, Uhrzeiten und Zeitintervalle werden in späteren Kapiteln ausführlich behandelt.

4.1.7 Factor vector (Faktor)

Faktoren sind kategoriale Variablen wie Geschlecht, Haarfarbe, Ethnizität, Krankheitsstatus usw. Ein Faktor ist schlicht eine kategoriale Variable, die mehrere Stufen haben kann. Die Stufen können eine inhärente Ordnung haben, das ist aber nicht notwendig. Viele neue Benutzer tun sich schwer damit, factor von character zu unterscheiden. Der wichtigste praktische Unterschied besteht darin, dass R in Berechnungen fast immer factor verwendet. Ist eine Variable vom Typ character, wandelt R sie meist in einen factor um, bevor die Berechnung durchgeführt wird. Manchmal müssen Sie einen character selbst in einen factor umwandeln, was Sie mit der Funktion [as.factor()](https://rdrr.io/r/base/factor.html) tun.

my_diagnoses <- c("Cancer", "Cancer", "Heart Disease", "Heart Disease", "Heart Disease")

my_diagnoses_character <- as.character(my_diagnoses)

my_diagnoses_factor <- as.factor(my_diagnoses)

Erstellen wir für jeden Vektor eine Tabelle. Die Tabelle zeigt, wie viele Beobachtungen jede Stufe (Kategorie) hat:

table(my_diagnoses_character)
my_diagnoses_character
       Cancer Heart Disease
            2             3
table(my_diagnoses_factor)
my_diagnoses_factor
       Cancer Heart Disease
            2             3

Tabellieren (eine Tabelle erstellen) lässt sich also sowohl mit character als auch mit factor. Verwenden wir die Funktion [levels()](https://rdrr.io/r/base/levels.html), um zu sehen, welche Stufen in diesen Vektoren vorhanden sind:

levels(my_diagnoses_character)
NULL
levels(my_diagnoses_factor)
[1] "Cancer"        "Heart Disease"

Wie oben ersichtlich, hat ein character-Vektor keine levels (Stufen). Die Funktion [levels()](https://rdrr.io/r/base/levels.html) gibt NULL zurück, wenn sie auf einen character-Vektor angewendet wird. Wenden wir [levels()](https://rdrr.io/r/base/levels.html) dagegen auf einen factor an, erfahren wir, welche Stufen der Faktor hat.

Faktoren haben eine Referenzstufe (reference level)

Alle Vektoren vom Typ factor haben eine Referenzstufe (reference level). Das ist die Kategorie bzw. Stufe, mit der alle übrigen Kategorien bzw. Stufen in verschiedenen Arten von Berechnungen verglichen werden. Die Referenzstufe ist tatsächlich die erste, die ausgegeben wird, wenn Sie [levels()](https://rdrr.io/r/base/levels.html) verwenden. Die Referenzstufe des Vektors my_diagnoses_factor ist also Cancer.

Sie können die Referenzstufe eines factor ändern, und das ist häufig notwendig, wenn man deskriptive Tabellen, Grafiken und statistische Modelle erstellt. Um dies zu verstehen, verwenden wir ein Beispiel mit Krebsdaten. In einer Studie möchte man das Überleben von Patienten mit Lungenkrebs in Abhängigkeit vom Jahr der Diagnosestellung vergleichen. Ziel ist es zu klären, ob sich das Überleben im Lauf der Jahre verbessert hat, und zu diesem Zweck soll eine logistische Regression durchgeführt werden, in der alle Kalenderjahre mit dem letzten Jahr der Studie verglichen werden. Leider hat R das erste Jahr (2017) als Referenzstufe festgelegt, wie unten ersichtlich:

## Vektor mit Diagnosejahren erstellen
cancer_diagnosis_year <- c("2020", "2022", "2019", "2017", "2022")

## Den Vektor in einen factor umwandeln
cancer_diagnosis_year <- as.factor(cancer_diagnosis_year)

## Stufen prüfen. Die erste Stufe ist die Referenzstufe
levels(cancer_diagnosis_year)
[1] "2017" "2019" "2020" "2022"

Wir können dies mit der Funktion [relevel()](https://rdrr.io/r/stats/relevel.html) wie folgt ändern:

## Relevel
cancer_diagnosis_year <- relevel(cancer_diagnosis_year, "2022")

## levels erneut prüfen
levels(cancer_diagnosis_year)
[1] "2022" "2017" "2019" "2020"

4.2 Coercion (erzwungene Umwandlung)

Sie haben bereits einige Beispiele für coercion gesehen: R erzwingt bestimmte Umwandlungen von Datentypen. Die häufigste Form der coercion tritt in folgenden Szenarien auf:

  • Enthält ein Vektor ein einziges nicht numerisches Symbol bzw. Zeichen, wird der gesamte Vektor in einen Vektor vom Typ character umgewandelt, selbst wenn es sich eigentlich um einen numerischen Vektor handelt und das Zeichen bzw. Symbol versehentlich hineingeraten ist.
  • Enthält ein Vektor ausschließlich numerische Werte, wandelt R ihn in einen double um.
  • Enthält ein Vektor ausschließlich 0/1, wird er in einen double umgewandelt, auch wenn er als Vektor vom Typ logical gedacht ist.
  • Enthält ein Vektor ausschließlich TRUE/FALSE, wird er in einen logical umgewandelt.

Sie können Vektoren jederzeit mit den Funktionen [as.numeric()](https://rdrr.io/r/base/numeric.html), [as.factor()](https://rdrr.io/r/base/factor.html), [as.logical()](https://rdrr.io/r/base/logical.html), [as.character()](https://rdrr.io/r/base/character.html) umwandeln.

Mathematisch wird TRUE als 1 und FALSE als 0 interpretiert. Das lässt sich bestätigen, indem man einen Vektor mit TRUE und FALSE erstellt und mit der Funktion [sum()](https://rdrr.io/r/base/sum.html) die Summe des Vektors berechnet:

sum(c(TRUE, TRUE, FALSE, FALSE))
[1] 2

Sie können 0 und 1 wie folgt in TRUE und FALSE umwandeln:

as.logical(c(1, 0, 1, 1))
[1]  TRUE FALSE  TRUE  TRUE

Und umgekehrt:

as.numeric(c(TRUE, TRUE, FALSE, FALSE))
[1] 1 1 0 0

4.3 Attributes (Attribute)

Attribute sind zusätzliche Informationen oder Präzisierungen, die Vektoren oder Objekten hinzugefügt werden. Attribute sind in vielen Zusammenhängen nützlich. Das häufigste Attribut in R ist names, das die Namen der Elemente in einem Objekt enthält. In einem Data Frame (Tabelle) sind dies schlicht die Namen der Spalten.

4.3.1 Names

Erstellen wir einen Data Frame mit zwei Spalten (Variablen), nämlich Geschlecht und Blutdruck. Dazu erstellen wir zunächst zwei Vektoren (gender, blood_pressure), die anschließend mit der Funktion [data.frame()](https://rdrr.io/r/base/data.frame.html) zu einem Data Frame kombiniert werden:

gender <- c("Man", "Woman", "Man", "Woman")
blood_pressure <- c(140, 130, 120, 150)
my_data_frame <- data.frame(gender, blood_pressure)

Sehen wir uns unseren Data Frame an:

my_data_frame
  gender blood_pressure
1    Man            140
2  Woman            130
3    Man            120
4  Woman            150

Unser Data Frame hat 4 Zeilen und 2 Spalten (Variablen). Prüfen wir die names (Namen der Spalten) in unserem Data Frame:

names(my_data_frame)
[1] "gender"    "blood_pressure"

Es gibt zwei Namensattribute: gender und blood_pressure.

Sie können die Namen der Spalten ändern, indem Sie die Information in names durch neue Information ersetzen. Das geschieht wie folgt:

names(my_data_frame) <- c("Sex", "Pressure")
names(my_data_frame)
[1] "Sex"      "Pressure"

Glücklicherweise gibt es einfachere Methoden, um Spalten umzubenennen; diese werden in späteren Kapiteln vorgestellt.

Attribute können verwendet werden, um auf Inhalte in Objekten zu verweisen. Das bedeutet, dass Sie über das Attribut auf bestimmte Spalten eines Data Frames zugreifen können. Um auf Pressure in my_data_frame zu verweisen, verwenden Sie das Symbol $ wie folgt:

my_data_frame$Pressure
[1] 140 130 120 150

Auf dieselbe Weise können Sie eine neue Spalte erstellen. Nun erstellen wir die Spalte Pressure_Half, indem wir Pressure durch 2 teilen:

my_data_frame$Pressure_Half <- my_data_frame$Pressure/2

## Unseren Data Frame ansehen
my_data_frame
    Sex Pressure Pressure_Half
1   Man      140            70
2 Woman      130            65
3   Man      120            60
4 Woman      150            75

So lassen sich also Spalten auf Grundlage bestehender Spalten erstellen.

4.3.2 Dimensions

Prüfen wir das Attribut dim, die Abkürzung für dimension. Diese Funktion gibt die Dimensionen des Objekts zurück, bei einem Data Frame (Tabelle) also die Anzahl der Zeilen und die Anzahl der Spalten:

dim(my_data_frame)
[1] 4 3

Die Funktion [dim()](https://rdrr.io/r/base/dim.html) hat die Zahlen 4 und 3 zurückgegeben, die die Anzahl der Zeilen bzw. Spalten darstellen.

4.4 Matrix (Matrix)

Engl.: Singular = matrix, Plural = matrices.

Dt.: Singular = Matrix, Plural = Matrizen.

Eine matrix (Matrix) ist eine zweidimensionale Struktur. Matrizen erstellen Sie mit der Funktion [matrix()](https://rdrr.io/r/base/matrix.html). Diese Funktion hat die Argumente nrow (Anzahl der Zeilen) und ncol (Anzahl der Spalten), mit denen die Anzahl der Zeilen und Spalten festgelegt wird. Erstellen wir zunächst einen numerischen Vektor und anschließend daraus eine Matrix:

## Vektor mit Zahlen erstellen
my_vector <- c(1, 2, 3, 4, 5, 6)

## Den Vektor in eine Matrix mit 2 Zeilen und 3 Spalten umwandeln
my_matrix <- matrix(my_vector, nrow=2, ncol=3)

## Die Matrix ansehen
my_matrix
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

Die Funktion matrix() füllt die Matrix von oben nach unten, jeweils eine Spalte nach der anderen. Mit dem Argument byrow=TRUE können Sie dieses Verhalten so ändern, dass stattdessen jeweils eine Zeile nach der anderen gefüllt wird:

my_matrix <- matrix(my_vector, nrow=2, ncol=3, byrow=TRUE)

## Die Matrix ansehen
my_matrix
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6

Eine Matrix kann nur einen einzigen Vektortyp enthalten. Das ist der große Unterschied zwischen Matrizen und Data Frames. Ein Data Frame kann alle Vektortypen enthalten (factor, character, numeric, double, integer usw.).

4.5 Array

Ein Array kann mehr als zwei Dimensionen haben. Ein Array lässt sich somit als Objekt betrachten, das mehrere separate Matrizen enthält. Die Funktion [array()](https://rdrr.io/r/base/array.html) verwendet das Argument dim, um die Struktur des Arrays festzulegen. Um ein Array mit 2 Zeilen, 2 Spalten und 3 Dimensionen zu erstellen, verwenden Sie folgenden Befehl:

my_vector <- c(1, 2, 3, 4, 5, 6)
my_array <- array(my_vector, dim=c(2, 2, 2))

## View my_array
my_array
, , 1
     [,1] [,2]
[1,]    1    3
[2,]    2    4
, , 2
     [,1] [,2]
[1,]    5    1
[2,]    6    2

Ist ein Array größer als die Anzahl der Elemente in dem Vektor, auf dem es basiert, wird der Vektor wiederverwendet, wie das obige Beispiel zeigt (die Zahlen 1 und 2 wurden in der zweiten Spalte der zweiten Matrix wiederverwendet).

4.6 Lists (Listen)

Listen sind leistungsfähige Objekte, da sie alle Arten von Objekten speichern können. Eine Liste kann also gleichzeitig mehrere Vektoren, Data Frames, Matrizen und Arrays enthalten. Die Objekte dürfen sogar unterschiedlich lang sein! Listen werden mit der Funktion [list()](https://rdrr.io/r/base/list.html) erstellt. Erstellen wir eine Liste mit je einem Vektor vom Typ character, numeric und logical (beachten Sie, dass die Vektoren unterschiedlich lang sind):

## Numerischer Vektor
my_numbers <- c(1, 2, 3)

## Character-Vektor
my_characters <- c("Diabetes", "Cancer", "AIDS", "Heart failure", "Arthritis", "Depression")

## Logical-Vektor
my_bools <- c(TRUE, TRUE, FALSE, TRUE)

## Die Vektoren zu einer Liste kombinieren
my_list <- list(my_numbers, my_characters, my_bools)

## Die Liste ansehen
my_list
[[1]]
[1] 1 2 3
[[2]]
[1] "Diabetes"      "Cancer"        "AIDS"          "Heart failure"
[5] "Arthritis"     "Depression"
[[3]]
[1]  TRUE  TRUE FALSE  TRUE

Beachten Sie oben Folgendes:

  • Die Vektoren, die in einer Liste gespeichert werden, können unterschiedliche Länge und unterschiedliche Datentypen haben.
  • Aus der obigen Ausgabe geht hervor, dass die Liste 3 Objekte enthält, gekennzeichnet durch [1[1], [2[2] und [3[3]. Um auf Objekte in einer Liste zu verweisen, verwendet man also doppelte eckige Klammern.

Eine Liste kann sogar einen Data Frame enthalten. Erweitern wir das obige Beispiel um einen Data Frame und geben anschließend die Liste aus:

## Numerischer Vektor
my_numbers <- c(1, 2, 3)

## Character-Vektor
my_characters <- c("Diabetes", "Cancer", "AIDS", "Heart failure", "Arthritis", "Depression")

## Logical-Vektor
my_bools <- c(TRUE, TRUE, FALSE, TRUE)

## Data frame
age <- c(1, 2, 3, 4)
sex <- c("male", "female", "male", "female")
my_data_frame <- data.frame(age, sex)

## Alles zu einer Liste kombinieren
my_list <- list(my_numbers, my_characters, my_bools, my_data_frame)

## Die Liste ansehen
my_list
[[1]]
[1] 1 2 3
[[2]]
[1] "Diabetes"      "Cancer"        "AIDS"          "Heart failure"
[5] "Arthritis"     "Depression"
[[3]]
[1]  TRUE  TRUE FALSE  TRUE
[[4]]
  age    sex
1   1   male
2   2 female
3   3   male
4   4 female

Das erste Listenobjekt ([1[1]) speichert die Werte 1, 2 und 3. Das zweite Listenobjekt ([2[2]) speichert die Zeichenketten Diabetes, Cancer, AIDS usw.

Listen sind sehr flexibel; sie können sogar andere Listen enthalten. Es folgt ein Beispiel:

## Create atomic vector
my_numbers <- c(1, 2, 3)

## Create a list
my_first_list <- list(c("A", "B", "C"), c(100, 200, 300))

## Create a list storing both an atomic vector and a list
my_second_list <- list(my_numbers, my_first_list)

## View my list
my_second_list
[[1]]
[1] 1 2 3
[[2]]
[[2]][[1]]
[1] "A" "B" "C"
[[2]][[2]]
[1] 100 200 300

Nun sehen Sie, dass das neue Objekt drei Zeilen, aber nur zwei Objekte enthält; das zweite Objekt ([2[2]) ist jedoch eine Liste und enthält zwei Objekte. Es ist wichtig zu beachten, dass eine Liste alle Arten von R-Objekten enthalten kann, was Listen für die Speicherung von Daten nützlich macht.

4.7 Data frames

Wir haben in den obigen Beispielen bereits mehrere Data Frames gesehen. Ein Data Frame ähnelt einem Tabellenblatt in Excel oder Numbers. Ein typischer Data Frame enthält in jeder Zeile Beobachtungen, und die Spalten bilden die Variablen:

Name Alter Einkommen Bildung Cholesterin
Adam 45 324211 Hochschule 4.5
Zara 51 198765 Grundschule 7.6
John 49 250643 Gymnasium 3.2

Beispiel für einen Data Frame.

In den meisten Fällen bilden die Zeilen die Beobachtungen und die Spalten die Messwerte (Variablen) zu diesen Beobachtungen. Statistische Modelle, Machine Learning und andere gängige Funktionen in R setzen häufig voraus, dass die Daten in einem Data Frame vorliegen. Nun erstellen wir drei Vektoren und kombinieren sie zu einem Data Frame.

## Erstellt einen Vektor mit den Zahlen 1 bis 15
variable1 <- 1:15

## Verwendet die Funktion rnorm(), um 15 völlig zufällige Werte zu erzeugen
variable2 <- rnorm(15)

## Erstellt einen Vektor mit 15 Buchstaben </em>
variable3 <- c("A", "B", "W", "C", "D", "E", "A", "B", "C", "D", "E", "U", "O", "L", "E")

## Kombiniert alles mit der Funktion data.frame() zu einem Data Frame
my_data_frame <- data.frame(variable1, variable2, variable3)

## Unseren Data Frame ansehen
my_data_frame
   variable1   variable2 variable3
1          1  0.61687819         A
2          2 -1.49693238         B
3          3 -0.02426337         W
4          4  0.97459121         C
5          5 -1.03211448         D
6          6 -0.57205032         E
7          7 -0.30575213         A
8          8 -0.77495326         B
9          9 -0.67784625         C
10        10  0.50121613         D
11        11  1.23014030         E
12        12 -1.84284583         U
13        13  0.16945138         O
14        14  0.91849363         L
15        15  0.69476883         E

Jede Spalte in unserem Data Frame enthält denselben Datentyp, und die Vektoren haben dieselbe Länge. Haben die Vektoren nicht dieselbe Länge, recycelt R den kürzeren Vektor, um einen Data Frame zu erstellen.

Warum so umständlich?

In den obigen Beispielen haben wir Vektoren und Data Frames manuell erstellt. Das ist zweifellos zeitaufwendig und umständlich. In der Praxis werden Sie höchstwahrscheinlich einen fertigen Data Frame importieren, den Sie anschließend analysieren. Wir haben Vektoren und Data Frames dennoch manuell erstellt, um zu demonstrieren, wie R sich verhält.

Prüfen wir die Struktur unseres Data Frames mithilfe der Funktion [str()](https://rdrr.io/r/utils/str.html):

str(my_data_frame)
'data.frame':   15 obs. of  3 variables:
 $ variable1: int  1 2 3 4 5 6 7 8 9 10 ...
 $ variable2: num  0.6169 -1.4969 -0.0243 0.9746 -1.0321 ...
 $ variable3: chr  "A" "B" "W" "C" ...

Demnach ist das Objekt vom Typ ‘data.farme’, mit 15 Beobachtungen und 3 Variablen. Daraus geht hervor, dass variable1 vom Typ integer ist, variable2 numeric und variable3 character. Beim Erstellen eines Data Frames können Sie mit dem Argument stringsAsFactors festlegen, ob R character-Vektoren in factors umwandeln soll, und zwar wie folgt:

my_data_frame <- data.frame(variable1, variable2, variable3, stringsAsFactors = TRUE)
str(my_data_frame)
'data.frame':   15 obs. of  3 variables:
 $ variable1: int  1 2 3 4 5 6 7 8 9 10 ...
 $ variable2: num  0.6169 -1.4969 -0.0243 0.9746 -1.0321 ...
 $ variable3: Factor w/ 9 levels "A","B","C","D",..: 1 2 9 3 4 5 1 2 3 4 ...

Nun ist variable3 ein factor mit 9 levels (Stufen).

Symbol eines Programmfensters mit drei farbigen Schaltflächen und grünen Codezeilen auf dunklem Hintergrund

Data Frame = df

Es ist üblich, Data Frame mit df abzukürzen. Diese Abkürzung werden Sie bei der Arbeit mit R häufig sehen.