10  Umgang mit Datensätzen

Mit der Funktion str() (für structure) erhalten wir eine erste Beschreibung des Datensatzes.

# Übersicht von "MeinDatenframe" 
str(MeinDatenframe)
## 'data.frame':    12 obs. of  4 variables:
##  $ geschlecht: Factor w/ 3 levels "d","m","w": 2 3 1 2 3 1 2 3 1 2 ...
##  $ spitzname : chr  "Hasi" "Ide" "Momsi" "Ryu" ...
##  $ hausnummer: int  1 2 3 4 5 6 7 8 9 10 ...
##  $ angemeldet: logi  TRUE TRUE FALSE TRUE FALSE FALSE ...

Das Datenframe MeinDatenframe enthält 12 Beobachtungen von 4 Variablen. Varibale geschlecht ist ein Faktor mit 3 Ausprägungen, usw.

In RStudio werden diese Informationen im Datenfenster angezeigt (Abbildung 10.1).

Abb. 10.1: str() im Datenfenster

Mit der Funktion head() können Sie sich einen weiteren Überblick über den Datensatz verschaffen. Die Funktion head() gibt die ersten 6 Zeilen des Datensatzes aus.

# zeige die ersten 6 Reihen von "MeinDatenframe"
head(MeinDatenframe)
##       geschlecht spitzname hausnummer angemeldet
## Eins           m      Hasi          1       TRUE
## Zwei           w       Ide          2       TRUE
## Drei           d     Momsi          3      FALSE
## Vier           m       Ryu          4       TRUE
## Fünf           w      Dave          5      FALSE
## Sechs          d      Zoid          6      FALSE

Möchten wir mehr als 6 Einträge sehen, können wir dies an head() übergeben:

# zeige die ersten 10 Reihen von "MeinDatenframe"
head(MeinDatenframe, 10)
##        geschlecht spitzname hausnummer angemeldet
## Eins            m      Hasi          1       TRUE
## Zwei            w       Ide          2       TRUE
## Drei            d     Momsi          3      FALSE
## Vier            m       Ryu          4       TRUE
## Fünf            w      Dave          5      FALSE
## Sechs           d      Zoid          6      FALSE
## Sieben          m       Adu          7      FALSE
## Acht            w       Efi          8       TRUE
## Neun            d       Ole          9       TRUE
## Zehn            m       Ray         10       TRUE

Im Gegensatz dazu zeigt tail() die letzten Reihen des Datenframes an.

# zeige die letzten 5 Reihen von "MeinDatenframe"
tail(MeinDatenframe, 5)
##       geschlecht spitzname hausnummer angemeldet
## Acht           w       Efi          8       TRUE
## Neun           d       Ole          9       TRUE
## Zehn           m       Ray         10       TRUE
## Elf            w       Sam         11      FALSE
## Zwölf          d       Emi         12       TRUE

10.1 Sortieren

Mit der Funktion sort() können Datenreihen auf- und absteigend sortiert werden. Standardmäßig wird aufsteigend sortiert

# sortiere "hausnummer" von "MeinDatenframe" 
# aufsteigend
sort(MeinDatenframe$hausnummer)
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12

Um absteigend zu sortieren, muss der Parameter decreasing auf TRUE gesetzt werden

# sortiere "spitzname" von "MeinDatenframe"
# absteigend
sort(MeinDatenframe$spitzname, decreasing=T)
##  [1] "Zoid"  "Sam"   "Ryu"   "Ray"   "Ole"   "Momsi" "Ide"   "Hasi"  "Emi"  
## [10] "Efi"   "Dave"  "Adu"

Mit der Funktion order() werden die Zeilenpositionen ausgegeben, an deren Stelle sich die von sort() sortierten Daten befinden.

# sortiere "spitznamen" von "MeinDatenframe" 
# aufsteigend, und zeige Positionen an 
order(MeinDatenframe$spitzname)
##  [1]  7  5  8 12  1  2  3  9 10  4 11  6

Das kann man nun verwenden, um den kompletten Datensatz in dieser Ordnung anzuzeigen. Wir können ja durch Anhängen von eckigen Klammern die gewünschten Zeilen und Spalten des Datenframes referenzieren. Also übergeben wir die Positionsreihenfolge von order() als Argument in die eckige Klammer.

# sortiere "spitznamen" von "MeinDatenframe" 
# aufsteigend, zeige ganzes Datenframe an
MeinDatenframe[ order(MeinDatenframe$spitzname), ]
##        geschlecht spitzname hausnummer angemeldet
## Sieben          m       Adu          7      FALSE
## Fünf            w      Dave          5      FALSE
## Acht            w       Efi          8       TRUE
## Zwölf           d       Emi         12       TRUE
## Eins            m      Hasi          1       TRUE
## Zwei            w       Ide          2       TRUE
## Drei            d     Momsi          3      FALSE
## Neun            d       Ole          9       TRUE
## Zehn            m       Ray         10       TRUE
## Vier            m       Ryu          4       TRUE
## Elf             w       Sam         11      FALSE
## Sechs           d      Zoid          6      FALSE

Oder andersherum

# sortiere "spitznamen" von "MeinDatenframe" 
# absteigend, zeige ganzes Datenframe an 
MeinDatenframe[order(MeinDatenframe$spitzname, decreasing=T), ]
##        geschlecht spitzname hausnummer angemeldet
## Sechs           d      Zoid          6      FALSE
## Elf             w       Sam         11      FALSE
## Vier            m       Ryu          4       TRUE
## Zehn            m       Ray         10       TRUE
## Neun            d       Ole          9       TRUE
## Drei            d     Momsi          3      FALSE
## Zwei            w       Ide          2       TRUE
## Eins            m      Hasi          1       TRUE
## Zwölf           d       Emi         12       TRUE
## Acht            w       Efi          8       TRUE
## Fünf            w      Dave          5      FALSE
## Sieben          m       Adu          7      FALSE

10.2 Teilgruppen erstellen

Mit der Funktion subset() können Teilgruppen aus einem Datenframe erstellt werden.

# erstelle eine Teilgruppe aus MeinDatenframe
# für "geschlecht" = d
subset(MeinDatenframe, geschlecht=="d")
##       geschlecht spitzname hausnummer angemeldet
## Drei           d     Momsi          3      FALSE
## Sechs          d      Zoid          6      FALSE
## Neun           d       Ole          9       TRUE
## Zwölf          d       Emi         12       TRUE

Über den Parameter select kann angegeben werden, welche Spalten übernommen werden sollen.

# erstelle eine Teilgruppe aus MeinDatenframe
# für "geschlecht" = d
# aber nur Spalte "spitzname" und "angemeldet"
subset(MeinDatenframe, geschlecht=="d", select = c(spitzname, angemeldet))
##       spitzname angemeldet
## Drei      Momsi      FALSE
## Sechs      Zoid      FALSE
## Neun        Ole       TRUE
## Zwölf       Emi       TRUE

Eine andere Möglichkeit zur Erstellung von Teilgruppen kann über die Referenzierung der Zeilen und Spalten des Datenframes (eckige Klammern) erfolgen

# erstelle eine Teilgruppe aus MeinDatenframe
# für "geschlecht" = w
MeinDatenframe[ MeinDatenframe$geschlecht == "w", ]
##      geschlecht spitzname hausnummer angemeldet
## Zwei          w       Ide          2       TRUE
## Fünf          w      Dave          5      FALSE
## Acht          w       Efi          8       TRUE
## Elf           w       Sam         11      FALSE

Auf diese Weise können die Bedingungen auch mit einem & kombiniert werden

# erstelle eine Teilgruppe aus MeinDatenframe 
# für "geschlecht" = w und "hausnummer" größer 5 
MeinDatenframe[(MeinDatenframe$geschlecht == "w") & (MeinDatenframe$hausnummer > 5) ,]
##      geschlecht spitzname hausnummer angemeldet
## Acht          w       Efi          8       TRUE
## Elf           w       Sam         11      FALSE

Über Angabe der Spaltennummern können wir das Teilset noch weiter zusammenschrumpfen lassen

# erstelle eine Teilgruppe aus MeinDatenframe 
# für "geschlecht" = w und "angemeldet" = TRUE 
# aber nur Spalte "spitzname" und "hausnummer"
MeinDatenframe[(MeinDatenframe$geschlecht == "w") & (MeinDatenframe$angemeldet== T), c(2,3)]
##      spitzname hausnummer
## Zwei       Ide          2
## Acht       Efi          8

Möchte man auf die Referenzierung per Dollarzeichen $ verzichten, kann die Funktion with() verwendet werden.

# with() macht es leichter 
with(MeinDatenframe, MeinDatenframe[(geschlecht == "w") & (angemeldet == T), c(2,3)])
##      spitzname hausnummer
## Zwei       Ide          2
## Acht       Efi          8

10.3 Klassen für Variablen bilden (klassieren)

Angenommen, eine Variable enthält Werte zwischen 0 und 500, und wir möchten diese Werte in die Gruppen “0-70”, “71-200”, “201-400”, “>400” klassieren.

Erstellen wir zunächst zufällige Zahlen zwischen 0 und 500.

# erzeuge 200 Zufallszahlen von 0 bis 500
dummy <- sample(0:500, 200)
# bzw. direkt als Dataframe
dummy <- data.frame(x = sample(0:500, 200))

Nun erzeugen wir die neue Variable xKAT, in welcher die Klassierung angegeben werden soll. Dies kann auf mehreren Wegen erfolgen.

10.3.1 Klassieren “von Hand”

Zunächst erzeugen wir die Kategorien “von Hand”.

# wir bilden Kategorien
#      "0-70"
#      "71-200"
#      "201-400"
#      "> 400"
# und speichern das in die neue Variable xKAT
dummy$xKAT[dummy$x <71] <- "0-70"
dummy$xKAT[dummy$x <201 & dummy$x > 70] <- "71-200"
dummy$xKAT[dummy$x <401 & dummy$x > 200] <- "201-400"
dummy$xKAT[dummy$x >400] <- "größer 400"

Anschließend wandeln wir die neue Variable in einen ordinalen Faktor mit korrekter Levelreihenfolge.

dummy$xKAT <- factor(dummy$xKAT, levels=c("0-70",
                                    "71-200",
                                    "201-400",
                                    "größer 400"),
                       ordered=TRUE)
head(dummy$xKAT)
## [1] 201-400 0-70    201-400 201-400 0-70    0-70   
## Levels: 0-70 < 71-200 < 201-400 < größer 400

10.3.2 Klassieren mittels cut()

Mit Hilfe der cut()-Funktion kann die Klassierung ebenfalls vorgenommen werden. Sie unterteilt kontinuierliche (numerische) Werte in Kategorien oder Intervalle. Über den Parameter breaks können die Klassengrenzen festgelegt werden.

# bilde Klassen mittels "cut()"
cut(dummy$x, breaks=c(0, 70, 200, 400, Inf))
##   [1] (200,400] (0,70]    (200,400] (200,400] (0,70]    (0,70]    (200,400]
##   [8] (70,200]  (70,200]  (0,70]    (200,400] (200,400] (200,400] (200,400]
##  [15] (400,Inf] (0,70]    (400,Inf] (200,400] (70,200]  (0,70]    (200,400]
##  [22] (0,70]    (200,400] (400,Inf] (0,70]    (70,200]  (200,400] (70,200] 
##  [29] (200,400] (70,200]  (0,70]    (70,200]  (70,200]  (200,400] (400,Inf]
##  [36] (70,200]  (0,70]    (0,70]    (200,400] (70,200]  (400,Inf] (70,200] 
##  [43] (0,70]    (70,200]  (200,400] (200,400] (200,400] (200,400] (200,400]
##  [50] (70,200]  (70,200]  (400,Inf] (200,400] (400,Inf] (200,400] (0,70]   
##  [57] (200,400] (400,Inf] (70,200]  (200,400] (200,400] (70,200]  (200,400]
##  [64] (200,400] (70,200]  (400,Inf] (200,400] (0,70]    (200,400] (400,Inf]
##  [71] (400,Inf] (200,400] (70,200]  (400,Inf] (200,400] (200,400] (70,200] 
##  [78] (70,200]  (0,70]    (0,70]    (70,200]  (0,70]    (200,400] (70,200] 
##  [85] (70,200]  (0,70]    (200,400] (70,200]  (200,400] (70,200]  (400,Inf]
##  [92] (200,400] (400,Inf] (70,200]  (200,400] (400,Inf] (0,70]    (70,200] 
##  [99] (0,70]    (200,400] (0,70]    (200,400] (200,400] (400,Inf] (70,200] 
## [106] (200,400] (70,200]  (0,70]    (200,400] (400,Inf] (70,200]  (70,200] 
## [113] (70,200]  (400,Inf] (400,Inf] (70,200]  (0,70]    (200,400] (70,200] 
## [120] (200,400] (400,Inf] (200,400] (70,200]  (400,Inf] (200,400] (70,200] 
## [127] (70,200]  (0,70]    (70,200]  (400,Inf] (0,70]    (0,70]    (200,400]
## [134] (400,Inf] (400,Inf] (0,70]    (70,200]  (200,400] (0,70]    (200,400]
## [141] (70,200]  (0,70]    (70,200]  (200,400] (0,70]    (70,200]  (200,400]
## [148] (70,200]  (200,400] (70,200]  (70,200]  (400,Inf] (400,Inf] (0,70]   
## [155] (0,70]    (200,400] (200,400] (400,Inf] (0,70]    (200,400] (400,Inf]
## [162] (200,400] (200,400] (200,400] (200,400] (0,70]    (200,400] (200,400]
## [169] (200,400] (400,Inf] (70,200]  (0,70]    (400,Inf] (200,400] (0,70]   
## [176] (0,70]    (400,Inf] (200,400] (200,400] (400,Inf] (200,400] (200,400]
## [183] (200,400] (200,400] (0,70]    (200,400] (200,400] (200,400] (200,400]
## [190] (200,400] (200,400] (400,Inf] (70,200]  (200,400] (200,400] (400,Inf]
## [197] (70,200]  (70,200]  (400,Inf] (400,Inf]
## Levels: (0,70] (70,200] (200,400] (400,Inf]

Die erzeugten Werte werden als Factor wiedergegeben. Die Factorlevels entsprechen dabei den Kategorien (Klassen). Die cut()-Funktion benennt die Klassen mit der üblichen “(]”-Notation. Die eckigen Klammern geben an, dass die nebenstehende Zahl in der Klasse eingeschlossen wird. Runde Klammern hingegen schließen die nebenstehende Zahl aus.

  • Eine Klasse mit der Notation (10,20] schließt die \(10\) nicht mit ein, sondern jede höhere Zahl. Sie endet bei der Zahl \(20\), wobei \(20\) in der Klasse enthalten ist.
  • Eine Klasse mit der Notation [10,20) schließt die \(10\) mit ein. Sie endet bei der Zahl \(20\), wobei \(20\) nicht in der Klasse enthalten ist, sondern zur nächst-höheren Klasse zählt.

Über den Parameter right kann bestimmt werden, ob die Zahlen an der rechten Klassengrenze mit eingeschlossen werden sollen, oder nicht.

# erzeuge Dummy-Werte
x <- 1:20

# cut-Beispiele für Parameter "right"
# die rechte Grenze wird mit eingeschlossen. Entspricht "(]"
cut(x, breaks=c(0,5,10,15,20))
##  [1] (0,5]   (0,5]   (0,5]   (0,5]   (0,5]   (5,10]  (5,10]  (5,10]  (5,10] 
## [10] (5,10]  (10,15] (10,15] (10,15] (10,15] (10,15] (15,20] (15,20] (15,20]
## [19] (15,20] (15,20]
## Levels: (0,5] (5,10] (10,15] (15,20]
# die rechte Grenze wird NICHT mit eingeschlossen. Entspricht "[)"
cut(x, breaks=c(0,5,10,15,20),
    right=FALSE)
##  [1] [0,5)   [0,5)   [0,5)   [0,5)   [5,10)  [5,10)  [5,10)  [5,10)  [5,10) 
## [10] [10,15) [10,15) [10,15) [10,15) [10,15) [15,20) [15,20) [15,20) [15,20)
## [19] [15,20) <NA>   
## Levels: [0,5) [5,10) [10,15) [15,20)

Über den Parameter labels können eigene Bezeichnungen für die Klassen gesetzt werden.

cut(x, breaks=c(0,5,10,15,20),
    labels=c("0 bis 5", "6 bis 10", "11 bis 15", "16 bis 20"))
##  [1] 0 bis 5   0 bis 5   0 bis 5   0 bis 5   0 bis 5   6 bis 10  6 bis 10 
##  [8] 6 bis 10  6 bis 10  6 bis 10  11 bis 15 11 bis 15 11 bis 15 11 bis 15
## [15] 11 bis 15 16 bis 20 16 bis 20 16 bis 20 16 bis 20 16 bis 20
## Levels: 0 bis 5 6 bis 10 11 bis 15 16 bis 20

Auch hier kann man sich etwas Schreibarbeit sparen. Wir speichern die Klassengrenzen in das Objekt mybreaks. Innerhalb des labels-Parameter greifen wir darauf zurück. Für die unteren Grenzen nehmen wir die mybreaks-Einträge (ohne den letzten) und addieren jeweils \(1\). Für die oberen Grenzen nehmen wir mybreaks ohne den ersten Eintrag. Mittels paste() können die Grenzwerte aneinander geklebt werden.

# erzeuge eigenes Objekt für "breaks"
mybreaks <- c(0,5,10,15,20)

# eigene Klassenbezeichnung
cut(x, breaks=mybreaks,
    labels = paste(mybreaks[-length(mybreaks)]+1, "bis", mybreaks[-1]))
##  [1] 1 bis 5   1 bis 5   1 bis 5   1 bis 5   1 bis 5   6 bis 10  6 bis 10 
##  [8] 6 bis 10  6 bis 10  6 bis 10  11 bis 15 11 bis 15 11 bis 15 11 bis 15
## [15] 11 bis 15 16 bis 20 16 bis 20 16 bis 20 16 bis 20 16 bis 20
## Levels: 1 bis 5 6 bis 10 11 bis 15 16 bis 20

Über den Parameter ordered_result kann die Ausgabe als ordinaler Factor erfolgen.

cut(x, breaks=mybreaks,
    labels = paste(mybreaks[-length(mybreaks)]+1, "bis", mybreaks[-1]),
    ordered_result = TRUE)
##  [1] 1 bis 5   1 bis 5   1 bis 5   1 bis 5   1 bis 5   6 bis 10  6 bis 10 
##  [8] 6 bis 10  6 bis 10  6 bis 10  11 bis 15 11 bis 15 11 bis 15 11 bis 15
## [15] 11 bis 15 16 bis 20 16 bis 20 16 bis 20 16 bis 20 16 bis 20
## Levels: 1 bis 5 < 6 bis 10 < 11 bis 15 < 16 bis 20