Zum Inhalt springen

GNU R: rbind

Aus Wikibooks


Mit rbind(a,b,c) lassen sich die Vektoren a, b und c zeilenweise zu einer Matrix zusammenführen. Im Gegensatz dazu verbindet cbind() die Vektoren spaltenweise zu einer Matrix.

Handhabung

[Bearbeiten]

Zunächst erzeugen wir drei Vektoren:

a <- c(1,2,3,4)
b <- c(-1,-2,-3,-4)
c <- c(99,88,77,66)

Diese führen wir nun per rbind zu einer Matrix zusammen, wobei jeder Vektor einer Zeile entspricht:

mymatrix <- rbind(a,b,c)
rm(a,b,c) # Vektoren löschen

Die Matrix mymatrix sieht nun wie folgt aus:

mymatrix
  [,1] [,2] [,3] [,4]
a    1    2    3    4
b   -1   -2   -3   -4
c   99   88   77   66

Mit Hilfe von dimnames() oder colnames() und rownames() können nun noch die Zeilennamen (derzeit: a, b, c) und Spaltennamen (derzeit: [,1] [,2] [,3]) verschönert werden.


Einem Objekt eine weitere Zeile hinzufügen

[Bearbeiten]

Per rbind können nun auch weitere Zeilen der Matrix mymatrix zugeordnet werden:

mymatrix <- rbind(mymatrix, c(0, 8, 15, 23))

Nun sieht es wie folgt aus:

> mymatrix
  [,1] [,2] [,3] [,4]
a    1    2    3    4
b   -1   -2   -3   -4
c   99   88   77   66
     0    8   15   23

Einem Datenframe eine weitere Zeile hinzufügen

[Bearbeiten]

Will man einem Datenframe per rbind eine weitere Zeile hinzufügen, muss ein wenig "Vorarbeit" geleistet werden. Zur besseren Erklärung verwenden wir folgendes Datenframe:

myframe <- structure(list(Name = c("Caro",  "Hans", "Ines", "Lars", "Peter", "Samira", "Sarah"),      
             Geschlecht = structure(c(2L, 3L, 1L, 3L, 3L, 2L, 3L), .Label = c("intersexuell", "maennlich", "weiblich"), class = "factor"), 
             Lieblingsfarbe = structure(c(3L, 1L, 2L, 4L, 2L, 3L, 1L), .Label = c("blau", "gelb", "gruen", "schwarz"), class = "factor"), 
             Einkommen = c(1233, 800, 2400, 4000, 899, 1100, 1900)), .Names = c("Name", "Geschlecht",  "Lieblingsfarbe", "Einkommen"),
             row.names = c(NA, -7L), class = "data.frame")

Diesem soll nun die folgende Zeile hinzugefügt werden:

Jörg    maennlich    blau   18000

Die vielleicht denkbare Methode

myframe <- rbind(myframe, c("Jörg", "maennlich", "blau", 18000)) # liefert NICHT das gewünschte Resultat!!!

liefert nur auf den ersten Blick hin das gewünschte Resultat. Die Zeile ist zwar dem Frame hinzugefügt worden, aber die Struktur des Frames wurde "zerschossen". Dies wird sichtbar, wenn wir versuchen, mit den Werten der Spalte "Einkommen" zu rechnen. Versuchen wir mal, das jeweilige Einkommen mit 12 zu multiplizieren:

myframe$Einkommen * 12

Dieser Befehl schlägt fehl, und die Fehlermeldung sagt uns, dass es sich bei der Spalte "Einkommen" nicht mehr um numerische Werte handelt. Und tatsächlich,

class(myframe$Einkommen)

liefert als Antwort "Character". Schuld daran ist die Funktion c, mit derer wir die neue Zeile innerhalb des rbind-Befehls angegeben haben.

  • Unser Datenframe ist eine Liste mit Variablen unterschiedlicher modes (character, factor und numeric).
  • Der Befehl c definiert hingegen eine Liste, die nur einen Mode haben kann. Innerhalb unseres Ausdrucks "c("Jörg", "maennlich", "blau", 18000)" sind jedoch die modes character (zu erkennen an den Anführungszeichen) und numeric enthalten.
  • Da dies nicht geht, ermittelt R automatisch einen "Gesamt"-Mode aus dem komplexesten Vektorelement, in diesem Fall "character".
  • Somit sind alle Werte innerhalb des c-Ausdrucks vom Typ character
  • Durch die Verknüpfung mit dem Datenframe myframe geschieht dieser Prozess nun erneut: Die Spalte "Einkommen" kann auch nur einen Mode besitzen. Zunächst ist dieser noch numeric. Durch den oben verwendeten rbind-Ausdruck wird eine Variable vom Typ character hinzugefügt.
  • Da dies auch hier wieder nicht geht, ermittelt R wieder automatisch einen "Gesamt"-Mode aus dem komplexesten Vektorelement für die Spalte "Einkommen", in diesem Fall wieder "character".


Die Lösung:

Und wie geht das dann?

Wir verwenden zunächst an Stelle von c die Funktion data.frame, da hier sehr wohl unterschiedliche modi verwendet werden dürfen.

myframe <- rbind(myframe, data.frame("Jörg", "maennlich", "blau", 18000)) # geht auch nicht :(

Der Befehl schlägt mit der Fehlermeldung fehl, die Spalten-Namen würden nicht zueinander passen. Dies umgeht man wie folgt:

# DIE ungeschickte LÖSUNG:
neue.zeile <- data.frame("Jörg", "maennlich", "blau", 18000)
colnames(neue.zeile) <- colnames(myframe)
myframe <- rbind(myframe, neue.zeile)

Diese Methode erfordert aber unnötig Rechen- und Speicherkapazität. Geschickter ist es, direkt auf den von R rückgemeldeten Fehler "die Spalten-Namen passen nicht zusammen" zu reagieren. Wenn man nämlich der neuen Reihe die Namen direkt mitgibt, etwa so:

 # Die geschickte Lösung
 myframe <- rbind(myframe, data.frame(Name="Jörg", Geschlecht="maennlich", Lieblingsfarbe="blau", Einkommen=18000))

dann funktioniert das auch. Dann ist auch die Reihenfolge völlig egal, und auch dieser Befehl:

 myframe <- rbind(myframe, data.frame(Geschlecht="maennlich", Name="Jörg", Einkommen=18000, Lieblingsfarbe="blau"))

liefert das selbe Ergebnis.

Probleme mit "POSIXct" "POSIXt"

[Bearbeiten]

Enthält das Datenframe eine Variable vom Typ "POSIXct" oder "POSIXt", schlagen rbind und cbind mit folgender Fehlermeldung fehl:

In names(value[[jj]])[ri] <- nm :
  Anzahl der zu ersetzenden Elemente ist kein Vielfaches der Ersetzungslänge


siehe auch

[Bearbeiten]