Sie sind auf Seite 1von 81

Eine Einfhrung in die Statistik-Software R

Daniel Jones 16. September 2013

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

Aktualitt (Zusatzpakete) weit verbreitet schnelle Hilfe

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.4 Starten von R


Bei Rechnern im Mathebau ist R schon vorinstalliert. Start: Terminal aufrufen und R eingeben Konsole net sich, siehe Abbildung 1.1 Nach dem Prompt (>) werden die Befehle eingegeben. Durch Drcken von ENTER werden diese ausgefhrt.

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

Abbildung 1.1: Screenshot der R Console unter Windows

1.2 R als Taschenrechner


Die blichen Rechenregeln werden natrlich beachtet. Besteht der Imaginrteil einer komplexen Zahl nur aus i muss dieser mit 1i eingegeben werden. Per Voreinstellung zeigt R genau 7 Stellen des Ergebnisses an. Mit options(digits = a) werden a-stellige Ergebnisse (a 22) ausgegeben. Fr eine einmalige Ausgabe eines hherstelligen Ergebnisses bietet sich der Befehl print(Berechnung, digits= a) an. Viele elementare Funktionen sind in R bereits vorporgrammiert (vgl. Tabelle 1.1). Funktionsaufruf geschieht Argument2 = x2,...) wie folgt: funktionsname(Argument1 = x1,

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)

1.6 Der Arbeitsplatz (Workspace)


Ergebnisse von Berechnungen ohne Zuweisung werden direkt in der Konsole ausgegeben, wohingegen Zuweisungen von R gespeichert und im sogenannten Workspace gelagert werden. Befehl ls() rm(Objektname) rm(list=ls()) save(file=Pfadname.RData, O1,..., On) save.image(file=Pfadname.RData) load(Pfadname.RData) q() getwd() setwd(Pfadname) history() Beschreibung Anzeigen aller Objekte im Workspace Lschen eines Objektes aus Workspace Lschen aller Objekte aus dem Workspace Speichert die Objekte O1,..., On in eigenen Workspace Speichert den aktuellen Workspace Laden eines gespeicherten Workspaces Beenden von R Zeigt das Arbeitsverzeichnis an ndert das Arbeitsverzeichnis Anzeige der zuletzt eingegebenen Befehle

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.

1.7 Das Skriptfenster


Das Skriptfenster (nur unter Windows) bietet sich besonders bei der Eingabe von hug verwendeten und langen Befehlen an. Man net es im Men ber Datei Neues Skript. Durch Markieren des Codes und Drcken von Strg+R wird die Funktion dann in der Konsole ausgefhrt. Das Speichern der Skriptdatei geschieht ebenfalls ber das Men, das Laden mit source(Pfadname.r).

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

Kapitel 2 Datentypen und -strukturen


In R ist alles ein Objekt (Vektoren, Matrizen, (...), Funktionen). Je nach Struktur haben die Objekte verschiedene Eigenschaften. In diesem Kapitel sollen die wichtigsten Datenstrukturen vorgestellt werden. Hierbei handelt es sich um eine Art der Darstellung von Daten. Je nach Problemstellung und Art der Daten gibt es verschiedene geeignete Datenstrukturen. Wir werden kennenlernen: Vektoren, Matrizen, Arrays Listen Dataframes

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

Beispiel: mode(3.7) is.complex(3.7) as.complex(3.7) "numeric" FALSE 3.7+0i

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)

# Vektor x wird erweitert

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

# Ausgabe als character

Auch ein Benennen von Elementen eines Vektors ist mglich. > c(WertA = 5, WertB = 4) WertA WertB 5 4 # Benennen der Elemente

2.2.1 Folgen und Wiederholungen


Ist es notwendig, Vektoren mit bestimmtem Regelmigkeiten zu erstellen (zum Beispiel Indexvektoren), so existieren eektivere Mglichkeiten als c(): Befehl a:b seq(Startwert, Endwert, by=Schrittweite ) seq(Startwert, Endwert, length=Lnge ) rep(Objekt, Anzahl der Wiederholungen ) Beispiel: > 4 : 2 [1] 4 3 2 1 0 -1 -2 > seq(-1, 1, by = 0.5) [1] -1.0 -0.5 0.0 0.5 1.0 > rep(c(1,2), 3) [1] 1 2 1 2 1 2 # Ganzzahlige Zahlenfolge Beschreibung Ganzzahlige Zahlenfolge (a, b ) Zahlenfolge beliebigen gleichen Abstands Zahlenfolge mit vorgegebener Lnge Wiederholen desselben Objektes

# Zahlenfolge mit beliebigem Abstand

# 3-maliges Wiederholen des Vektors (1, 2)t

18

> rep(c(1,2), each=3) [1] 1 1 1 2 2 2 > rep(c(1,2,3), 2:4 ) [1] 1 1 2 2 2 3 3 3 3

2.2.2 Rechnen mit Vektoren


Das Rechnen mit Vektoren geschieht komponentenweise. Wenn die Lngen zweier Vektoren nicht bereinstimmen, die Lnge des greren Vektors aber ein Vielfaches der Lnge des kleineren Vektors ist, wird der krzere Vektor so oft wie ntig wiederholt. Stimmen die Dimensionen auch nicht in Vielfachen berein, wird so lange aufgefllt, bis die Dimension wieder passend ist, es erscheint jedoch eine Warnmeldung. > (-2 : 2) 4 [1] -8 -4 0 # komponentenweise 4 8 # Wiederholung des krzeren # Vektors # Wiederholung des krzeren # Vektors mit Warnmeldung

> 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

> (1:3) % [, 1] [1, ] 4 [2, ] 8 [3, ] 12

% t((4:6)) [, 2] [, 3] 5 6 10 12 15 18

# Matrixprodukt: 2. Vektor transponieren!

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

2.2.3 Indizierung von Vektoren


Einzelne, aber auch mehrere Elemente eines Vektors gleichzeitig knnen mit Hilfe der zugerigen Indizes angesprochen werden. Dabei ist es mglich, sich die Werte ausgeben zu lassen, diese aber auch durch neue Werte zu ersetzen. Dies geschieht durch Nachstellen der Indizes in eckigen Klammern. Mchte man also auf das 5. Element des Vektors x zugreifen, so geschieht das durch x[5]. Die Indizierung ist aber nicht auf eine einzelne ganze Zahl beschrnkt:

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

7 5 4 (Reihenfolge!) 7 1 9 3 FALSE FALSE TRUE FALSE TRUE FALSE

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.

2.3.1 Rechnen mit Matrizen


Das Rechnen mit Matrizen erfolgt vllig analog zu dem mit Vektoren. Auch die meisten der Funktionen fr Vektoren funktionieren fr Matrizen. Weitere ntzliche Funktionen sind unter anderem

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

2.3.2 Indizierung von Matrizen


Auch hier gilt die Analogie zu den Vektoren. Auf das Element mit Index (i, j ) der Matrix A greift man mit A[i, j] zu. Mchte man die i-te Zeile betrachten, so geschieht dies ber A[i, ]. Vllig analog fr die j -te Spalte A[ ,j]. Beispiel mit der Matrix B von oben: B[1,2] B[3,1] B[2, ] B[ ,1] 2 5 3 4 4 3 5

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.

3.1 Eigene Funktion denieren


Wir haben R bereits als berdimensionalen Taschenrechner kennengelernt. Hat man nun eine ganze Folge solcher Berechnungen auf einmal durchzufhren und mchte dabei evtl. sogar Parameter und Startwerte variieren, so bietet es sich an, dafr eine eigene Funktion zu schreiben. Eine Funktionsdenition hat die Form Funktionsname< function(Argumente){Befehlsfolge} Der Funktionsaufruf geschieht wie gewohnt: Funktionsname(Argument1 = x1, Argument2 = x2,...). Die Rckgabe einer Funktion knnen beliebige Objekte sein, also zum Beispiel auch Listen. Dies ermglicht es, auch mehrere Objekte zurckzugeben, die unterschiedlichen Typs sein knnen. Beispiel: Mit1 > standardabweichung < function(y) { +
1

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

+ +

sqrt((1 / (n-1)) sum((y-mean(y)) 2)) }

kann die empirische Standardabweichung 1 n1


n

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.

3.2 Bedingte Anweisungen


Oft ist es beim Programmieren notwendig, sogenannte bedingte Anweisungen zu verwenden. Verwendet werden bedingte Anweisungen zum Beispiel zur einfachen Fallunterscheidung

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.

> c(g,h) [1] 3 16

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

repeat{ j < j+1 if (j > 4) break}

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 <

while(j > -1){ j < j+1}

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

while(j < 5){ j < j+1}

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

for(j in M){ print(j2)}

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)

for(j in M){ print(j[1])} 3 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.

3.4 Vektorwertiges Programmieren


In Kapitel 2 wurde bereits angesprochen, dass Vektoren die grundlegende Datenstruktur in R sind. Deshalb sollte man, wann immer dies mglich ist, auch vektorwertig programmieren und Schleifen vermeiden. Natrlich existieren zu dieser Regel auch Ausnahmen, zum Beispiel wenn der Speicherplatz nicht ausreicht. Trotzdem sollte man das vektorwertige Programmieren immer im Hinterkopf haben. Insbesondere sind Funktionen, die in R bereits vorimplementiert sind und vektorwertig arbeiten, immer vorzuziehen. Beispiel (schlecht): > > + d< c(9, -5, 12.5, 0.16) for (i in seq( along = d)) { d[i] < d[i] 2 }

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

> + [1] [1] [1]

for(i in 1 : (dim(A)[1])) print(max(A[i, ])) 4 4 5

Einfacher geht es durch Anwendung von apply(): > [1] apply(A,1,max) 4 4 5

Analog die spaltenweisen Maxima: > [1] apply(A,2,max) 4 5

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:

>

a < sapply(1:n, fun)

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.

4.1 Data frames


Die meisten Datenstze in R sind als sogenannte data frames gespeichert. Dabei handelt es sich um eine spezielle Liste mit der Eigenschaft, dass alle Listeneintrge dieselbe Lnge haben mssen. Insbesondere knnen also unterschiedliche Listeneintrge unterschiedliche Datentypen enthalten. Durch diese Eigenschaften ensteht eine matrixhnliche Struktur, die sich anbietet, um multidimensionale Datenstze zu reprsentieren: Die Spalten der Matrix entsprechen den verschiedenen Variablen, die Zeilen entsprechen den Beobachtungen. Als Beispiel kann man sich Daten zum Verlauf einer bestimmten Aktie vorstellen. In den Spalten stehen die Variablen Tag Tageshoch, Tagestief Schlusskurs etc. Greift man eine bestimmte Zeile heraus, so erhlt man zu einem gegebenen Tag das Tageshoch, das Tegestief sowie den Schlusskurs der Aktie. Um die verschiedenen Mglichkeiten der Operation auf data frames zu veranschaulichen, soll als Beispiel die folgende Einkaufsliste betrachtet werden: > + + + + Einkaufen <- data.frame(Produkt = c(Apfelsaft, Quark, Joghurt, Schinken, Wasser, Wurst, Bier), Abteilung=c(Getrnke, Milchprod., Milchprod., Fleischw., Getrnke, Fleischw., Getrnke), Menge=c(4,2,2,1,3,1,2))

40

So sieht das Ergebnis der Liste aus: > Einkaufen Produkt 1 Apfelsaft 2 Quark 3 Joghurt . . . .

Abteilung Getrnke Milchprod. Milchprod.

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.

4.1.1 Indizierung und Teilauswahl


Wegen der Nhe zur Datenstruktur Liste funktioniert die Indizierung von Dataframes zum einen vllig anaolg zu der von Listen. Zum anderen ist ein dataframe auch eine Art Matrix, weshalb auch diese Indizierung mglich ist. Mchte man zum Beispiel auf das zweite Element des Eintrages Menge zugreifen, so ist dies durch die folgenden Befehle mglich: Einkaufen[[3]][2] Einkaufen$Menge[2] Einkaufen[2,3] Einkaufen[2,Menge] Oft interessiert man sich bei einem Datensatz fr fr eine Teilmenge von Beobachtungen, fr die bestimmte Kriterien erfllt sind. Dazu sind logische Operatoren ntig, hier nocheinmal eine bersicht:

41

R-Code == !< > >= < <= & | !

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

4.1.2 Umbenennen und Lschen von Variablen Umbenennen von Variablen


Wie gerade gesehen, greift man auf die Variablennamen eines Datensatzes mit der Funktion names() zu: > names(Einkaufen) [1] Produkt Abteilung Menge Diese Ausgabe wird von R als Vektor angesehen und kann dementsprechend manipuliert werden. Der Befehl > names(Einkaufen)[3] < Anzahl ndert die Bezeichnung der Variable Menge zu Anzahl: > Einkaufen Produkt 1 Apfelsaft 2 Quark 3 Joghurt . . . .

Abteilung Getrnke Milchprod. Milchprod.

Anzahl 4 2 2 # usw.

Der allgemeinere Lsungsansatz fr diese Zuweisung ist der folgende: > names(Einkaufen)[names(Einkaufen)==Menge] < Anzahl

Lschen von Variablen


Die einfachste Mglichkeit, eine Variable aus einem Datensatz zu lschen, ist ihr den Wert NULL zuzuweisen. Das Lschen der Variablen Abteilung funktiert also wie folgt: > Einkaufen$Abteilung < NULL Zur berprfung das Ergebnis:

44

> Einkaufen Produkt Anzahl 1 Apfelsaft 4 2 Quark 2 3 Joghurt 2 . . . .

# 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.

Sortieren von Variablen


Wir haben in der bung die Funktion sort() zum Sortieren von Vektoren kennengelernt. Mchte man einen Datensatz sortieren, so bietet es sich eher an, mit order() zu arbeiten. Mit dieser Funktion lassen sich die Indizes des ursprnglichen Vektors auslesen, die zur Sortierung bentigt werden. Es gilt folglich sort(y)=y[order(y)]. Hat man die Indizes durch order() gegeben, kann man auch mehrere Spalten gleichzeitig danach sortieren. Soll die Einkaufsliste aufsteigend nach der Menge sortiert werden, so geschieht dies durch > Einkaufen[order(Einkaufen$Menge),] Produkt Abteilung Menge 4 Schinken Fleischw. 1 6 Wurst Fleischw. 1 2 Quark Milchprod. 2 3 Joghurt Milchprod. 2 7 Bier Getrnke 2 . . . . # usw.

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

4.1.3 Hinzufgen neuer Variablen


Mit dem Befehl Preis < runif(7, min=0, max=2) werden 7 auf dem Intervall [0,2] gleichverteilte Zufallszahlen erzeugt. Diese sollen durch Runden auf zwei Nachkommastellen als ktive Preise der Produkte verwendet werden: > (Preis < round(Preis,2)) [1] 0.58 1.58 0.82 1.77 1.88 0.09 1.06 Die Variable Preis kann dem Datensatz nun mit der Funktion data.frame() hinzugefgt werden: > (Einkaufen < data.frame(Einkaufen, Preis)) Produkt Abteilung Menge Preis 1 Apfelsaft Getrnke 4 0.58 2 Quark Milchprod. 2 1.58 3 Joghurt Milchprod. 2 0.82 . . . .

# 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.

4.1.4 Aufteilen und Zusammenfhren von Datenstzen


split() Manchmal mchte man einen Datensatz auf Basis der Merkmalsausprgungen einer bestimmten Variablen aufteilen. Dies wird in R durch die Funktion split() bewerkstelligt. Soll die Einkaufsliste aufgeteilt werden nach Abteilungen, so geschieht dies durch den Aufruf split(Einkaufen, Einkaufen$Abteilung). Das Ergebnis des Aufrufes ist eine Liste:

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

Preis 1.58 0.82

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 Datenimport und Datenexport


Im vorigen Kapitel haben wir gesehen, wie man mit Datenstzen arbeitet. Das Format des Dataframe spielt auch deshalb in R eine groe Rolle, weil viele Datenstze, die zum Beispiel als Excel-Datei abgespeichert sind, bereits diese Grundform besitzen. In diesem Kapitel werden die wesentlichen Mglichkeiten dargestellt, solche externen Datenstze einzulesen, um sie dann in R weiterbearbeiten zu knnen. Auch auf die manuelle Dateneingabe sowie das Exportieren von Daten aus R in andere Dateiformate wird eingegangen.

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.

4.2.2 Einlesen von externen Datenstzen


Im Allgemeinen wird man Daten selten so einlesen, wie es im vorangegangen Kapitel erklrt wurde. In der Praxis kommen die Daten im Regelfall aus anderen Quellen und liegen in Formaten wie .xls, .txt oder .csv vor. In diesem Kapitel werden die gngigsten Mglichkeiten zum Einlesen von externen Datenstzen vorgestellt. ASCII-Dateien Am einfachsten und sichersten ist der Import von externen Daten, wenn sie im ASCII1 Format (z.B. .txt oder .csv) vorliegen.
1

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.

Kann heruntergeladen werden unter http://www.rrzn.uni-hannover.de/buch.html?no_cache=1&titel=statistik_r

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

header FALSE TRUE TRUE

sep , ;

dec . . ,

Die Abkrzung steht fr comma seperated values.

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).

4.2.3 Daten exportieren


Auslesen eines einzelnen Vektors Hat man whrend einer Sitzung einen einzelnen Vektor produziert, auf den man auch auerhalb von R zugreifen mchte, so kann man diesen mit write() exportieren. Mit dem folgenden Befehl erzeugen wir zunchst 100 standardnormalverteilte Zufallszahlen:

> 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.

5.1 High-level Grak


High-level Grak-Funktionen ermglichen es, einen vollstndigen Plot der Daten zu erstellen, die als Argumente an die Funktion bergeben wurden. Je nach Art der Daten werden Axen, Label und Titel automatisch erstellt. Eine bersicht ber einige der Highlevel Grak-Funktionen bietet Tabelle 5.1. Eine der meistgenutzten Funktionen ist dabei plot(). Wie auch bei einigen anderen der High-level Grakfunktionen handelt es sich bei plot() um eine sogenannte generische Funktion. Eine solche Funktion ist derart aufgebaut, dass sie verschiedene Arten von Objekten als Eingabe zulsst und die Ausgabe entsprechend anpasst. Die Art der Grak, die von plot() produziert wird, hngt also von den Eigenschaften des Objektes ab, was als Argument bergeben wird. Beispielsweise wird bei Eingabe von zwei Vektoren gleicher Lnger ein Streudiagramm erzeugt (Scatterplot), bei Eingabe eines lm -Objektes

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.

5.2 Kongurierbarkeit von Graken


Die im Beispiel gesehenen Graken reichen zu einer ersten Analyse der Daten vollstndig aus. Oft ist man aber in der Situation, dass man (zum Beispiel fr Publikationen oder eine Prsentation) Graken noch erweitern bzw. anpassen mchte. Dies kann zum Beispiel geschehen durch Beschriftung (berschriften, Axenbeschriftung, Beschriftung einzelner Punkte, etc.), die Verwendung anderer Symbole, Lininenstrken, Farben, die Vernderung der Skalierung usw. Eine Vielzahl dieser Anpassungen kann erreicht werden, in dem man entsprechende Argumente direkt an die Plotfunktion bergibt. Dazu gehren vor allem die Parameter, die in den Hilfen ?plot und ?plot.default aufgefhrt werden, aber auch ein Groteil der Argumente, die man in der Hilfe ?par ndet. In jedem Fall lohnt sich ein Blick in auf die einzelnen Hilfeseiten, um einen berblick ber die verschiedenen Mglichkeiten zu bekommen. Mit der Funktion par() lassen sich die wichtigsten Grundeinstellungen fr Graken bearbeiten. Im Gegensatz zur direkten bergabe von Parametern an Plotfunktionen ist hierbei zu beachten, dass die Vernderungen durch par() fr alle folgenden Graken gelten. Dies bietet sich an, wenn man mehrere einheitliche Graken hintereinander erstel-

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

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

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

Dichte 100 N(0,1)verteilter Zufallszahlen

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

Dichte 100 N(0,1)verteilter Zufallszahlen

0 x

Abbildung 5.3: Vier Plots in einer Grak.

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

0.6 0.5 Dichte Dichte 4 2 0 x 2 4 0.4 0.3 0.2 0.1 0.0

0.6 0.5 0.4 0.3 0.2 0.1 0.0 4 2 0 x 2 4

0.6 0.5 Dichte Dichte 4 2 0 x 2 4 0.4 0.3 0.2 0.1 0.0

0.6 0.5 0.4 0.3 0.2 0.1 0.0 4 2 0 x 2 4

Abbildung 5.5: berschrift bei mehreren Plots im selben Device.

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.

5.3 Low-level Grak


Low-level Grak-Funktionen stellen eine Erweiterung von High-level Grak-Funktionen dar. Sie dienen unter anderem dazu, Graken zu initialisieren (z.B. durch Bereitstellung eines Koordinatensystems). Weiterhin knnen mit ihrer Hilfe zustzliche Elemente wie Punkte, Geraden oder Beschriftungen in bestehende Graken eingezeichnet werden. Funktionsname abline() arrows() axis() grid() legend() lines() mtext() plot.new() plot.window() points() polygon() qqline() segments() text() title() Erluterung intelligente Linie Pfeile Achsen Gitternetz Legende Linien Text in den Rndern der Grak Initiierung einer neuen Grak Koordinatensystem initialisieren Punkte Polygone fgt eine Gerade in ein Q-Q-Diagramm vektorwertige Linien Text Graktitel

Tabelle 5.3: Auswahl an Low-level Grak-Funktionen.

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

emp. Dichte theor. Dichte

0.4

Dichte

0.3

0.2

0.1

0.0 4 2 0 x 2 4

Abbildung 5.6: Erweiterung der Histogrammgrak um eine Legende.

71

5.4 Mathematische Beschriftung


Bei der Erstellung von Graken mit R besteht die Mglichkeit, mathematische Notation als Beschriftung miteinzubinden. Gerade fr Publikationen im Bereich der Mathematik ist dies von Vorteil. Dabei knnen komplexe Formeln, mathematische Symbole und griechische Buchstaben verwendet werden. Bei den meisten Grakfunktionen (wie z.B. plot()) ist dies immer dort mglich, wo es um Beschriftung geht, also zum Beispiel bei den Argumenten main, sub, xlab und ylab. Mathematische Notation wird in Form von nicht ausgewerteten R Ausdrcken angegeben, dabei werden Formeln nahezu in R Syntax speziziert. In der einfachsten Form lsst sich das durch die Funktion expression() umsetzen. Dabei sind einige SchlsselwrA A ter an L TEX angelehnt, beispielsweise frac(Zhler, Nenner). Wie man es von L TEX kennt, werden griechische Buchstaben in Lateinischer Schrift ausgeschrieben, wobei es auf Gro- und Kleinschreibung ankommt: aus sigma wird , aus Sigma . Die Formel y i = 0 + 1 xi + e kann als Unterschrift beispielsweise durch > plot(1:10, sub = expression(y[i] == beta[0] + beta[1] * x[i] + e)) in eine Grak eingefgt werden. Hug kommt es vor, dass Variablen in Formeln durch ihre Werte ersetzt werden sollen. Ist der Wert bekannt, so kann dies mit expressions() umgesetzt werden. Wird er aber erst innerhalb einer Funktion berechnet und an die Grak bergeben, so funktioniert diese Vorgehensweise nicht mehr. Hier hilft die Verwendung der Funktion substitute(). Im folgenden Beispiel sei das Objekt wert zu einem frheren Zeitpunkt durch Berechnungen erzeugt worden: > wert < 0.5 > substitute(sigma == s, list(s = wert)) sigma == 0.5 Der Funktion substitute() wurde hier neben dem Ausdruck noch eine Liste mit Werten bergeben. Da in dieser Liste ein Objekt mit dem Namen s existiert, wird dieses im Ausdruck entsprechend durch seinen Wert ersetzt. Zurckgegeben wird ein sogenanntes Sprachobjekt2 , welches von Grakfunktionen entsprechend interpretiert werden kann.
2

Mehr Informationen zu Sprachobjekten nden sich im Buch von Ligges (2007)

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

emp. Dichte theor. Dichte

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

Abbildung 5.7: Mathematische Beschriftung in der Histogrammgrak.

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.

5.5 Graken exportieren


Wann imer eine Grak produziert wird, muss ein Device (engl. fr Gert) bestimmt werden, auf dem die Ausgabe erfolgt. Sofern man interaktiv mit R arbeitet, ist dies standardmig das Device fr Bildschirmgrak (X11()). Es ist aber auch mglich, Graken zu exportieren, in dem man andere Devices verwendet, eine bersicht ber einige Devices liefert Tabelle 5.5. Beispielsweise wurde der linke Teil von Abbildung 5.1 durch den Befehl > > > > > pdf(scat.pdf) attach(iris) plot(Petal.Length, Petal.Width, pch = as.numeric(Species)) detach(iris) dev.off()

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

Funktion bmp() jpeg() pdf() pictex() png() postscript()

Dateiformat Bitmap-Datei JPEG-Datei PDF-Datei PicTEX fr LATEX-Dokumente PNG-Datei Postscript-Datei

Dateiendung .bmp .jpeg oder .jpg .pdf .tex .png .ps

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.

6.1 Verteilungen und Stichproben


Verteilungen
R stellt fr viele Wahrscheinlichkeitsverteilungen Funktionen bereit, mit denen sich Werte fr Verteilungsfunktion, Quantile und Zufallszahlen ermitteln lassen. Eine bersicht ndet man in Tabelle 6.1. Die zur Verteilung gehrige Funktion ergibt sich durch Voranstellen eines der folgenden Buchstaben vor den Verteilungsname in R: d (density) Wert der Dichtefunktion an der zugehrigen Stelle. p (probability) Wert der Verteilungsfunktion an der zugehrigen Stelle. q (quantile) Quantil der Verteilungsfunktion. r (random) Zufallszahlen, die der spezizierten Verteilung folgen.

76

Verteilungsname BetaBinomialCauchyChi-QuadratExponentialFGammaGeometrische GleichHypergeometrische LognormalLogistische MultinomialNegative BinomialNormalPoissontWeibull-

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"

# ohne Zurcklegen # mit Zurcklegen # beliebige Objekte

78

6.2 Einfache lineare Regression


Beim einfachen linearen Regressionsmodell Y = 0 + 1 x + mit 0 : Interzeptparameter 1 : Steigungsparameter Y : erklrte Variable (Regressant) x: erklrende Variable (Regressor) (deterministisch) : Residuum (zufllig) wird angenommen, dass zwischen den Zufallsvariablen Y und X ein linearer Zusammenhang besteht. In der Literatur ndet man meist den Fall vor, dass X eine deterministische Gre (zum Beispiel eine Messstelle) ist, und nicht dem Zufall unterliegt. Dies wird in der Gleichung dadurch angedeutet, dass x im Gegensatz zu Y in Kleinbuchstaben geschrieben ist. Ziel der einfachen linearen Regression ist es, die unbekannten Parameter 0 und 1 zu schtzen, um fr neue Messstellen die zugehrigen Y -Werte vorhersagen zu knnen. Aber auch eine Interpretation der Parameter im Hinblick auf den Modellansatz ist mglich. Die Schtzung erfolgt auf Basis einer Stichprobe {(x1 , Y1 ), ..., (xn , Yn )} (wobei die Yi als unabhngig und identisch verteilt wie Y angenommen werden) nach dem Modellansatz Yi = 0 + 1 xi + (i = 1, . . . , n). Die nicht beobachtbaren Residuen identisch N (0, 2 )verteilt.
i i

(i = 1, . . . , n) seien unabhngig und

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 x )(yi y ) 0 = y 1 x und , 2 (xi 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).

6.3 Statistische Tests


An dieser Stelle soll nur der Vollstndigkeit halber eine kurze bersicht an statistischen Tests prsentiert werden: Test binom.test() chisq.test() chisq.test() cor.test() fisher.test() friedman.test() kruskal.test() ks.test() shapiro.test() t.test() var.test() wilcox.test() Befehl Binomialtest 2 -Anpassungstest 2 -Unabhngigkeitstest Test des Korrelationskoezienten nach Pearson exakter Test von Fisher Friedman-Rangsummen-Test Kruskal-Wallis-Rangsummen-Test Kolmogorov-Smirnov-Test (1- und 2-Stichproben) Shapiro-Wilk-Test (Test auf Normalverteilung) t-Test F-Test Wilcoxon-Test (1- und 2-Stichproben)

Eine detaillierte Behandlung vieler der aufgefhrten Tests ndet man zum Beispiel im RRZN-Handbuch Statistik mit R - Grundlagen der Datenanalyse.

80

6.4 Ntzliche Funktionen


Abschlieend seien noch einige Funktionen aufgefhrt, die bei der statistischen Datenanalyse von Nutzen sein knnen: Funktionsname mean() var() sd() cov() cor() min() max() range() quantile() median() mad() IQR() summary() fivenum() Erluterung Mittelwert Varianz Standardabweichung Kovarianz Korrelation Minimum Maximum Vektor mit Minimum und Maximum (Spannweite) Quantil Median (50%-Quantil) Median der absoluten Abweichungen vom Median Interquartilsabstand Min, 25%-Quantil, Median, Mittelwert, 75%-Quantil und Max Min, 25%-, 50%-, 75%-Quantil und Max

81