GNU R: Umgang mit Datensätzen (Erstellen, Auswählen und Filtern)
Datensatzerstellung
BearbeitenAngenommen wir haben eine Erhebung durchgeführt. Von einer Anzahl Menschen (Untersuchungseinheiten) interessierte uns Name, Geschlecht, Lieblingsfarbe, und Einkommen (Variablen). Vielleicht haben wir ihnen einen Fragebogen übergeben oder die entsprechenden Angaben in einer Liste notiert. Jetzt wollen wir die Daten übernehmen. Wer zuvor schon mit anderer Statistiksoftware gearbeitet hat, kann sich diese Daten vermutlich schon als geordnete Liste vorstellen (vgl. Anwendungsbeispiel 4).
Typischerweise repräsentiert dabei jede Zeile eine Untersuchungseinheit, während die Variablen in den Spalten stehen:
Name | Geschlecht | Lieblingsfarbe | Einkommen |
Hans | männlich | grün | 1233 |
Caro | weiblich | blau | 800 |
Lars | intersexuell | gelb | 2400 |
Ines | weiblich | schwarz | 4000 |
Samira | weiblich | gelb | 899 |
... | ... | ... | ... |
Diese Form der Datenrepräsentation bewerkstelligt man in R
am leichtesten über einen sogenannten data.frame. Um die Daten des Beispiels zu erfassen, können wir z.B. so einen neuen Datensatz erstellen, der die Variablen enthält:
bsp4 <- data.frame( Name=character(), Geschlecht=factor(), Lieblingsfarbe=factor(), Einkommen=numeric() )
Dem Objekt bsp4
wird damit ein data.frame zugewiesen, der aus vier (noch leeren) Vektoren (Name, Geschlecht, Lieblingsfarbe und Einkommen) besteht. Diese sollen unsere Variablendaten enthalten und haben entsprechende Datenmodi: Einkommen ist numerisch (numeric()
), Geschlecht ist kategorial und wird als factor
repräsentiert, usw.
R kennt verschiedene Möglichkeiten der Dateneingabe (-> Import). Wer eine Version mit graphischem User-Interface verwendet, kann Daten in einem eigenen Editor eingeben:
bsp4 <- data.entry(bsp4)
# ersetzt bsp4 durch editierte version von bsp4
# Aufruf ohne Zuweisung würde Veränderungen nicht speichern
Da das Interessante an Datensätzen aber wohl eher nicht deren Eingabe ist, können wir uns diese Arbeit sparen:
- Wenn Sie bereits das Paket
wikibooks
installiert und geladen haben, steht der Datensatz mit dem Befehldata(bsp4)
zur Verfügung. - Andernfalls können die obigen Daten durch Kopieren der folgenden Zuweisung in die Eingabezeile direkt übernommen werden:
bsp4 <- structure(list(Name = c("Hans", "Caro", "Lars", "Ines", "Samira", "Peter", "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")
Tipp: Bei diesem - hier nicht bedeutsamen - Code handelt es sich um die interne Repräsentation eines data.frame in R, die für beliebige Objekte mit der Funktion deparse(x) ausgegeben werden kann. |
In jedem Fall sollte nun das Objekt bsp4
die obigen Daten enthalten:
> bsp4
Name Geschlecht Lieblingsfarbe Einkommen
1 Hans maennlich gruen 1233
2 Caro weiblich blau 800
3 Lars intersexuell gelb 2400
4 Ines weiblich schwarz 4000
5 Samira weiblich gelb 899
6 Peter maennlich gruen 1100
7 Sarah weiblich blau 1900
Referenzierung (Auswahl von Variablen oder Fällen)
BearbeitenDie Referenzierung von data.frames erfolgt allgemein durch den Objekt-/ Datensatznamen gefolgt von eckigen Klammern nach der Regel:datensatzname [ Zeile(n) , Spalte(n) ] |
Auswählen von Variablen (spaltenweise)
BearbeitenAngenommen wir interessieren uns zunächst nur für die Variable Geschlecht. Dann geht es uns nur um die zweite Spalte.
> bsp4 [,2]
[1] maennlich weiblich intersexuell weiblich weiblich maennlich weiblich
Levels: intersexuell maennlich weiblich
Wir erhalten die gemachten Angaben zu Geschlecht und – da es sich um einen factor handelt – die möglichen Ausprägungen dieser Variable (Levels:...). Eine andere, gleichwertige Möglichkeit funktioniert folgendermaßen:
> bsp4$Geschlecht
[1] maennlich weiblich intersexuell weiblich weiblich maennlich weiblich
Levels: intersexuell maennlich weiblich
Auswählen von Fällen (zeilenweise)
Bearbeitendata.frames können sehr viele Fälle umfassen. Oft ist es deshalb sinnvoll, sich nur einen bestimmten Fall anzusehen, z.B. den dritten:
> bsp4 [3,]
Name Geschlecht Lieblingsfarbe Einkommen
3 Lars intersexuell gelb 2400
Erweiterte Referenzierung
BearbeitenZusätzlich zu obiger Konvention können zwei weitere Verfahren zum Einsatz kommen:
- Minuszeichen (-) schließen Zeilen oder Spalten aus.
- Wenn Vektoren in den eckigen Klammern angegeben werden, werden alle darin angegebenen positiven Zahlen ausgewählt und alle negativen ausgeschlossen.
Wenn wir für die Fälle 1,4,6 alle Variablen mit Ausnahme des Geschlechts ausgeben wollen, lautet die Referenzierung somit:
> bsp4[c(1,4,6), -2 ]
Name Lieblingsfarbe Einkommen
1 Hans gruen 1233
4 Ines schwarz 4000
6 Peter gruen 1100
Referenzierungen können ebenso in Zuweisungen verwendet werden.
Angenommen wir bemerken nachträglich, dass die Einkommensangabe von Ines falsch war. Wenn sie 3000 statt 4000 Euro zur Verfügung hat, können wir das folgendermaßen korrigieren.
> bsp4[4,4] <- 3000
> bsp4[4,]
Name Geschlecht Lieblingsfarbe Einkommen
4 Ines weiblich schwarz 3000
Auswahl von Fällen mittels "Wildcard"
BearbeitenMan kann die Fälle auch mittels "Wildcard" auswählen, indem man sich der Funktionen grep
, regexpr
- und which
bedient. Angenommen, wir möchten diejenigen Fälle haben, deren Lieblingsfarbe mit "bl" beginnt, so lautet der passende Befehl:
bsp4[grep("bl",bsp4$Lieblingsfarbe),]
oder
bsp4[which((regexpr("bl",bsp4$Lieblingsfarbe))==1),]
Möchten wir diejenigen Fälle haben, in deren Vornamen ein "a" enthalten ist, lautet der Befehl:
bsp4[grep(".*a.*",bsp4$Name),]
oder
bsp4[which((regexpr(".*a.*",bsp4$Name))==1),]
".*
" ist ein so genannter "regulärer Ausdruck" (engl. "regular expression") und definiert hierbei unsere gewünschte Wildcard. Für weitere Optionen siehe regexpr
.
Filtern von Daten: Teilgruppen und bedingte Ausgabe
BearbeitenIn der Praxis sind wir oft daran interessiert, Teilgruppen zu bilden.
Eine Frage könnte etwa sein, inwieweit sich die Einkommen von Männern und Frauen in unserem Bekanntenkreis unterscheiden.
Die Funktion subset (x,...)
Bearbeiten
Eine einfache Möglichkeit Teilgruppen auszuwählen bietet die Funktion subset (x,bedingung_von_x)
.
> subset(bsp4,bsp4$Geschlecht=="weiblich")
Name Geschlecht Lieblingsfarbe Einkommen
2 Caro weiblich blau 800
4 Ines weiblich schwarz 3000
5 Samira weiblich gelb 899
7 Sarah weiblich blau 1900
Wir interessieren uns nur für das Einkommen der Frauen:
> subset(bsp4$Einkommen,bsp4$Geschlecht=="weiblich")
[1] 800 3000 899 1900
Wenn bsp4
eine größere Fallzahl umfassen würde, wäre diese Liste viel zu lang. Wir würden für einen ersten Eindruck über die Einkommensunterschiede auf das arithmetische Mittel ausweichen:
> mean(subset(bsp4$Einkommen,bsp4$Geschlecht=="weiblich")) [1] 1649.75 # bzw. 1899.75 falls Ines Einkommen=4000 > mean(subset(bsp4$Einkommen,bsp4$Geschlecht=="maennlich")) [1] 1166.5
Dasselbe Ergebnis lässt sich durch Definition von Teilgruppen erzielen:
> frauen <- subset(bsp4,bsp4$Geschlecht=="weiblich") > maenner <- subset(bsp4,bsp4$Geschlecht=="maennlich") > mean(frauen$Einkommen) [1] 1649.75 > mean(maenner$Einkommen) [1] 1166.5
Bedingte Referenzierung
BearbeitenDas gleiche Ergebnis wie bei der Benutzung der Funktion subset kann u. U. einfacher durch bedingte Referenzierung erreicht werden. Entsprechend der Auswahl von Fällen (Zeilen) und Variablen (Spalten) durch Nummern in eckigen Klammern kann auch eine Teilgruppe ausgewählt werden, wenn an Stelle von Nummern logische Bedingungen angegeben werden:
datensatzname [ Zeilenbedingung , Spaltenbedingung] |
Wenn wir z. B. nur die Frauen mit Einkommen über 1500 EUR auswählen wollen, so erreichen wir das folgendermaßen:
> bsp4 [(bsp4$Geschlecht=="weiblich") & (bsp4$Einkommen>1500) ,]
Referenziert werden alle Zeilen (Fälle), für die die beiden obigen Bedingungen gelten (die mit dem Operator & (logisches UND) verknüpft wurden). Entsprechend erhalten wir die Ausgabe:
Name Geschlecht Lieblingsfarbe Einkommen 4 Ines weiblich schwarz 4000 7 Sarah weiblich blau 1900
Tipp: Das Komma hinter den Bedingungen ist notwendig, da wir angeben müssen, dass wir mit der Bedingung (wie zumeist) Fälle auswählen wollen. Stünde das Komma vor der Bedingung, so würden wir versuchen mit dieser Bedingung bestimmte Spalten (Variablen) zu selektieren. |
Filtern doppelter Einträge
BearbeitenMit Hilfe der Funktion duplicated()
kann ein Datensatz nach doppelten Einträgen durchsucht werden. duplicated
gibt hierbei für jede Zeile den Wert "TRUE" oder "FALSE" zurück.
Zunächst erzeugen wir testweise Duplikate in unser Objekt bsp4
:
bsp4 <- rbind(bsp4,bsp4) # wir verdoppeln die Einträge duplicated(bsp4)
In Kombination mit der Funktion which() werden die Zeilnennamen der doppelten Einträge ausgegeben:
which(duplicated(bsp4))
Des weiteren lässt sich diese Kombination auch als Argument zur Zeilendarstellung verwenden:
bsp4[which(duplicated(bsp4)),]
Die Ausgabe von duplicated
lässt sich umkehren, wenn ein Ausrufezeichen vorangestellt wird:
bsp4[which(!duplicated(bsp4)),]
Dasselbe Ergebnis erhält man auch über die Funktion unique()
, welche alle unterschiedlichen Einträge eines Datensatzes genau einmal anzeigt.
duplicated
und unique
können nicht nur auf ein gesamtes Objekt, sondern auch auf einzelne Variablen angewendetet werden, z.B.
unique(bsp4$Name) duplicated(bsp4$Geschlecht)
Hinzufügen / Berechnen neuer Variablen
BearbeitenAngenommen wir wollen eine neue Variable zu unserem Datensatz hinzufügen, die z.B. den Dollarwert der ermittelten Einkommen enthält. Am 8. Juni 2007 erhielt man im Tausch gegen einen Euro 1.34826 US$. Somit errechnen sich die Einkommen ausgedrückt in US$ als:
> bsp4$Einkommen * 1.34826
[1] 1662.405 1078.608 3235.824 5393.040 1212.086 1483.086 2561.694
Mit Hilfe der Funktion cbind
("bind" = engl. verbinden; "c" für column = engl. Spalte ) kann dieser Vektor zum Datensatz als weitere Spalte (Variable) hinzugefügt werden:
bsp4 <- cbind ( bsp4 , "Einkommen (USD)"= bsp4$Einkommen*1.34826 )
Der bisherige Datensatz bsp4
wird ersetzt durch die spaltenweise Verbindung von bsp4
und der neu berechneten Variable "Einkommen (USD)"
:
> bsp4[1,] Name Geschlecht Lieblingsfarbe Einkommen Einkommen (USD) 1 Hans maennlich gruen 1233 1662.405
Hinzufügen neuer Fälle
Bearbeitenmittels Daten-Editor
BearbeitenDer folgende Befehl öffnet unser Objekt bsp4
im Daten-Editor. So können weitere Fälle "von Hand" hinzugefügt werden:
bsp4 <- data.entry
(bsp4)
mittels rbind
Bearbeiten
Unserem Datensatz bsp4
soll ein weiterer Fall hinzugefügt werden:
Jörg maennlich blau 18000 24268.68
Die vielleicht denkbare Methode
bsp4 <-rbind
(bsp4,c
("Jörg", "maennlich", "blau", 18000, 24268.68)) # 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:
bsp4$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(bsp4$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, 24268.68)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. Allerdings können wir leider keinen "Einzeiler" verwenden:
bsp4 <- rbind(bsp4, data.frame
("Jörg", "maennlich", "blau", 18000, 24268.68)) # geht auch nicht :(
Der Befehl schlägt mit der Fehlermeldung fehl, die Spalten-Namen würden nicht zueinander passen. Daher verwenden wir die Funktion list
:
# DIE LÖSUNG: bsp4 <-rbind
(bsp4,list
("Jörg", "maennlich", "blau", 18000, 24268.68))
So geht es.
Umbenennen von Variablen
BearbeitenDer Name der im vorhergehenden Abschnitt neu erstellten Variable enthält Leerzeichen und die Sonderzeichen "(" und ")" . Dies dient der Übersichtlichkeit, ist aber generell eher nicht empfehlenswert, da wir den Variablennamen bei der Referenzierung dann immer in Anführungszeichen setzen müssen ( bsp4$"Einkommen (USD)"
). Somit bietet sich eine Umbenennung an.
Zugang zu den Variablennamen eines Datensatzes ermöglicht die Funktion names(), die diese als Vektor zurückgibt:
> names(bsp4) [1] "Name" "Geschlecht" "Lieblingsfarbe" "Einkommen" "Einkommen (USD)"
Umbenennung von Variablen funktioniert durch eine Neuzuweisung des Vektors names(bsp4) für das Vektorelement des alten Namens:
names(bsp4)[names(bsp4)=="Einkommen (USD)"] <- "EinkommenUSD"
Eine andere Möglichkeit bietet sich mit Hilfe der Funktion gsub, die bestimmte Zeichen eines character-Vektors durch andere Zeichen ersetzt. Dadurch lassen sich auch mehrere Variablen gleichzeitig umbenennen:
> gsub("Ein","Zwei",names(bsp4)) [1] "Name" "Geschlecht" "Lieblingsfarbe" "Zweikommen" "ZweikommenUSD" > names(bsp4) <- gsub("Ein","Zwei",names(bsp4))
Mit dieser Anweisung wurde der gesamte Namensvektor durch die modifizierten Version ersetzt:
> bsp4[1,] Name Geschlecht Lieblingsfarbe Zweikommen ZweikommenUSD 1 Hans maennlich gruen 1233 1662.405
Löschen von Variablen
BearbeitenDie Löschung einer Variablen aus einem Datensatz lässt sich am einfachsten folgendermassen erreichen:
bsp4$Name <- NULL
Diese Anweisung weißt der Variable "Name" das NULL
-Objekt zu, welches eine Liste der Länge 0 repräsentiert. Objekte der Länge Null werden aus einem data.frame
automatisch entfernt und somit ist die Variable gelöscht.
Wenn mehrere Variablen gelöscht werden sollen, bietet sich folgende Variante an:
bsp4 <- bsp4[,-c(1,2)]
Sortieren von Datensätzen
BearbeitenDatensätze lassen sich nach beliebigen Kriterien sortieren, wofür besonders das Funktionspaar sort
und v.a. order
geeignet ist.
Angenommen wir wollen bsp4
nach dem Einkommen sortieren. sort
ordnet metrische Vektoren in aufsteigender Reihenfolge.
> sort
(bsp4$Einkommen)
[1] 800 899 1100 1233 1900 2400 4000
Allerdings wollen wir keinen Vektor sortieren, sondern den gesamten Datensatz. Dies bewerkstelligen wir über den Umweg der numerischen Indize der Fälle (Zeilen). order
gibt als Ergebnis einen Vektor zurück, der die Stelle enthält, an der die mit sort
umsortierten Vektorelemente ursprünglich waren.
> order
(bsp4$Einkommen)
[1] 2 5 6 1 7 3 4
Diese Information lässt sich für Datensätze auch folgendermaßen lesen: Der 2. Fall (Caro) hat das niedrigste Einkommen, das zweitniedrigste Einkommen hat der 5. Fall (Samira), usw. Diesen geordneten Indexvektor kann man nun entsprechend den obigen Referenzierungsregeln verwenden, um den Gesamtdatensatz sortiert auszugeben.
> bsp4[order(bsp4$Einkommen), ] Name Geschlecht Lieblingsfarbe Einkommen 2 Caro weiblich blau 800 5 Samira weiblich gelb 899 6 Peter maennlich gruen 1100 1 Hans maennlich gruen 1233 7 Sarah weiblich blau 1900 3 Lars intersexuell gelb 2400 4 Ines weiblich schwarz 4000
Ein weiteres Beispiel soll die Sortierung nach mehreren Kriterien verdeutlichen. Angenommen wir wollen zunächst nach Geschlecht und innerhalb der Geschlechtergruppen als 2. Sortierungsregel nach dem Einkommen sortieren.
Hierzu werden Variablen, in der Reihenfolge die der "Sortierungs-Hierarchie" entspricht, hintereinander order
übergeben. Für die nominale Variable Geschlecht liefert order
eine alphabetische Sortierung. Somit kann der nach beiden Bedingungen sortierte Datensatz ausgeben werden:
> bsp4[order(bsp4$Geschlecht, bsp4$Einkommen), ] Name Geschlecht Lieblingsfarbe Einkommen 3 Lars intersexuell gelb 2400 6 Peter maennlich gruen 1100 1 Hans maennlich gruen 1233 2 Caro weiblich blau 800 5 Samira weiblich gelb 899 7 Sarah weiblich blau 1900 4 Ines weiblich schwarz 4000
Gruppierung von Variablen
BearbeitenAngenommen uns interessiert der mittlere Wert des Einkommens abhängig von der Geschlechtsgruppe. Mit der Funktion tapply(VARIABLE, GRUPPENVARIABLE, FUNKTION)
ist dies besonders einfach möglich:
> tapply(bsp4$Einkommen,bsp4$Geschlecht,mean) intersexuell maennlich weiblich 2400.00 1166.50 1899.75
Übungsaufgaben
Bearbeiten
|
InhaltsverzeichnisBearbeiten
|