GNU R: rbind
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
undnumeric
). - Der Befehl
c
definiert hingegen eine Liste, die nur einen Mode haben kann. Innerhalb unseres Ausdrucks "
" sind jedoch die modesc
("Jörg", "maennlich", "blau", 18000)character
(zu erkennen an den Anführungszeichen) undnumeric
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 Typcharacter
- 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 nochnumeric
. Durch den oben verwendetenrbind
-Ausdruck wird eine Variable vom Typcharacter
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]