Beruflich Dokumente
Kultur Dokumente
Eine Einführung in Die Statistik-Software R
Eine Einführung in Die Statistik-Software R
Dieses Skript basiert auf dem RRZN-Handbuch Statistik mit R - Grundlagen der Datenanalyse, 1. Auage, Mai 2011 sowie dem Buch Programmieren mit R von Uwe Ligges, 3. Auage, Juli 2008, sowie zu Teilen auf dem Skript Programmieren und Statistik mit R zum gleichnamigen Kurs von Tina Felber aus dem Sommersemester 2012. Es stellt nur eine Einfhrung dar und erhebt keinen Anspruch auf Vollstndigkeit. Insbesondere wird es durch die zugehrigen bungen ergnzt, so dass nicht alle Befehle und Erklrungen im Skript auftauchen.
Inhaltsverzeichnis
1 Einfhrung 1.1 ber R . . . . . . . . . . . . 1.1.1 Was ist R? . . . . . . 1.1.2 Warum R? . . . . . . 1.1.3 Literatur . . . . . . . . 1.1.4 Starten von R . . . . . 1.1.5 Hinweise . . . . . . . . 1.2 R als Taschenrechner . . . . . 1.3 Hilfe . . . . . . . . . . . . . . 1.4 Zuweisungen . . . . . . . . . . 1.5 Logik . . . . . . . . . . . . . . 1.6 Der Arbeitsplatz (Workspace) 1.7 Das Skriptfenster . . . . . . . 1.8 Zusatzpakete . . . . . . . . . 5 5 5 5 6 6 6 7 8 10 10 12 13 13 16 16 17 18 19 20 22 22 23 23 24 25 25 25
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
2 Datentypen und -strukturen 2.1 Datentypen . . . . . . . . . . . . . . . . . 2.2 Vektoren . . . . . . . . . . . . . . . . . . . 2.2.1 Folgen und Wiederholungen . . . . 2.2.2 Rechnen mit Vektoren . . . . . . . 2.2.3 Indizierung von Vektoren . . . . . . 2.3 Matrizen . . . . . . . . . . . . . . . . . . . 2.3.1 Rechnen mit Matrizen . . . . . . . 2.3.2 Indizierung von Matrizen . . . . . . 2.4 Arrays . . . . . . . . . . . . . . . . . . . . 2.5 Listen . . . . . . . . . . . . . . . . . . . . 2.6 Dataframes . . . . . . . . . . . . . . . . . 2.7 Verschiedenes . . . . . . . . . . . . . . . . 2.7.1 Eigenschaften von Datenstrukturen
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
2.7.2
Faktoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26 27 27 29 31 34 38 40 40 41 44 47 47 49 51 51 53 57 60 60 62 70 72 74 76 76 79 80 81
3 Programmieren 3.1 Eigene Funktion denieren . . . 3.2 Bedingte Anweisungen . . . . . 3.3 Schleifen . . . . . . . . . . . . . 3.4 Vektorwertiges Programmieren . 3.5 Sonstiges . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
4 Datenmanagement 4.1 Data frames . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.1 Indizierung und Teilauswahl . . . . . . . . . . . . 4.1.2 Umbenennen und Lschen von Variablen . . . . . 4.1.3 Hinzufgen neuer Variablen . . . . . . . . . . . . 4.1.4 Aufteilen und Zusammenfhren von Datenstzen 4.1.5 Verschiedenes . . . . . . . . . . . . . . . . . . . . 4.2 Datenimport und Datenexport . . . . . . . . . . . . . . . 4.2.1 Dateneingabe in R . . . . . . . . . . . . . . . . . 4.2.2 Einlesen von externen Datenstzen . . . . . . . . 4.2.3 Daten exportieren . . . . . . . . . . . . . . . . . . 5 Grak 5.1 High-level Grak . . . . . . . . 5.2 Kongurierbarkeit von Graken 5.3 Low-level Grak . . . . . . . . . 5.4 Mathematische Beschriftung . . 5.5 Graken exportieren . . . . . . 6 Statistik 6.1 Verteilungen und Stichproben 6.2 Einfache lineare Regression . . 6.3 Statistische Tests . . . . . . . 6.4 Ntzliche Funktionen . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
Kapitel 1 Einfhrung
Dieses Kapitel beinhaltet eine (zum Teil) sehr knapp gehaltene Einfhrung.
1.1 ber R
1.1.1 Was ist R?
Frei verfgbare Programmiersprache Programmpaket zur statistischen Datenanalyse und Grakerstellung Basiert auf der Programmiersprache S (heute: S-PLUS) Homepage von R: http://www.r-project.org/ Installation von R: http://cran.r-project.org/mirrors.html
1.1.2 Warum R?
Vorteile von R: kostenlos Open-Source-Software keine Blackbox, alles kann nachvollzogen werden Flexibilitt Auf allen gngigen Rechnersystemen (Windows, Macintosh, UNIX) lauhig
Nachteile von R: Keine vollkommene Sicherheit bei der Verwendung Keine graphische Oberche, Zusatzpakete wie der R-Commander schaen hier Abhilfe.
1.1.3 Literatur
Statistik mit R, RRZN-Handbuch. (Erhltlich im HRZ.) Ligges, U. Programmieren mit R. Springer. Wollschlger, D. Grundlagen der Datenanalyse mit R. Springer. Chambers, J. Software for Data Analysis: Programming with R (Statistics and Computing). Springer.
1.1.5 Hinweise
R unterscheidet Gro- und Kleinschreibung. Kommentare knnen nach einer # eingegeben werden, Befehle nach einer # werden ignoriert. Leerzeichen sind erlaubt und machen Programme bersichtlicher. ber .Last.value kann der letzte berechnete Wert angesprochen werden
Fr manche Argumente gibt es Voreinstellungen (default). Diese mssen dann nicht zwingend angegeben werden Beispiel: round(5.2) ergibt keine Fehlermeldung, da als Voreinstellung 0 Nachkommastellen eingestellt sind.
Voreinstellungen fr Argumente ndet man auf der Hilfeseite der Funktionen (siehe nchster Abschnitt)
Symbol, Funktion +, , / oder %/% %% max(), min() abs() factorial() choose(n,k) sqrt() sum(), prod() log(), log10(), log2(), log(x, base=b) exp() sin(), cos(), tan(), asin(), ... round(), floor(), ceiling() pi Inf, -Inf NaN NA NULL
Beschreibung Addition, Subtraktion Multiplikation, Division Potenz Ganzzahlige Division Modulo Division Maximum, Minimum Betrag Fakultt Binomialkoezient n k Quadratwurzel Summe, Produkt Logarithmen Exponentialfunktion trigonometrische Funktionen Runden Unendlichkeit (innity) nicht deniert (Not a Number) fehlende Werte (Not Available) leere Menge
Tabelle 1.1: Einige elementare Funktionen (und Symbole), die in R bereits vorporgrammiert sind.
1.3 Hilfe
Die Benutzung der Hilfe gehrt zum Prozess des Lernens einer neuen Programmiersprache dazu. R bietet drei Klassen an Hilfemglichkeiten an, die ntzlich sind, wenn z.B. nach einer korrekten Spezikation der Argumente einer Funktion oder sogar nach dem Namen der Funktion selbst gesucht wird.
1. Hilfe in Form von Literatur: Es gibt sehr viele Bcher ber R (meist in englischer Sprache) und Handbcher. Einige werden in der Regel mit dem Programm gleich mitinstalliert. Man ndet diese als pdf -Datei entweder im Men (nur Windows) unter Hilfe Handbcher (PDF) oder in dem Ordnerverzeichnis, in dem R installiert wurde (meist unter C:/Programme/R/R-2.12.1). Im Unterverzeichnis ... /doc/manuals sind dann die Handbcher zugnglich. Ansonsten net der Aufruf von help.start() die R-Dokumentation (unabhngig vom Betriebssystem), auch dort ndet man Handbcher und FAQs. 2. Hilfe, die im Programm integriert ist: Mit ?help net sich das integrierte Hilfesystem von R und gibt eine kurze bersicht ber die unterschiedlichen Arten, Hilfe in Anspruch zu nehmen. Befehl help(Name ) ?Name example(Name ) help.search(Nam ) ??Nam apropos(Nam ) Beschreibung Hilfe zur Funktion Name () Hilfe zur Funktion Name () Kurzes Beispiel zur Funktion Name () Durchsucht alle Hilfeseiten nach Nam Durchsucht alle Hilfeseiten nach Nam Sucht Funktionen, in denen Nam vorkommt
Beendet wird die Hile im Terminal unter Linux mit der Taste q. Die Informationen werden sehr knapp prsentiert, was am Anfang vielleicht etwas irritierend ist. Mit etwas bung im Lesen solcher Hilfeseiten wird man jedoch irgendwann diesen przisen Prsentationsstil zu schtzen wissen. 3. Hilfe, die online verfgbar ist: ber die Mailingliste R-help. In Mailinglisten stellen Benutzer Fragen zum Umgang mit R, ber die sie weder in der Literatur noch auf Hilfeseiten/Archiven fndig geworden sind. Meist wird die Frage innerhalb krzester Zeit von der R-Gemeinde umfassend beantwortet. Eine bersicht erhlt man auf http://www.R-projct.org/mail.html.
1.4 Zuweisungen
Ergebnisse sollen beim Programmieren oft als Objekte gespeichert werden, damit sie spter weiter verwendet werden knnen. Hierfr wird der Zuweisungspfeil (< ) verwendet. Beispiel: > a < 3 cos(0) > a [1] 3 > (a < 3 cos(0) ) [1] 3 > a < pi [1] FALSE
# Nach ENTER erscheint weitere Eingabezeile. # Erst nach Eingabe des Objektes . . . # . . . wird das Ergebnis ausgegeben. # Klammer um den Befehl nach ENTER . . . # . . . wird das Ergebnis direkt ausgegeben. # Falls Leerzeichen im Zuweisungspfeil, . . . # . . . keine Zuweisung logische Abfrage.
> A # Gro- und Kleinschreibung wird beachtet. Error: object A not found
1.5 Logik
Um spter Funktionen zu schreiben, aber auch zur Analyse von Daten, werden logische Ausdrcke bentigt. Funktion, Operator, Wert ==, != >, >= <, <= ! &, && |, || xor() TRUE, FALSE (T,F) Beschreibung gleich, ungleich grer als, grer gleich kleiner als, kleiner gleich nicht (Negation) und oder ausschlieendes oder wahr, falsch
10
Die Abkrzungen T und F sind trgerisch, da man diese unter Umstnden als Variablennamen verwendet. Am besten sowohl diese beiden Abkrzungen, als auch die Belegung von T und F vermeiden. Zur Verdeutlichung der Operatoren einige Beispiele: 4<3 (3 + 1) != 3 -3<-2 -3 < -2 FALSE TRUE Fehlermeldung (Zuweisung) TRUE
Die Operatoren && und || arbeiten nicht vektorwertig (dazu spter mehr), sondern liefern immer einen einzelnen Wahrheitswert. Es wird nur so viel der Logikverknpfung ausgewertet wie ntig ezient, birgt aber auch Fehlerquellen in eigenen Programmen. FALSE && TRUE TRUE && FALSE FALSE || (x<-3) TRUE || (x<-3) FALSE, rechte Seite nicht ausgewertet FALSE, rechte Seite ausgewertet TRUE, rechte Seite ausgewertet TRUE, rechte Seite nicht ausgewertet
Im Gegensatz zu den Operatoren && und || arbeiten & und | vektorwertig, es wird immer der volle Ausdruck ausgewertet. Zur Veranschaulichung des Unterschiedes: c(TRUE,TRUE) & c(FALSE,TRUE) c(TRUE,TRUE) && c(FALSE,TRUE) c(FALSE,FALSE) | c(FALSE,TRUE) FALSE TRUE FALSE FALSE TRUE
Weitere Operationen mit logischen Werten any() (sind Elemente eines Vektors/einer Matrix TRUE) all() (sind alle Elemente eines Vektors/einer Matrix TRUE) which() (welche Elemente eines Vektors/einer Matrix sind TRUE)
11
Fehlende Werte Eine weitere logische Konstante ist NA, was fr fehlenden Wert steht (Not Available). Auch undenierte Werte NaN (Not a Number) werden wie NAs behandelt. Weitere Operationen: is.na() (Test auf fehlende Werte eines Vektors) is.nan() (Test auf undenierte Werte eines Vektors) na.omit() (reduziert Vektoren um die fehlenden Werte)
Die zugewiesenen Objekte werden nur fr die aktuelle R-Sitzung gespeichert. Nach Schlieen von R und erneutem nen stehen diese Objekte dann nicht mehr zur Verfgung, es sei denn, man hat den Workspace vorher gespeichert. Um beim Speichern des Workspaces mit save.image(le=C:/R/Ausgaben/Test.RData) die Eingabe des oft langen Pfadnamens zu vermeiden, kann man ihn mit save.image(Test.RData) im Arbeitsverzeichnis speichern. Bei Schlieen von R wird man gefragt, ob der Workspace
12
gesichert werden soll. Klickt man auf Ja, wird der aktuelle Workspace in der Datei .RData im Arbeitsverzeichnis gespeichert. Zustzlich wird die history in der Datei .Rhistory im Arbeistverzeichnis gespeichert. Diese beinhaltet eine komplette Liste der bei der letzten R-Sitzung eingegebenen Befehle.
Alternativ dazu bietet der R Commander eine graphische Oberche (vgl. Abb. 1.2), welche auch unter Linux luft. Paket installieren: install.packages(Rcmdr). Laden und erstmaliges nen: library(Rcmdr). Ab dann mit Commander().
1.8 Zusatzpakete
ber 4500 Zusatzpakete zu diversen Themen sind erhltlich, darunter z.B. Themen wie Dierential Equations
13
Abbildung 1.2: Screenshot des R Commanders Finance Graphics Optimization Time Series (...) Eine bersicht (auch nach Themen geordnet) ber alle Zusatzpakete ndet man unter http://cran.r-project.org/web/packages/.
14
Befehl install.packages(nortest) update.packages(nortest) update.packages(ask=FALSE) remove.packages(nortest) search() library() library(nortest) library(help=nortest) detach(package:cluster)
Beschreibung Installiert das Paket nortest Fhrt ein Update fr das Paket nortest durch Alle installierten Pakete werden upgedatet Lscht das Paket nortest Zeigt alle aktuell geladenen Pakete an Zeigt installierten Pakete an Ldt das Paket nortest in den Workspace net das Hilfefenster zum Paket nortest Entfernt das Paket nortest aus dem Workspace
15
2.1 Datentypen
Bevor wir auf Datenstrukturen eingehen, ist es wichtig zu wissen, was fr Datentypen es gibt. R unterscheidet je nach Werten eines Objektes zwischen verschiedenen Datentypen:
Tabelle 2.1: Die verschiedenen Datentypen. Datentyp NULL logical numeric complex character Beschreibung die leere Menge logische Werte ganze und reelle Zahlen komplexe Zahlen Buchstaben, Zeichenfolgen Beispiel NULL FALSE 3.14 2.13+5i Hallo
16
Die leere Menge ist bei den Datentypen ein Sonderfall und wird nur der Vollstndigkeit halber in der Tabelle mit aufgefhrt. Fr die restlichen aufgefhrten Datentypen gilt, dass jeder Datentyp durch die in der Tabelle unter ihm liegenden Datentypen dargestellt werden kann, aber nicht umgekehrt. Man kann z.B. eine reelle Zahl immer als komplexe Zahl interpretieren, (bei der der Imaginrteil Null ist,) aber niemals umgekehrt. Beim Datentyp logical wird TRUE als 1 und FALSE als 0 gespeichert: > TRUE + FALSE + TRUE [1] 2 Wichtige Funktionen im Zusammenhang mit Datentypen: Befehl mode() is.Datentyp () as.Datentyp () Beschreibung Abfragen des Datentyps (Modus) Test, ob Objekt bestimmten Datentyp hat Erzwingen eines Datentyps
2.2 Vektoren
Vektoren sind die grundlegende Datenstruktur in R, denn fast alle Datentypen werden programmintern als Vektoren interpretiert. Mit der Funktion c() (steht fr combine bzw. concatenate ) kann man am einfachsten Vektoren erzeugen: > (x< c(4.1, 6.36)) [1] 4.10 6.36 > x< c(7, x, 3.2)
17
Ein Vektor muss nicht nur aus Zahlen bestehen, beliebige Elemente aus Tabelle 2.1 sind mglich. Dabei werden dann alle Elemente des Vektors als der im Vektor vorkommende Datentyp interpretiert, der in der Tabelle am weitesten unten steht. > (y< c(Hallo, TRUE, x)) [1] Hallo TRUE 7 4.10 [5] 6.36 3.20
Auch ein Benennen von Elementen eines Vektors ist mglich. > c(WertA = 5, WertB = 4) WertA WertB 5 4 # Benennen der Elemente
18
> c(1,2,3,4) c(0,10) [1] 0 20 0 40 > c(1,2,3) c(0,10) [1] 0 20 0 Warnmeldung: In a b : Lnge des lngeren Objektes ist kein Vielfaches der Lnge des krzeren Objektes
Mchte man keine komponentenweise Multiplikation durchfhren, sondern eine Matrixmultiplikation, so verwendet man den Operator % %: > t((1:3)) % % (4:6) [, 1] [1, ] 32 # Skalarprodukt
Hier wird ersichtlich, dass R Vektoren standardmig als stehende Vektoren interpretiert. Dasselbe Ergebnis erhlt man durch Eingabe von (1:3) % % (4:6). Wenn die Dimensionen nmlich nicht passen, aber durch Transponieren des ersten Vektors passend gemacht werden knnen, berechnet R das Skalarprodukt. Das Matrixprodukt erhlt man durch
19
% t((4:6)) [, 2] [, 3] 5 6 10 12 15 18
Auch die Anwendung der elementaren Funktionen aus Tabelle 1.1 ist mglich und geschieht wieder komponentenweise. Weitere ntzliche Funktionen im Zusammenhang mit Vektoren sind Befehl crossprod() length() mean() sum() cumsum() prod() cumprod() sort() order() rank() rev() unique() which() which.max() numeric(n) Beschreibung schneller als %% Lnge eines Vektors Arithmetisches Mittel aller Eintrge Summe aller Eintrge Kumulierte Summe aller Eintrge Produkt aller Eintrge Kumuliertes Produkt aller Eintrge Sortieren Vektor der zum Sortieren gehrenden Indexzahlen Vektor der Rnge Umkehren eines Vektors entfernt mehrfach vorkommende Elemente Index der Elemente, die TRUE sind Zeigt den Index des maximalen Wertes an erzeugt einen Vektor mit n Nullen
20
Es knnen mehrere Indizes auf einmal angesprochen werden. Ein vorangestelltes Minuszeichen whlt alle auer den entsprechenden Indizes aus. Auch logische Indizierung ist mglich, wobei TRUE bedeutet, dass ein Element ausgewhlt wird. Hierbei muss die Lnge des Indexvektors mit dem des angesprochenen bereinstimmen. Benannte Elemente werden ber ihren Namen angesprochen. Eine Ersetzung von Elementen erfolgt durch den Zuweisungspfeil. Eine leere eckige Klammer [] ersetzt alle Elemente eines Vektors, anstatt ihn zu berschreiben. Beispiele: x <- c(4, 7, 1, 9, 3, 5) x[2] x[c(6, 1)] x[- c(6, 1)] x < pi Logik.Index <- x < pi x[Logik.Index] x[x < pi] y <- c(WertA = 5, WertB = 4) y[WertB] z <- 1:5 z[3] <- 7 z[1:2] <- 2:1 z[] <- 0 z <- 0
1 3 1 3 (direkt) 4 1 1 2 0 0
2 2 1 0
3 7 7 0
4 4 4 0
5 5 5 0
21
2.3 Matrizen
Matrizen kann man mit der Funktion matrix() erstellen. Die Argumente dieser Funktion sind Argumentname data nrow ncol byrow Beschreibung Vektor mit Daten Zeilenzahl Spaltenzahl Falls TRUE, wird Matrix zeilenweise aufgebaut
Tabelle 2.2: Argumente der Funktion matrix(). Beispiel: > (A < matrix(c(4,2,3,4,5,2), nrow=3)) [, 1] [, 2] [1, ] 4 4 [2, ] 2 5 [3, ] 3 2 Das Argument ncol ergibt sich in diesem Fall direkt aus den Daten und dem Argumemt nrow. Sollen dieselben Daten zeilenweise eingelsen werden, so wird das durch > (B < matrix(c(4,2,3,4,5,2), nrow=3, byrow=TRUE)) [, 1] [, 2] [1, ] 4 2 [2, ] 3 4 [3, ] 5 2 erreicht.
22
Befehl det() diag() dim(), nrow(), ncol() dimnames() cbind(), rbind() eigen() kappa() qr() solve() svd()
Beschreibung Determinante Abfragen und Setzen der Hauptdiagonalen Anzahl von Zeilen und Spalten Zeilen- und Spaltennamen Matrizen/Vektoren spalten-/zeilenweise zusammenfgen Eigenwerte und -vektoren Konditionszahl einer Matrix QR-Zerlegung Berechnen der Inversen bzw. Ausen des GLS Ax = b Singulrwertzerlegung
Hierbei wurden jetzt jeweils immer Vektoren zurckgegeben. Mchte man die Daten wieder als Matrix auslesen, so muss das Argument drop mit FALSE belegt werden, mehr dazu in den bungen.
2.4 Arrays
Arrays sind eine Verallgemeinerung von Matrizen und knnen beliebig viele Dimensionen besitzen. Arrays werden mit dem Befehl array() gebildet:
23
> (A < array(1:24, dim= c(4,3,2))) ,,1 [, 1] [, 2] [, 3] [1, ] 1 5 9 [2, ] 2 6 10 [3, ] 3 7 11 [4, ] 4 8 12 ,,2 [, 1] [, 2] [, 3] [1, ] 13 17 21 [2, ] 14 18 22 [3, ] 15 19 23 [4, ] 16 20 24
Die Indizierung erfolgt analog zur Indizierung von Vektoren und Matrizen.
2.5 Listen
Eine sehr exibele Datenstruktur ist die Liste. Listen knnen als Elemente Objekte unterschiedlicher Datenstruktur enthalten, also z.B. Vektoren, Matrizen und sogar wieder Listen. Listen werden mit list() erzeugt: > (L1 <- list(c(1,2,5,4), matrix(1:4, 2), c(Hallo,Welt))) [[1]] [1] 1 2 5 4 [[2]] [, 1] [1, ] 1 [2, ] 2 [, 2] 3 4
[[3]] [1] Hallo Welt Der Zugri auf die einzelnen Elemente erfolgt via [[]]:
24
> L1[[1]] [1] 1 2 5 4 > L1[[2]][2, 1] [1] 2 > L1[[c(3, 2)]] [1] Welt
# 1. Element von L1 # Element [2, 1] des 2. Elements von L1 # Rekursiv: zunchst das 3. Element von L1, # dann davon das 2.
Wie auch Vektoren knnen die Elemente einer Liste benannt sein. Dies kann bei komplizierten Objekten von Vorteil sein. > L2 <- list(Info = Information, Liste1 = L1) L2$Info Information L2[[1]] gleiche Ausgabe L2[[2]][[1]][3] 5 L2$Liste[[1]][3] gleiche Ausgabe
2.6 Dataframes
Diese spezielle Liste wird im Kapitel Datenmanagement behandelt.
2.7 Verschiedenes
2.7.1 Eigenschaften von Datenstrukturen
Die Eigenschaften der verschiedenen Datenstrukturen lassen sich mit folgenden Befehlen ausgeben: Befehl class() length() mode() attributes() str() Beschreibung Abfragen der Klasse eines Objektes Abfragen der Lnge eines Objektes Abfragen des Datentyps (Modus) Abfragen der Attribute eines Objektes Abfragen der Struktur eines Objektes inkl. Modus und Attribute
25
Beispiel: > (X< matrix(1 : 6, 2)) # Erzeugen einer Matrix X [, 1] [, 2] [, 3] [1, ] 1 3 5 [2, ] 2 4 6 > class(X) [1] matrix" > length(X) [1] 6 > mode(X) [1] numeric" > attributes(X) # Eine Matrix hat Dimensionsattribute $dim [1] 2 3
2.7.2 Faktoren
Mchte man qualitative (diskrete) Merkmale darstellen, so bedient man sich des Datentyps Faktor. Dieser ist kein atomarer Datentyp im Sinne von Tabelle 2.1. Intern wird bei der Erzeugung von Faktoren durch factor() eine Nummer vergeben, nach auen wird diese aber durch einen Namen reprsentiert. > (geschlecht < rep(c(1, 2), each = 5)) [1] 1 1 1 1 1 2 2 2 2 2 > (factor.geschlecht <- factor(geschlecht, labels = c(mnnlich, weiblich))) [1] mnnlich mnnlich mnnlich mnnlich mnnlich weiblich weiblich weiblich [9] weiblich weiblich
26
Kapitel 3 Programmieren
In diesem Kapitel sollen die wesentlichen Elemente bereitgestellt werden, die man zum Programmieren von eigenen Programmen bentigt. Dabei wird zunchst erklrt, wie man eine eigene Funktion deniert. Anschlieend werden verschiedene Konstrukte wie zum Beispiel Schleifen erklrt. Zum Abschluss wird noch auf den Vorteil von vektorwertigem Programmieren eingegeangen.
n < length(y)
Die Pluszeichen in der Kommandozeile von R weisen nur darauf hin, dass eine weitere Zeile angebrochen wurde und haben nichts mit Addition zu tun.
27
+ +
Sn =
(yi y )2
i=1
fr y = (y1 , y2 , . . . , yn ) berechnet werden und mit > standardabweichung(rnorm(1000)) [1] 0.9816088 wird die empirische Standardabweichung von 1000 standardnormalverteilten Zufallszahlen berechnet. Hierbei ist zu beachten, dass als Ergebnis des Funktionsaufrufes immer das zuletzt denierte Objekt zurckgegeben wird. Der Aufruf der Funktion standardabweichung2() deniert durch > standardabweichung2 < function(y) { + + + 0 n < length(y) sqrt((1 / (n-1)) sum((y-mean(y)) 2)) }
ergibt 0 fr jegliche Eingabe. Um das zurckzugebende Objekt zu spezizieren verwendet man return(): > standardabweichung3 < function(y) { + + + + n < length(y) y < sqrt((1 / (n-1)) sum((y-mean(y)) 2)) 0 return(y) }
Die Funktionen standardabweichung() und standardabweichung3() liefern dieselben Ergebnisse. Durch return() wird die Funktion automatisch beendet.
28
Man kann bei der Denition der Funktion auch Voreinstellungen denieren: Funktionsname< function(Argument1 = Vorgabe1, Argument2 = Vorgabe2, ...){Befehlsfolge} Wrde man die Funktion standardabweichung() ohne Argument aufrufen, so gbe es eine Fehlermeldung. Speziziert man aber ein Argument als Voreinstellung, so geschieht dies nicht mehr: > standardabweichung4 < function(y=c(1,2,3)) { + + + n < length(y) sqrt((1 / (n-1)) sum((y-mean(y)) 2)) }
Um Fehler zu vermeiden, sollte man sich deshalb vor dem Aufruf von Funktionen auch ber deren Argumente und Voreinstellungen informieren. Funktionen kann man unter Windows im Skriptfenster schreiben und abspeichern. Auch der R-Commander eignet sich dazu. Komfortablere Editoren sind Emacs mit Ess (nahezu alle Betriebssysteme) sowie Tinn-R (Windows). Mehr Informationen zu diesen Editoren nden sich im Buch von Ligges (2007). Man kann natrlich auch einen beliebigen Texteditor verwenden, um R-Skripte zu schreiben. Hierbei ist darauf zu achten, die fertigen Skripte mit der Endung .r zu versehen, damit diese dann von R wieder eingelesen werden knnen. Das Einlesen des Skriptes geschieht durch source(Skriptname.r) bzw. source(Pfad/Skriptname.r) wenn sich das Skript nicht im Arbeitsverzeichnis bendet. Durch diesen Befehl landen smtliche im Skript denierten Variablen und Funktionen im Workspace von R und knnen fr die aktuelle Sitzung verwendet werden. Innerhalb von Funktionen zugewiesene Objekte auer dem return-Wert werden nicht im Workspace gespeichert.
29
um Abbruchkriterien fr bestimmte Programmablufe zu denieren zur Abfrage der Korrektheit von Funktionsargumenten
if ... else
Die klassische if ... else-Abfrage wird bei R wie folgt umgesetzt: if (Bedingung.1) {Ausdruck.1} else if (Bedingung.2) {Ausdruck.2} else {Ausdruck.k}
Dabei wird zunchst geprft, ob die Bedingung.1 erfllt ist, hierbei muss es sich also um einen Wahrheitswert handeln. Gilt Bedingung.1=TRUE, so wird Ausdruck.1 ausgewertet. Hierbei kann es sich um einen Funktionsaufruf handeln, um eine weitere Abfrage, um die Zuweisung eines Objektes etc. Die weiteren Ausdrcke mit vorangestelltem else if werden in diesem Falle nicht ausgewertet. Gilt Bedingung.1=FALSE, so wird Bedingung.2 berprft usw. Es wird also der erste Ausdruck ausgewertet, dessen zugehrige Bedingung TRUE ist. Ist keiner der Ausdrcke TRUE, so wird der Ausdruck nach dem else ausgewertet. Beispiel: > g<9 > h<4 > + + + + + + if (g < 0) { g < 2g h < 1/h } else { g < sqrt(g) h < h 2 } # # # # # # Falls g negativ: g verdoppeln und reziproken Wert von h nehmen. Sonst: Wurzel von g und h zum Quadrat nehmen.
30
Da g 0 gilt, wird die erste Anweisung ignoriert und stattdessen direkt die zweite Anweisung durchgefhrt. Htte man zum Beispiel g< -0.5 gesetzt, so htte man als Ergebnis (1, 1/4) erhalten. Weiterhin gilt: wenn der Ausdruck nur in einer Zeile steht, knnen die geschweiften Klammern auch weggelassen werden. Der Teil else{Ausdruck.k} muss nicht zwingend angegeben werden.
ifelse()
Obige Abfrage bentigt einzelne Wahrheitswerte, die Bedingung darf hier nicht vektorwertig sein. Vektorwertige Bedingungen lassen sich mit der ifelse-Abfrage berprfen: ifelse (Bedingung, Ausdruck.1, Ausdruck.2) Dabei ensteht ein Vektor/eine Liste der Lnge length(Bedingung), der/die in jeder Komponente j Ausdruck.1(j) enthlt, wenn Bedingung(j)=TRUE und ansonsten Ausdruck.2(j).
switch()
Muss eine ganze Reihe von mglichen Fllen berprft werden, so bietet sich die Funktion switch(EXPR,...) an. Ihre Funktionsweise soll an folgendem Beispiel klargemacht werden: > switch(2, a=11,b=12,c=13,d=14) [1] 12
Hierbei wurde als Expr die Zahl 2 verwendet, womit der zweite mgliche Fall eintritt. Es ist auch mglich, auf die benannten Elemente zuzugreifen: > switch(c, a=11,b=12,c=13,d=14) [1] 13
3.3 Schleifen
Sollen bestimmte Rechenoperationen oft wiederholt werden, so lsst sich das durch Schleifen bewerkstelligen. Ein klassisches Besipiel ist die Monte-Carlo-Simulation, in der die gleiche Rechenoperation immer wieder mit verschiedenen (Pseudo-) Zufallszahlen durchgefhrt wird. Eine bersicht ber die einzelnen Mglichkeiten fr Schleifen:
31
Schleife bzw. Kontrollwort repeat{Ausdruck} while (Bedingung) {Ausdruck} for (i in M) {Ausdruck} next break
Beschreibung Wiederholung des Ausdrucks Wiederholung solange Bedingung erfllt ist Wiederhole Ausdruck fr jedes i M Sprung in den nchsten Interationsschritt Sofortiges Verlassen der Schleife
Repeat
Eine einfache Schleifenkonstruktion wird durch repeat{Ausdruck} erzeugt. Dabei wird der Ausdruck in der Klammer immer wieder wiederholt, wenn die Schleife nicht durch das Kontrollwort break abgebrochen wird. Da ein einfaches Einfgen von break zum sofortigen Abbruch der Schleife fhren wrde, bietet sich eine bedingte Abfrage an. Beispiel fr eine Endlosschleife: > > j < 0 j+1}
repeat{j <
Endlosschleifen knnen mit Escape abgebrochen werden. Das gleiche Beispiel mit einem Abbruchkriterium: > > + + j < 0
Die repeat-Schleife wird in der Regel nicht so hug benutzt, wie die anderen Schleifenkonstrukte.
While
Bei der while-Schleife wird ein Ausdruck immer wieder berprft und im Falle eines TRUE der nachstehende Ausdruck ausgewertet. Tritt einmal der Wert FALSE auf, bricht die Schleife ab. Die Beispiele von oben lassen sich auch mit while bewerkstelligen:
32
> > +
j <
Da j nichtnegativ ist, und es durch die Auswertung des Ausdrucks auch bleibt, luft die Schleife endlos. Mit dem Abbruchkriterium von oben erhlt man > > + j < 0
An dieser Stelle kan man erahnen, warum die while-Schleife vielleicht etwas populrer ist als obige Konstruktion mit repeat: Direkt am Anfang der Schleife wird ersichtlich, welches das Abbruchkriterium ist. Bei komplizierteren Schleifen wie den hier aufgefhrten wird es evtl. schwierig, im Code der repeat-Schleife das Abbruchkriterium direkt zu erkennen.
For
Mchte man einen bestimmten Ausdruck fr eine bestimmte Indexmenge auswerten, bietet sich die for-Schleife an. > > + M < 1:10
Bei der Menge M muss es sich aber nicht um einen Vektor ganzer Zahlen handeln, M kann ein beliebiges Objekt sein: > > + [1] [1] M < list(a = c(3, 4), b = Test)
Ntzlich im Zusammenhang mit der for-Schleife ist das Argument along der Funktion seq(), die wir bereits kennengelernt haben. Durch die Anweisung for (i in
33
seq(along=d)) wird jeder Index des Objektes d durchlaufen, was manchmal sehr ntzlich sein kann. Da bei dieser Anweisung auch der Fall abgegolten ist, dass das Objekt d die Lnge 0 besitzt, ist sie der Anweisung for (i in 1:length(d)) vorzuziehen. In Fall length(d)=0 wrde bei for (i in seq(along=d)) nichts passieren, wohingegen bei for (i in 1:length(d)) unerwnschterweise der Vektor (1, 0) durchlaufen werden wrde.
Viel einfacher und auch schneller (sowohl was den Schreibaufwand angeht, als auch, was die Rechenzeit angeht): > d < d 2
Apply() und Co
Die Verwendung der in R bereits vorhandenen Funktionen ist oensichtlich, zum Beispiel wenn man den komponentenweisen Absolutbetrag einer Matrix betrachten mchte. Interessiert man sich jedoch fr das zeilenweise Maximum der Matrix, so knnte man auf die Idee kommen, diese Operation als Schleife zu programmieren. Aber auch hier gibt es einfachere/schnellere Mglichkeiten, Tabelle 3.1 gibt eine bersicht.
34
Tabelle 3.1: Funktionen fr vektorwertiges Programmieren Funktion colSums(), rowSums() colMeans(), rowMeans() apply() lapply() sapply() mapply() tapply() Beschreibung schnelle Spalten-/ Zeilensummen schnelle Spalten-/ Zeilenmittel spalten- und zeilenweises Anwenden einer Funktion auf Matrizen bzw. Arrays elementweises Anwenden einer Funktion auf Listen, Datenstze und Vektoren wie lapply(), gibt einfaches Objekt zurck multivariates lapply() Tabellen gruppiert nach Faktoren
apply() Die Funktion apply() (engl: anwenden) eignet sich zur Anwendung von Funktionen auf Spalten oder Zeilen von Matrizen, ohne das das Programmieren einer Schleife notwendig wird. Analog kann sie auch auf Arrays eingesetzt werden. Die allgemeine Form der Funktion sieht wie folgt aus: apply(X, MARGIN, FUN, ...) Als Argumente gehen dabei die Matrix/der Array X ein, die beizubehaltende Dimension MARGIN sowie die anzuwendende Funktion FUN. Auerdem knnen durch ... noch Argumente der Funktion FUN weitergegeben werden. Als einfaches Beispiel betrachten wir die Matrix A: > (A < matrix(c(4,2,3,4,5,2), nrow=3, byrow=TRUE)) [, 1] [, 2] [1, ] 4 2 [2, ] 3 4 [3, ] 5 2
Mchte man hier die zeilenweisen Maxima bestimmen, so knnte man dies wie oben angesprochen wie folgt erreichen:
35
Es ist auch mglich, anonyme (unbenannte) Funktionen zu verwenden: > [1] apply(A,2, function(x) diff(range(x)) ) 2 2
Hierbei wurde die sogenannte Spannweite der beiden Spalten der Matrix berechnet, also die Dierenz aus dem maximalen und dem minimalen Wert. Die Funktion function(x) diff(range(x)) heit deshalb anonym, weil sie keinem Objekt zugweisen wurde. Aus diesem Grund ist sie nach dem Aufruf von apply() auch nicht mehr verfgbar. lapply() und sapply() Mit lapply() (l fr list) lassen sich Funktionen elementweise in hoher Geschwindigkeit auf Listen, Datenstze (dataframes, siehe nchstes Kapitel) und Vektoren anwenden. Die Argumente sind dabei analog zu denen von apply() mit der Ausnahme, dass MARGIN nicht bentigt wird. Es wird eine Liste ausgegeben, deren Lnge der des ursprnglichen Objektes entspricht. Beispiel:
36
> L< list(x = 1:10, y = 1:5 + 0i, z= matrix(c(1,2,3,4,5,6), nrow=3)) > lapply(L, mean) $x [1] 5.5 $y [1] 3+0i $z [1] 3.5 In diesem Falle wird eine Liste zurckgegeben, die Datentypen werden beibehalten. Die Funktion sapply() arbeitet vllig analog zu lapply(), versucht aber, das auszugebende Objekt zu vereinfachen. Sind die auszugebenden Werte pro Element Skalare, so wird anstelle einer Liste ein Vektor mit der entsprechenden Lnge ausgegeben: > > L< list(x = 1:10, y = 1:5 + 0i, z= matrix(c(1,2,3,4,5,6), nrow=3)) sapply(L, mean) x y z 5.5+0i 3.0+0i 3.5+0i
Um einen Vektor auszugeben zu knnen, wurden alle Datentypen in complex umgewandelt. mapply() Bei mapply() handelt es sich um eine Art multivariate Version von sapply(). Ihre Funktionsweise lsst sich am besten an einem Beispiel erklren: > mapply(sum, 1:10, 10:1, 5) [1] 16 16 16 16 16 16 16 16 16 16 # 1+10+5, 2+9+5, 3+8+5, ...
Hier werden die drei Objekte elementweise summiert, wobei der Skalar wie gewohnt entsprechend solange erweitert wird, bis die Lngen bereinstimmen. tapply() Diese Funktion kann verwendet werden, um Statistiken von Daten nach Faktoren zusammenzufassen. Argumente sind ein Vektor mit Daten, ein Faktor, nach dem gruppiert werden soll (mit gleicher Lnge wie der Datenvektor) sowie die Funktion, die angewendet werden soll. 37
Als Beispiel wird der iris Datensatz verwendet, der bereits aus der Beispielsitzung aus der bung bekannt ist2 : > attach(iris) # Datensatz anhngen > tapply(Sepal.Length, Species, mean) setosa versicolor virginica 5.006 5.396 6.588 > tapply(Sepal.Width, Species, range) $setosa [1] 2.3 4.4 $versicolor [1] 2.0 3.4 $virginica [1] 2.2 3.8 > detach(iris) Hier wurde zunchst nach Arten (Species) getrennt die mittlere Kelchblattlnge (Sepal.Length) ermittelt. Anschlieend wurde durch die Funktion range() pro Art das Minimum und Maximum der Kelchblattbreiten ausgegeben. An der Art der Ausgabe wird die hnlichkeit zur Funktion sapply() deutlich: Im ersten Fall wurden die Skalare zu einem Vektor zusammengefasst. Im zweiten war dies nicht mglich, weshalb die Ausgabe als Liste erfolgte.
3.5 Sonstiges
Es wurde bereits angesprochen, dass Programmschleifen wenn mglich zu vermeiden sind. Hier noch ein paar kleine Anmerkungen/Tipps: Zu Beginn Objekte, die pro Schleifendurchlauf wachsen, vollstndig initialisieren. Beispiel (schlecht):
Der Aufruf attach() zum Anhngen von Datenstzen wird im Folgekapitel behandelt.
38
> > +
a < Null for(j in 1:n){ a < c(a, fun(j))} (fun() sei hier eine beliebige Funktion, die ein passendes Objekt zurckgibt). Diese Schleife ist deshalb langsam, weil das Objekt pro Schleifendurchlauf verlngert wird. Dadurch muss jedes Mal erneut Speicher bereitgestellt werden und der Inhalt unter Umstnden intern kopiert werden. Besser ist folgender Ansatz:
> > +
a < numeric(n) for(j in 1:n){ a[j] < fun(j)} Sofern mglich, wre die beste Lsung, wie oben gesehen:
>
Nicht in Schleifen unntige Fehlerberprfungen durchfhren. Argumente sollte man auf ihre Richtigkeit vor einer Schleife berprfen. In der Schleife berechnete Ergebnisse am besten nach der Schleife und wenn mglich vektorwertig auf Plausibilitt prfen. Keine Berechnung mehrfach ausfhren - vor allem nicht in Schleifen. Als einfaches Beispiel betrachten wir > + for(j in 1:n){ a[j] < 2 * n * pi * fun(j)} Die Berechnung von 2 n pi wird hier unntigerweise in jedem Schleifendurchlauf ausgefhrt. Schneller geht es mit > + > for(j in 1:n){ a[j] < fun(j)} a < 2 * n * pi * a
39
Kapitel 4 Datenmanagement
In diesem Kapitel werden die Mglichkeiten vorgestellt, auf Datenstzen zu operieren und diese zu manipulieren. Zunchst wird die wichtige Datenstruktur data frames eingefhrt.
40
So sieht das Ergebnis der Liste aus: > Einkaufen Produkt 1 Apfelsaft 2 Quark 3 Joghurt . . . .
Menge 4 2 2 # usw.
Betrachten wir die Struktur des Datensatzes: > str(Einkaufen) # Struktur des data frame: data.frame: 7 obs. of 3 variables: $ Produkt: Factor w/ 7 levels Apfelsaft,Bier,..: 1 4 3 .. $ Abteilung: Factor w/ 3 levels Fleischw.,Get..,..: 2 3 3 .. $ Menge: num 4 2 2 1 3 1 2 Hierbei fllt auf, dass die Zeichenketten als Faktoren interpretiert wurden. Im Falle der Variable Abteilung macht dies sicherlich Sinn. Mchte man, dass die Funktion data.frame() Zeichenketten nicht als Faktoren interpretiert, so muss man dies durch das Argument stringsAsFactors spezizieren.
41
Bedeutung gleich ungleich grer grer gleich kleiner kleiner gleich und oder Negation
Um zum Beispiel alle Zeilen des Datensatzes anzeigen zu lassen, fr die die Variable Abteilung den Wert Getrnke annimmt, knnte man den folgenden Befehl verwenden: > Einkaufen[Einkaufen$Abteilung == Getrnke, ] Produkt Abteilung Menge 1 Apfelsaft Getrnke 4 5 Wasser Getrnke 3 7 Bier Getrnke 2 Hierbei wurde die matrixhnliche Struktur des Datensatzes ausgenutzt. Zunchst wurde dabei ein Vektor mit logischen Werten produziert. Dieser hat dieselbe Lnge wie es Beobachtungen gibt und berprft den Listeneintrag Abteilung auf bereinstimmungen mit Getrnke. Anschlieend werden durch diesen Vektor alle Zeilen der Matrix extrahiert, die die gewnschte Eigenschaft besitzen. Diese Vorgehensweise erfllt ihren Zweck, fr Dataframes gibt es aber eine bersichtlichere Methode: subset() Die Funktion subset() lsst sich am besten am Beispiel erklren: Die gleiche Auswahl wie oben erhlt man durch > subset(Einkaufen, Abteilung == Getrnke) Es ist auch mglich, mehrere Filterkriterien zu kombinieren:
42
> subset(Einkaufen, Abteilung == Getrnke & Menge > 3) Produkt Abteilung Menge 1 Apfelsaft Getrnke 4 Ebenso ist die Verwendung eines logischen ODERs mglich: > subset(Einkaufen, Abteilung == Getrnke | Abteilung == Milchprod.) Produkt Abteilung Menge 1 Apfelsaft Getrnke 4 2 Quark Milchprod. 2 3 Joghurt Milchprod. 2 5 Wasser Getrnke 3 7 Bier Getrnke 2 Eine elegantere Art, zu diesem Ergebnis zu kommen, ist > subset(Einkaufen, Abteilung %in% c(Getrnke,Milchprod.)). Diese bietet sich an, wenn viele solcher Kriterien zu berprfen sind. Die erste Lsung kann dann doch schnell unbersichtlich werden. Weiterhin bietet die Funktion subset() die Mglichkeit, Variablen aus dem Datensatz auszuschlieen. Im ersten Beispiel wird die Spalte Abteilung des Datensatzes berssig, da die gelterten Daten alle in der gleichen Abteilung zu nden sind. Um diese Spalte zu entfernen, wird das Argument select verwendet: > subset(Einkaufen, Abteilung == Getrnke, select=-2) Produkt Menge 1 Apfelsaft 4 5 Wasser 3 7 Bier 2 Kennt man die betroene Spaltenzahl nicht, so kann man sich folgendermaen helfen: > subset(Einkaufen, Abteilung == Getrnke, + select=names(Einkaufen)!=Abteilung)
43
Anzahl 4 2 2 # usw.
Der allgemeinere Lsungsansatz fr diese Zuweisung ist der folgende: > names(Einkaufen)[names(Einkaufen)==Menge] < Anzahl
44
# usw.
Zur Lschung mehrerer Variablen bietet sich folgendes an: > Einkaufen< Einkaufen[,-c(2,3)] Hierbei wurden die letzten beiden Variablen aus dem Datensatz entfernt. Analog knntem man natrlich auch die Funktion subset() mit einer entsprechenden Belegung des Argumentes select verwenden. Hinweis: Es ist zu beachten, dass der Vorgang des Lschens nicht rckgngig gemacht werden kann. Bei wichtigen Daten sollte man also eventuell zunchst eine Sicherungskopie erstellen.
45
Fr ein absteigendes Sortieren, kann man im Falle von quantitativen Merkmalen (statt das Zusatzargument decreasing=TRUE zu verwenden) dem Vektor, nach dem sortiert werden soll, ein Minuszeichen voranstellen: > Einkaufen[order(-Einkaufen$Menge),] Produkt Abteilung Menge 1 Apfelsaft Getrnke 4 5 Wasser Getrnke 3 7 Bier Getrnke 2 3 Joghurt Milchprod. 2 . . . . # usw. Bei der Sortierung nach einer einzelnen Variable wurde an der Reihenfolge sonst nichts verndert. Das erkennt man zum Beispiel daran, dass der Indexvektor ganz links innerhalb von Beobachtungen mit der gleichen Anzahl immer noch geordnet ist. Es ist auch mglich, nach verschiedenen Variablen gleichzeitig zu sortieren. Der Befehl > Einkaufen[order(Einkaufen$Menge,Einkaufen$Produkt),] Produkt Abteilung Menge 4 Schinken Fleischw. 1 6 Wurst Fleischw. 1 7 Bier Getrnke 2 . 3 Joghurt Milchprod. 2 2 Quark Milchprod. 2 5 Wasser Getrnke 3 1 Apfelsaft Getrnke 4 sortiert den Datensatz zunchst nach der Variablen Menge. Existieren innerhalb dieser Sortierung ties, also identische Beobachtungen, so wird hier nach dem zweiten Vektor sortiert. Die Reihenfolge der Vektoren, die an order() bergeben werden, spielt also eine Rolle. Im Beispiel ist die Zeile mit Bier am weitesten oben von allen Beobachtungen mit Menge=2, da im zweiten Schritt alphabetisch sortiert wurde. Hinweis: Daten vom Typ Charakter werden alphabetisch sortiert. Faktoren hingegen werden nach ihrem inneren Wert geordnet, unabhngig von der alphabetischen Reihenfolge der labels. Im Beispiel wurde die Spalte mit den Produkten beim Erstellen des Dataframe als Faktor kodiert. Bei diesem Vorgang wurden die inneren Werte entsprechend der alphabetischen Sortierung vergeben. So kam es zufllig zur alphabetischen Sortierung im vorigen Beispiel.
46
# usw.
Da der Dataframe letztlich auch eine Art Matrix ist, htte der folgende Befehl zum gleichen Ergebnis gefhrt: > Einkaufen < cbind(Einkaufen, Preis) Ebenso ist es mglich, dem Datensatz mit rbind() neue Beobachtungen zuzufhren.
47
$Fleischw. Produkt Abteilung Menge Preis 4 Schinken Fleischw. 1 1.77 6 Wurst Fleischw. 1 0.09 $Getrnke Produkt Abteilung Menge Preis 1 Apfelsaft Getrnke 4 0.58 5 Wasser Getrnke 3 1.88 7 Bier Getrnke 2 1.06 $Milchprod. Produkt Abteilung 2 Quark Milchprod. 3 Joghurt Milchprod.
Menge 2 2
Jeder Eintrag in dieser Liste ist wieder ein Dataframe, der alle Beobachtungen des ursprnglichen Datensatzes enthlt, die zur entsprechenden Ausprgung der Variable Abteilung gehren. Der Aufruf von unsplit() mit den entsprechenden Faktoren, nach denen aufgeteilt wurde, macht die Aufteilung des Datensatzes rckgngig. Die Liste kann jetzt nach den bekannten Regeln aus Kapitel 2.5 bearbeitet werden. Insbesondere kann man durch split(Einkaufen, Einkaufen$Abteilung)$Abteilungsname den Teil-Datensatz der Einkaufsliste herausgreifen, fr den die Variable Abteilung den Wert Abteilungsname annimmt. merge() In manchen Fllen liegen einem zwei Datenstze vor, die zu einer oder mehreren identischen Variablen komplementre Zusatzinformationen beinhalten. Diese knnen mit merge() zu einem allumfassenden Datensatz zusammengefhrt werden. Wir fhren das Beispiel der Einkaufsliste fort. Angenommen, bei gewissen Produkten kennen wird die Marke, die immer am gnstigsten ist. Diese Information haben wir in folgendem Dataframe abgespeichert:
48
> Marken <- data.frame(Produkt = c(Joghurt,Apfelsaft, Wurst, + Wasser), Marke=c(Nein!-Joghurt,Nein!-Apfelsaft,Nein!-Wurst, + Nein!-Wasser)) Da wir momentan aufs Geld achten mssen, wollen wir, wann immer mglich, das gnstigste Produkt kaufen. Deshalb macht es Sinn, die Informationen, die durch die beiden Dataframes gegeben sind, zusammenzufassen: > merge(Einkaufen,Marken) Produkt Abteilung Menge 1 Apfelsaft Getrnke 4 2 Joghurt Milchprod. 2 3 Wasser Getrnke 3 4 Wurst Fleischw. 1
Preis Marke 0.58 Nein!-Apfelsaft 0.82 Nein!-Joghurt 1.88 Nein!-Wasser 0.09 Nein!-Wurst
Da die Dataframes unterschiedliche Lngen besaen, wurden nur die Zeilen mit bereinstimmungen zusammengefasst. Mchte man trotzdem alle Produkte in der Einkaufsliste stehen haben, so lsst sich dies durch > merge(Einkaufen,Marken, all.x=TRUE) Produkt Abteilung Menge Preis Marke 1 Apfelsaft Getrnke 4 0.58 Nein!-Apfelsaft 2 Bier Getrnke 2 1.06 <NA> 3 Joghurt Milchprod. 2 0.82 Nein!-Joghurt 4 Quark Milchprod. 2 1.58 <NA> 5 Schinken Fleischw. 1 1.77 <NA> 6 Wasser Getrnke 3 1.88 Nein!-Wasser 7 Wurst Fleischw. 1 0.09 Nein!-Wurst erreichen. Zum besseren Verstndnis der diversen Argumente empehlt es sich, die Hilfeseite von merge() aufzurufen, und das angegebene Beispiel nachzuvollziehen.
4.1.5 Verschiedenes
Einhngen eines Datensatzes in den Suchpfad Mchte man auf bestimmte Variablen eines Datensatzes immer wieder zugreifen, so ist es umstndlich, jedes Mal mit dem $ Operator oder einer Indizierung zu arbeiten. Hier schat die Funktion attach() Abhilfe. Der Befehl attach(Einkaufen) ermglicht es, die Variable Produkt direkt anzusprechen:
49
Anstatt > Einkaufen$Produkt kann man nun > Produkt schreiben. Vorsicht ist allerdings geboten bei neuen Zuweisungen. Mchte man das Original-Objekt verndern, so muss man weiterhin mit Einkaufen$Produkt arbeiten. Die Zuweisung > Produkt[1] < Wasser lsst den Dataframe Einkaufen und damit insbeondere die Variable Einkaufen$Produkt unverndert. Stattdessen wird nur eine Kopie des Vektors im Workspace verndert. Mit dem Befehl detach() lassen sich geladene Datenstze aus dem Suchpfad wieder entfernen. Mehr Datenstze In den Basis- und Zusatzpaketen von R benden sich eine Vielzahl von Datenstzen. Um sich eine Liste von allen Datenstzen ausgeben zu lassen, die zu den installierten Zusatzpaketen gehren, gibt man > data(package = .packages(all.available=TRUE)) ein. Der Befehl ohne Zusatzargumente zeigt alle momentan verfgbaren Datenstze an. > data() Diese Liste ist evtl. krzer als die erste, da Datenstze nur verfgbar sind, wenn das entsprechende Zusatzpaket geladen ist. Das Laden eines Zusatzpaketes wurde in Kapitel 1.8 beschrieben. Ist das Zusatzpaket geladen, so kann man den Datensatz mit attach() in den Suchpfad einhngen und damit arbeiten. Eine bersicht ber die Datenstze eines Paketes erhlt man ber die Funktion try(). Zum Beispiel gibt > try(data(package=datasets)) eine Liste aller Datenstze des Paketes datasets.
50
Um Informationen ber einen Datensatz zu erhalten, kann man sich der Funktion help() bedienen: > help(Orange) gibt eine bersicht ber den Datensatz Orange aus dem Paket datasets.
4.2.1 Dateneingabe in R
Dateingabe mit scan() Eine sehr einfache Mglichkeit, Daten in R einzulesen, ist durch die Funktion scan() gegeben. Die Zuweisung einer Variablen geschieht wie folgt: > y < scan() 1: Die zweite Zeile mit dem Eingabefeld erscheint automatisch nach Drcken der ENTERTaste. Nun kann dem Vektor y der erste Wert durch Eingabe des Wertes und anschlieendem Drcken von ENTER zugewiesen werden. Dieses Vorgehen wiederholt man so lange, bis alle Werte eingegeben sind. Mchte man keinen weiteren Wert eingeben, so drckt man nur die ENTER-Taste. Dies schliet die Eingabe ab. Mithilfe von scan() knnen aus Excel Spalten direkt eingelesen werden. Dazu kopiert man die entsprechende Spalte in Excel und fgt diese durch die Tastenkombination STRG+V im Eingabefeld ein.
51
Die Funktion data.frame() Die Funktion data.frame() haben wir bereits kennengelernt. Hat man whrend einer R Sitzung verschiedene Vektoren erzeugt, die Variablen eines Datensatzes entsprechen, so kann man diese mit data.frame() zu einem Datensatz zusammenfgen: > x < 1:10 > y < 2 * y > Daten < data.frame(x,y) Das Ergebnis sieht dann wie folgt aus: > Daten x 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10
y 2 4 6 8 10 12 14 16 18 20
Manuelle Dateneingabe und -Bearbeitung Die rudimentrste Methode der Dateneingabe bei R ist die manuelle Dateneingabe. Dazu wird zunchst durch > Daten < data.frame() ein leerer Datensatz erstellt. Diesen kann man jetzt durch den Aufruf von > fix(Daten) manuell bearbeiten.
52
Durch den Aufruf net sich der Dateneditor (vgl. Abbildung 4.1).
Abbildung 4.1: Screenshot der manuellen Dateneingabe. Jetzt kann man nach einem Klick auf die Variablenfelder in der ersten Zeile deren Namen und Typ (numeric oder character) festlegen. Anschlieend kann man die einzelnen Zellen durch einen Klick anwhlen und Werte eintragen. Ist der Datensatz fertiggestellt, so schliet man den Editor wieder.
Die Abkrzung ASCII steht fr American Standard Code for Information Interchange.
53
Liegt eine Datei in einem solchen Format vor, so kann sie beispielsweise ber die Funktionen read.table(), read.csv(), oder read.csv2() eingelesen werden. Eine der am hugsten verwendeten Methoden zum Einlesen von externen Daten in R ist read.table(). Die Funktionsweise soll an einem Beispiel erklrt werden. Beispiel Die Datei kino.txt2 enthlt Daten zu einer ktiven Umfrage. 20 Personen wurden nach Alter, Geschlecht und der Anzahl der Kinobesuche im vergangenen Jahr befragt. Bevor man die Daten importiert, empehlt es sich, den Originaldatensatz zu betrachten, um Informationen darber zu erhalten, welche Trennzeichen verwendet wurden.
Abbildung 4.2: Der Datensatz kino.txt genet im Editor. In Abbildung 4.2 sieht man, dass als Trennzeichen das Semikolon verwendet wurde. Dezimaltrennzeichen sind nicht vorhanden, da es nur ganzzahlige Eintrge gibt.
54
Die Datei kann nun durch den Befehl > kino < read.table(file= "C:/R/Datensaetze/kino.txt", + header=TRUE,sep=";", dec =".") > kino id gender alter kino 1 A1 mnnlich 26 1 2 A2 mnnlich 43 5 3 A3 weiblich 17 9 ... 18 A18 weiblich 31 3 19 A19 mnnlich 40 1 20 A20 weiblich 38 0 eingelesen werden und steht im Workspace zur Verfgung. Die Argumente von read.table() erklren sich wie folgt: file: Der Pfad mit sich anschlieendem Dateinamen. Ist das entsprechende Verzeichnis bereits als Arbeitsverzeichnis ausgewhlt, so reicht der Dateiname. header: Ein Wahrheitswert. Gilt header=TRUE, so wird die erste Zeile des Datensatzes fr die Variablennamen verwendet. Voreinstellung ist FALSE. sep (kurz fr separator): Legt fest, welches Zeichen als Trennzeichen zwischen den Spalten des Datensatzes interpretiert werden soll. Voreinstellung ist , es wird also jeglicher Leerraum als Trennzeichen verwendet - Tabulatoren oder Leerzeichen. dec(decimal points): Dieses Zeichen bestimmt das Dezimaltrennzeichen. Voreinstellung ist .. Liegt eine Datei im csv3 -Format vor, so bietet sich je nach Trennzeichen read.csv() oder read.csv2() zum Einlesen an, vergleiche Tabelle 4.2.2. Funktion read.table() read.csv() read.csv2()
3
sep , ;
dec . . ,
55
Manuelles Einlesen von Daten Es ist auch mglich, Datenstze ber das Ordner-Men einzulesen, wie man es auch sonst von Windows kennt. Diese Vorgehensweise spart die Spezizierung des Argumentes file. Um Daten auf diese Weise einzulesen, verwendet man die Funktion file.choose(). Nach Eingabe des Befehls > kino < read.table(file.choose(),header=TRUE,sep=";", dec =".") net sich ein neues Fenster:
Abbildung 4.3: Einlesen von Daten mit file.choose() Nun kann man den Datensatz manuell im Dateiensystem auswhlen. Excel-Dateien Ein Nachteil von R ist, dass es keine einfache Mglichkeit gibt, Daten im Excel-Format direkt in R einzulesen. Ein Workaround im Falle einer berschaubaren Anzahl von Datenstzen besteht darin, diese zunchst im Format .txt oder .csv abzuspeichern und anschlieend mit den oben genannten Methoden zu importieren. Speichert man in Excel eine Datei im Format .csv ab, so sind die Voreinstellungen derart, dass sie zu denen von read.csv2() passen.
56
Der Umweg ber die zwischenzeitliche Abspeicherung in einem anderen Format scheint umstndlich, wird aber wegen der geringen Fehleranflligkeit in der Literatur meist empfohlen. Es existieren Zusatzpakete, die das direkte Einlesen von Excel-Dateien ermglichen, zum Beispiel RODBC, xlsReadWrite oder gdata. Auf diese wird hier aber nicht eingegangen. Mchte man nur einzelne Spalten eines Datensatzes einlesen, so kann man mit der Funktion scan() arbeiten (vgl. Kapitel 4.2.1).
> Datenvektor < rnorm(100) Durch > write(Datenvektor, "C:/R/Datensaetze/Datenvektor.txt", ncolumns=1) kann man den Vektor jetzt in einer .txt Datei abspeichern. Das Argument ncolumns wurde deshalb speziziert, weil die Voreinstellung fnf Spalten vorsieht. Dadurch wrde der Vektor auf fnf Spalten aufgeteilt werden. Nach dem Abspeichern kann man den Datensatz mit dem Texteditor nen (vgl. Abbildung 4.4). Auslesen eines Datensatzes Mchte man nicht nur einen einzelnen Vektor abspeichern, sondern einen ganzen Datensatz, so verwendet man die Funktionen write.table(), write.csv(), oder write.csv2(). Diese sind derart aufgebaut, dass man die gespeicherten Dateien mit den Voreinstellungen ihrer Pendants read (vgl. Tabelle 4.2.2) wieder einlesen kann.
57
Abbildung 4.4: Der mit write() ausgelesene Datenvektor. Als Beispiel betrachten wir den Datensatz Daten aus Kapitel 4.2.1: > Daten x 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10
y 2 4 6 8 10 12 14 16 18 20
Dieser wird mit dem Befehl > write.table(Daten, "C:/R/Datensaetze/Datensatz.txt") exportiert. Das mit dem Editor genete Ergebnis kann man in Abbildung 4.5 betrachten. Mchte man verhindern, dass dem Datensatz die fortlaufenden Nummern als Extraspalte vorangestellet werden, so muss man das Argument row.names auf FALSE setzen. Die Anfhrungsstriche bei den Variablennamen unterdrckt man durch das Argument quote.
58
Abbildung 4.5: Der mit write() ausgelesene Datensatz. Mchte man Daten nach dem Auslesen mit Excel nen, so bietet sich write.csv2() an.
59
Kapitel 5 Grak
In R existiert eine Vielfalt an Mglichkeiten, Graken zu erstellen. Diese reichen von der explorativen Grak, mit der man sich einen kurzen berblick ber Daten verschat bis zu Graken von hoher Qualitt, die man fr Prsentationen oder Publikationen verwenden kann. Durch den Aufruf des Befehls demo(graphics) erhlt man einen kurzen Einblick in die verschiedenen Mglichkeiten, Graken mit R zu erstellen. Bei der Grakerstellung mit R unterscheidet man zwischen den traditionellen Graken und den sogenannten Trellis Graken. Letztere basieren auf dem Paket lattice und bieten deutlich mehr Mglichkeiten in der Gestaltung, sind dafr aber etwas aufwndiger zu porgrammieren. Zur statistischen Datenanalyse reichen meist die traditionellen Graken aus, weshalb im Rahmen dieser Einfhrung auf die Trellis Graken verzichtet wird.
60
Funktionsname barplot() boxplot() contour() curve() hist() pairs() persp() plot() pie() pie3D() qqnorm() qqplot()
Erluterung Balkendiagramm Boxplot Hhenlinienplot (Konturplot) Funktion zeichnen Histogramm Scatterplotmatrix perspektivische Flchen je nach Datentyp: Scatterplot, Boxplot, Balkendiagramm u.a. Kreisdiagramm 3D-Kreisdiagramm nach Laden des Pakets plotrix Q-Q-Diagramm fr die Normalverteilung Q-Q-Diagramm mit zwei Datenstzen Tabelle 5.1: Einige High-level Grakfunktionen.
(lineares Modell, wird im folgenden Kapitel behandelt) Graken zur Modellanalyse (z.B. Residualplot) und bei Eingabe eines Zeitreihenobjektes wird eine mit Linien verbundene Zeitreihe geplottet. Als Beispiel betrachten wir den iris-Datensatz aus der Beispielsitzung aus der ersten bung: > > > > > attach(iris) plot(Petal.Length, Petal.Width, pch = as.numeric(Species)) windows() hist(Petal.Length) detach(iris)
Der Aufruf windows() zwischen den beiden Plots ist notwendig, um beide Graken parallel anschauen zu knnen. Ruft man nmlich eine High-level Grak-Funktion auf, so wird ein neuer Plot erstellt und - falls vorhanden - der aktuelle dadurch berschrieben. Durch die Eingabe von windows() net sich ein neues Fenster fr den weiteren Plot. Die Ergebnisse der beiden Aufrufe benden sich in Abbildung 5.1. Durch das Zusatzargument pch (von point character) wurde dabei jeder Panzenart ein anderes Symbol zugewiesen. Da die verschiedenen Panzenarten als Faktoren vorliegen, mussten sie durch den Aufruf as.numeric() durch ihren inneren Wert ersetzt werden. Dabei ist zu beach-
61
Histogram of Petal.Length
2.5
Petal.Width
1.5
2.0
Frequency
G G G GGG G GGG G G GG G G GG GG GG GG G G GG
1.0
0.5
4 Petal.Length
0 1
10
20
30
4 Petal.Length
Abbildung 5.1: Beispielgraken (Streudiagramm, Histogramm) mit den iris-Daten ten, dass der Vektor Species die gleiche Lnge besitzt wie Petal.Length bzw. Petal.Width.
62
Argument axes bg cex col las log lty, lwd main, sub mar mfcol, mfrow pch type usr xlab, ylab xlim, ylim xpd
Erluterung Achsen sollen (nicht) eingezeichnet werden Hintergrundfarbe Gre eines Punktes bzw. Buchstaben Farben Ausrichtung der Achsenbeschriftung Logarithmierte Darstellung Linientyp (gestrichelt, ...) und Linienbreite berschrift und Unterschrift Gre der Rnder fr Achsenbeschriftung etc. mehrere Graken in einem Bild Symbol fr einen Punkt Typ (l=Linie, p=Punkt, b=beides, n=nichts) Ausmae der Achsen auslesen x-/y-Achsenbeschriftung zu plottender Bereich in x-/y- Richtung in die Rnder hinein zeichnen
Tabelle 5.2: Einige hug benutzte Argumente in Grakfunktionen und par(). len mchte. Zu den Parametern, die man standardmig durch par() verndern wrde, gehren zum Beispiel die Aufteilung der Plotregionen, Rnder oder Anzahl der Graken in einem Plot. Eine Bildberschrift hingegen wrde man dem Plot individuell zuweisen, weshalb dies auch kein Argument von par() ist. Eine bersicht von hug verwendeten Argumenten in Grakfunktionen bzw. par() ndet man in Tabelle 5.2. Farben knnen auf verschiedene Art und Weise angegeben werden. Zunchst gibt es die Standard-Farbpalette, die man durch den Befehl palette() aufrufen kann: Die Zu> palette() [1] black red green3 blue [5] cyan magenta yellow gray weisung einer Zahl zwischen 1 und 8 speziziert also die gewnschte Farbe. Alternativ kann man aber auch eine Zeichenfolge in Anfhrungszeichen bergeben, zum Beispiel green3. Eine vollstndige1 Liste der bekannten Farbnamen erhlt man durch die Ein1
Eine Farbe fehlt in der Aufzhlung: transparent. Diese ist nicht fr alle mglichen Ausgaben verfgbar.
63
gabe von colors(). Es ist auch mglich, RGB-Werte in Hexadezimaldarstellung zu bergeben, mehr Informationen dazu ndet man in der Hilfe ?par unter Color Specication. Ein besonderer Einsatz von Farbe ist die Verwendung des alpha -Kanals, mit dem teilweise transparente Objekte erzeugt werden knnen. Auf dieser Art lassen sich berlagerungen verschiedener Objekte sichtbar machen, wie folgendes Beispiel verdeutlichen soll: > set.seed(321) > x <- c(rnorm(2000), (a <- rnorm(200, sd = 0.5))) > y <- c(rnorm(2000), a) Hierbei wurden strukturierte Daten unter eine Punktewolke gemischt. Plottet man nun mit plot(x, y, col = rgb(0, 0, 0), pch = 16) ein Streudiagramm zu den Daten, so lsst sich die Struktur nicht sofort erkennen:
G G GG G G G G G G G G G G G G G G G GG G G G G G G G G G G GG G GG G G G GG G G G G G G G G G GG G GG G G G G G G G G G G G GG G G G GG G G G G GG G G G G G G GG G GG G G G GG G G GG G G G G G G G G G G G G G G G G G G G G G GG G G G GG GG GG G GG GG G G GG G G G G G G G G G G G G G G G GGG G G G G G G G GG G G G G GG G G G G G G G G G G G G G G G G G G G G G GG G G G G G GG G G GG G G GGG GG G GG G G G G G G G GGGG G G G G G G G G G G GG G G G G GG G GG G G G GG GG G G G G GG G G G G G G G GG G GG G GG G G GG G G G G G G G G G G G G G G G G G G G G G G GG G G G G G G G G G G GG G G G G G G G G G G GG G G G G G G G G G G G G G G G G G G G G G G G G G G G G G GG GG G G GG G G G G G G G G GG GG G G G G G GG G G G GG G G G G G G G G G G GG G G G G G G G G G G G G G G G GG GG G G G G G GG G G G GGG GG G GGG G GG G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G GG G G G GG G G G G G G G G GG G G G G G G GGG G G G G G G G G G G G G G G GG G GG G GG G G G G G G G G G G G GG G G G G G G G G G G G G G G G G G G G G G G GG G G G GG GG G G G G GG GG G G GG G GG G G GG G G G G G G G G G G G G G G G G G G G G G G G G GG G G G G G G G G G G G G G G G G G G GG G G G G G G G G G G G G G G G G G G G G G G G G G G G GG G G G G G G G G G G G G G G G G G GGGG G GG G G G G G G G G G G G G G G G G G G GG G G GG G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G GG G G G G G GG G G GG G GG G G G G G G G G G G GG G G G GG G G G G G G G G G G G G G G G G GG G GG G GGG G G G G G G G GG G G G G G G GG GG GG G G GG G G G G G G G G G G G G G G GGG G GG G G G G G GG G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G GG G GG G G G G G G GG G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G GGG G G G G G G G G GG GG GG G G G G GG GG G G G G G GGG GG G G G G G G G G G G G G G G G G G G G G G G GG G G G G G G GG G G G G G G GG G G G GG GG G G G GG G G G G G G G G G G G G G G G G G G G G G G G G G G G GG GG G G G GG G G G G G G G G G G G G G G GG G G G GG G G GG GG G G G G G G G G G G G G G G G G G G G G G G G G G G G GG G GG G G G GG G G G G G G G G G G G G G G G G G G G G G G GG G G G G G G G G G G G GG GG GG G G G G G G G G G GG G G G G G G G G GG G G G G G G G GG G G G G G G G G G G G G G G G G G G G G G G G G G G G G G GG G G G G G G G G GG G G G G G G GG G G G G G GG G G GG G G G G G G G G G G G G G G G G GG G GG G G G G GG G G G G G G G G GG G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G GGG GG G G G GG G G G G G G G G G G G G G G G G G G GG GG G G G GG G G GG G G G G G G G G G G GG G GG G G GG G G G G GG GG G G G G G G G G G G G G G G G G GG G G G G G G G G G G G G G G G G G GG GG GG G G GG G GG GG G G G G G G G G G G G G G G G G G GG G G G G G G GG G G GG G G G G G G G G G G G G G GG G G G G GG G G G G G G G G G G G G G G GGG GG G G GG G G G GG G GG G G G G G G G G G G G G G G G G G G G G G G G G G G GG G G G G G GG G G G G G G G G GG G GG G G G GG G G G GG GG G G G G GG G G G G G G G G G GG G GG G G G G G G G G G G G GG G G G GGG G G GG G G G G G G G G G G G G G G G G G G G G G G G G G G G G G GG GG G G G G GG G G GG G G G G G G G GGG G G G GG G G G G GGG G G G GG G G G G G G G GG G G G G G G G G GG G GG G G G G G G G G G G G G G G GG G G G G GG G G GG G G G G G G G G G G G GG G G G G GGG G G G G G G G G GG G G G G G G G G G G G GG G G G G G G G G G G G G G
3 3
0 x
64
Nun plotten wir dieselben Daten unter Verwendung des Argumentes alpha der Funktion rgb(): plot(x, y, col = rgb(0, 0, 0, alpha=0.1), pch = 16) Es ergibt sich das folgende Bild, in dem die Struktur der Teilmenge des Datensatzes deutlich zu Tage tritt:
3 3
0 x
Als nchstes soll an einem Beispiel aufgezeigt werden, wie die verschiedenen Parameter verwendet werden knnen, um das Erscheinungsbild eines Plots zu verndern: > > > > > + + > > set.seed(123) x < rnorm(100) # 100 N(0,1)-verteilte Zufallszahlen par(las = 1) # alle Achsenbeschriftungen horizontal # Beschriftetes und manuell skaliertes Histogramm: hist(x, main = Dichte 100 N(0,1)-verteilter Zufallszahlen, freq = FALSE, col = grey, ylab = Dichte, xlim = c(-5, 5), ylim = c(0, 0.6)) # Hinzufgen der theor. Dichtefunktion - dick und gestrichelt: curve(dnorm, from = -5, to = 5, add = TRUE, lwd = 3, lty = 2)
Beim Beispiel wird zunchst eine Stichprobe standardnormalverteilter Zufallsvariablen gezogen. Anschlieend wird mit dem Argument las fr kommende Graken die Achsen-
65
0.5
0.4
Dichte
0.3
0.2
0.1
0.0 4 2 0 x 2 4
Abbildung 5.2: Beispielgrak - Histogramm und Dichtefunktion. beschriftung horizontal ausgerichtet (der Standardwert ist derart, dass die Beschriftung parallel zur Achse verluft). Danach wird ein Histogramm der Zufallszahlen erzeugt und mit einer berschrift und y-Achsenbeschriftung versehen. Auerdem werden die Achsengrenzen explizit angegeben, die y-Achse beispielsweise soll sich von 0 bis 0.6 erstrecken. Durch das Argument freq=FALSE wird dafr gesorgt, dass im Histogramm keine absoluten Hugkeiten angezeigt werden. Die Belegung von col mit grey fllt die Flchen mit grauer Farbe. Abschlieend wird mit curve() die Dichte der Standardnormalverteilung (Funktion dnorm()) der Grak hinzugefgt. Dabei wird durch add=TRUE verhindert, dass dieser Plot in einem eigenstndigen Fenster erscheint. Die Begrenzungen der x-Achse werden denen des Histogramms angepasst und die Dichte wird mit einer dicken (lwd = 3), gestrichelten (lty = 2) Linie gezeichnet. Das Ergebnis ist in Abbildung 5.2 zu sehen. Oft ist man in der Situation, mehrere Graken nebeneinander oder untereinander darstellen zu wollen. Dies erreicht man durch Belegung des Argumentes mfrow bzw. mfcol. Bei beiden wird die Anzahl der Zeilen und Spalten angegeben, in die der Grakbereich aufgeteilt werden soll. Dann werden die Teilbereiche nach und nach mit Graken gefllt,
66
bei mfrow zeilenweise, bei mfcol spaltenweise. Folgendes Beispiel soll die Vorgehensweise verdeutlichen: > > > > > + + > par(las = 1, mfrow = c(2,2)) set.seed(123) for (j in 1:4){ x < rnorm(100) hist(x, main = Dichte 100 \n N(0,1)-verteilter Zufallszahlen, freq = FALSE, col = grey, ylab = Dichte, xlim = c(-5, 5), ylim = c(0, 0.6)) curve(dnorm, from = -5, to = 5, add = TRUE, lwd = 3, lty = 2)}
Man beachte, dass der Code vom vorhergehenden Beispiel kaum verndert wurde. Es wurde lediglich das sogenannte Device (in diesem Fall das Fenster, in dem die Grak genet wird) zunchst in zwei Spalten und Zeilen aufgeteilt. Anschlieend wurde in einer Schleife vier mal der Code von vorher reproduziert. Das Ergebnis kann man in Abbildung 5.3 sehen. Die Teilgraken unterscheiden sich voneinander, da der Zufallszahlengenerator nicht vor jedem Schleifendurchlauf initiiert wurde, sondern vor der Schleife.
Dichte 100 N(0,1)verteilter Zufallszahlen
0.6 0.5 0.4 Dichte 0.3 0.2 0.1 0.0 4 2 0 x 2 4 Dichte 0.6 0.5 0.4 0.3 0.2 0.1 0.0 4 2 0 x 2 4
0 x
67
Plotbereich
Plotbegrenzung
Grafikbereich Devicebereich
Grafikbegrenzung
uere Begrenzung
Abbildung 5.4: Aufteilung des Devices. Wenn man mehrere Plots in einer Grak darstellt, kann es sinnvoll sein, allen Plots eine gemeinsame berschrift zuzuordnen. Dazu kann es notwendig sein, die Aufteilung des Fensters, in dem die Grak auftaucht, anzupassen. Standardmig ist das Device in verschiedene Bereiche aufgeteilt: das Device selbst, den Grakbereich und den Plotbereich, wie Abbildung 5.4 verdeutlicht. Dabei ist die Voreinstellung, dass der uere Bereich wegfllt, so dass der Grak mglichst viel Platz eingerumt wird. Fr Abbildung 5.4 wurden mittels par() folgende Voreinstellungen festgelegt: > par(mar=c(5, 4, 3, 2)) > par(oma=c(3, 3, 3, 3)) # Rnder zw Plot- und Grafikbegrenzung # Rnder zw. Grafik- und uerer Begrenzung
Das Argument mar steht fr margin (Rand) und oma steht fr outer margin. Beide geben die Anzahl an Zeilen an, die an den jeweilegen Rndern gelassen werden soll. Dabei steht der erste Wert fr den unteren Rand, dann wird im Uhrzeigersinn weitergezhlt. Im Beispiel wurde also der gesamte uere Rand auf drei Zeilen festgelegt, der Rand zwischen unterer Plotbegrenzung und unterer Grakbegrenzung auf fnf Zeilen, der Rand zwischen linker Plotbegrenzung und linker Grakbegrenzung auf vier Zeilen usw.
68
Die berschrift fr Abbbildung 5.3 lsst sich jetzt folgendermaen umsetzen: Man erweitert das Fenster durch den Aufruf von > par(oma=c(0, 0, 4, 0)) um einen oberen Rand und lsst dann den identischen Code laufen. Abschlieend kann man die berschrift via > mtext(4 Plots der Dichte 100 \n N(0,1)-verteilter Zufallszahlen, + outer=TRUE, cex=1.5) festlegen. Hierbei wurde die Schriftgre auf das 1.5-fache vergrert. Das Ergebnis ist in Abbildung 5.5 zu sehen.
4 Plots der Dichte 100 N(0,1)verteilter Zufallszahlen
69
Bei allen Zuweisungen mit par() ist zu beachten, dass diese die Einstellungen dauerhaft verndern. Deshalb ist es sinnvoll, die Defaulteinstellungen vor einem Plot abzuspeichern. Dies kann durch > old_par < par(no.readonly = TRUE) erreicht werden. Spter kann man die Einstellungen dann durch den Befehl > par(old_par) zurcksetzen.
70
Eine Auswahl an Low-level Grak-Funktionen ist in Tabelle 5.3 aufgefhrt. Die meisten dieser Funktionen sind intuitiv in ihrer Anwendung, weshalb eine kurze Konsultation der zugehrigen Hilfeseite ausreichend ist. An dieser Stelle wird deshalb auf weitere Erklrungen verzichtet. Es soll lediglich das Beispiel aus Abschnitt 5.2 aufgegrien werden. Der Grak soll eine Legende hinzugefgt werden, was durch Erweiterung des Codes um die beiden Zeilen > legend(-4.5, 0.55, legend = c(emp. Dichte, theor. Dichte), + col = c(grey, black), lwd = 5) erreicht werden kann. Durch diesen Befehl wird eine Legende am Koordinatenpunkt [-4.5, 0.55] (linker oberer Rand der Legende) eingezeichnet. Durch Spezizierung des Argumentes lwd wird dafr gesorgt, dass Linien neben den beiden Bezeichnungen emp. Dichte bzw. theor. Dichte auftauchen. Weiterhin wurden den beiden Linien verschiedene Farben entsprechend den Farben im Plot zugeordnet. Das Ergebnis kann man in Abbildung 5.6 betrachten.
Dichte 100 N(0,1)verteilter Zufallszahlen
0.6
0.5
0.4
Dichte
0.3
0.2
0.1
0.0 4 2 0 x 2 4
71
72
Abschlieend soll das Beispiel des Histogramms noch um mathematische Beschriftung erweitert werden. In der linken Hlfte der Grak soll nun zustzlich die Formel fr die Dichtefunktion der Normalverteilung
(x)2 1 f (x) = e 22 2
erscheinen. Weiterhin sollen auf der rechten Hlfte der Grak die Parameter mit ihren Werten angegeben werden. Dazu wird die Funktion text() verwendet und der Code um die folgenden zwei Zeilen erweitert: > text(-5, 0.3, adj = 0, cex = 1.3, + expression(f(x) == frac(1, sigma * sqrt(2*pi)) + e ^{frac(-(x - mu) ^2, 2 * sigma ^2)})) > text(5, 0.3, adj = 1, cex = 1.3, + expression(mit {mu == 0} , {sigma == 1})) Dabei erzeugt adj = 0 rechts (bzw. adj = 1 links) an den angegebenen Koordinatenpunkten ausgerichteten Text. Das doppelte Tildezeichen erhht den Abstand zwischen Bruch und Exponentialfunktion. Das Ergebnis ist in Abbildung 5.7 zu sehen.
Dichte 100 N(0,1)verteilter Zufallszahlen
0.6
0.5
0.4
Dichte
0.3
f(x) =
1 2
(x)2 22
mit = 0, = 1
0.2
0.1
0.0 4 2 0 x 2 4
73
Eine detaillierte Behandlung des Themas soll hier nicht weiter vorgenommen werden. Dazu sei auf das die Hilfeseiten > help(plotmath) > example(plotmath) > demo(plotmath) verwiesen. Auch im Buch von Ligges (2007) und den Literaturangaben dort nden sich weitere Details.
erzeugt. Dabei wurde zunchst das Device zum Erzeugen von Graken im pdf-Format genet. Dabei muss in Klammern der Dateiname inklusive Pfad angegeben werden, unter dem die Grak gespeichert werden soll. In diesem Fall wurde kein Pfad speziziert, so dass die Datei im Arbeitsverzeichnis abgespeichert wurde. Abschlieend wurde das Device mit dem Befehl dev.off() geschlossen. Die Besonderheit bei den beiden Devices pdf() und postscript() ist, dass dort auch mehrere Graken in einem Devices abgespeichert werden knnen. Fr jede neue Grak wird dann eine neue Seite erstellt.
74
Natrlich kann man Graken auch aus der Bildschirmgrak exportieren. Bei einem Rechtsklick auf die Grak erscheinen dann die Mglichkeiten, diese abzuspeichern. Diese Vorgehensweise ist aber nicht zu empfehlen, da die Ausgabedatei abhngig von der Gestalt des Grakfensters in R ist. Weiterhin ist die Auswahl an Speicherformaten beschrnkt.
75
Kapitel 6 Statistik
Bei R handelt es sich um eine Programmiersprache mit starkem Bezug zur statistischen Datenanalyse. Nicht umsonst ist die Homepage von R mit der berschrift The R Project for Statistical Computing versehen. Deshalb darf in einem Skript zu R ein Kapitel zu diesem Thema nicht fehlen. Allerdings handelt es sich bei dem Kurs zu diesem Skript um einen Einfhrungskurs, bei dem auer der Einfhrung in die Stochastik keine weiteren Vorlesungen vorausgesetzt werden. Deshalb wird es in diesem Kapitel nur eine bersicht ber die wichtigsten Befehle geben. Dabei wird vorausgesetzt, dass das Prinzip von Zufallsvariablen, Verteilungen etc. bekannt ist.
76
Befehl beta() binom() cauchy() chisq() exp() f() gamma() geom() unif() hyper() lnorm() logis() multinom() nbinom() norm() pois() t() weibull()
Argumente shape1, shape2, ncp size, prob location, scale df, ncp rate df1, df2, ncp shape, scale prob min, max m, n, k meanlog, sdlog location, scale size, prob size, prob mean, sd lambda df, ncp shape, scale
Tabelle 6.1: bersicht ber einige in R bereitgestellte Wahrscheinlichkeitsverteilungen. Zum Beispiel werden fnf Pseudo-Zufallszahlen1 einer Gleichverteilung auf dem Intervall [3, 5] wie folgt berechnet: > set.seed(123) > runif(5, min = 3, max = 5) [1] 3.575155 4.576610 3.817954 4.766035 4.880935 Hier wurde zunchst der Pseudo-Zufallszahlengenerator mit einem Startwert initiiert, so dass das Ergebnis reproduzierbar ist. Das 25%- Quantil der gleichen Verteilung erhlt man durch > qunif(0.25, min = 3, max = 5) [1] 3.5
1
Auf einem Rechner generierte Pseudo-Zufallszahlen sind natrlich nicht zufllig, sondern mssen anhand von Funktionen berechnet werden. Mehr dazu im Buch von Ligges (2008).
77
Der Wert der Verteilungsfunktion einer Standardnormalverteilung an der Stelle 0 ergibt sich durch den Aufruf > pnorm(0, mean = 0, sd = 1) [1] 0.5 Dabei wre die Spezikation der Werte fr Erwartungswert und Standardabweichung nicht notwendig gewesen, da diese den Voreinstellungen entsprechen.
Stichproben
Zufallsstichproben knnen mit dem Befehl sample erzeugt werden: sample( x, size, replace = FALSE, prob = NULL ) Dabei wird aus dem Vektor x, der die Grundgesamtheit darstellt, eine zufllige Stichprobe der Gre size entnommen. Das Argument replace bestimmt, ob die Ziehung mit oder ohne Zurcklegen geschieht. Wird der Wert prob nicht speziziert, so werden alle Elemente von x mit der gleichen Wahrscheinlichkeit gezogen. Andernfalls muss der Vektor prob die selbe Lnge wie x haben und reprsentiert die Wahrscheinlichkeiten, mit der die einzelnen Elemente gezogen werden. Die folgenden Beispiele sollen die Funktionsweise von sample verdeutlichen: > set.seed(54321) > # Stichprobe aus den Zahlen 1:10 der Gre 4: > sample(10, 4) [1] 5 10 2 8 > sample(10, 4, replace = TRUE) [1] 3 9 1 3 > sample(letters, 5) [1] "i" "j" "d" "p" "a"
78
Hat man nun eine Realisierung {(x1 , y1 ), ..., (xn , yn )} von {(x1 , Y1 ), ..., (xn , Yn )} beobachtet, so werden die Parameter des Modells 0 und 1 mit dem Kleinsten Quadrate Schtzer geschtzt:
n 0 ,1 n 2 i i=1
min
= min
0 ,1 i=1
(yi (0 + 1 xi ))2 .
Es lsst sich zeigen, dass dieses Minimierungsproblem die folgende Lsung besitzt: 1 = wobei x =
1 n n i=1
xi und y =
yi .
79
Die Kleinsten Quadrate Schtzer fr die beiden Regressionsparamter 0 und 1 berechnet R mit lm(y x) Um einer Grak die Regressionsgerade hinzuzufgen wird abline(lm(y x) ) verwendet. Weitere Details zur Anpassung von Modellen an Daten ndet man in Kapitel 7 im Buch von Ligges (2008).
Eine detaillierte Behandlung vieler der aufgefhrten Tests ndet man zum Beispiel im RRZN-Handbuch Statistik mit R - Grundlagen der Datenanalyse.
80
81