Upload
mark-heckmann
View
3.203
Download
2
Embed Size (px)
DESCRIPTION
R course for the Bachelor in Psychology at University of Bremen, Germany during winter term 2010/11.
Citation preview
1
Einführung in das R Frame-work
Mark HeckmannUniversität BremenWiSe 2010/11
Was erwarten wir von dem Kurs?
• Von vorne abholen / Grundlagen
• Grafiken erstellen
• Datensätze speichern / erstellen
• Weniger und genauer statt viel oberflächlich
2
Reuter, H. (2002). Über den Umgang mit offenen Fragen. In G. Gniech, H. Reuter & M. A. Stadler (Hrsg.). Lebenswelt und Erleben: Beiträge zur Erfahrungspsychologie. Festschrift zum 65. Geburtstag von Gisla Gniech. Lengerich: Pabst Science Publishers (S. 172-181).
„Auch wenn das Handwerkszeug solcher Forschung sich virtuos etablierter Techniken der Empirie und des Experimentierens bedient (in deutlicher Abgrenzung zur dümmlichen - ingnoranten Aufgabe dieser Instrumente) ...“
Reuter, 2002 , S. 180
3
Reuter, H. (2002). Über den Umgang mit offenen Fragen. In G. Gniech, H. Reuter & M. A. Stadler (Hrsg.). Lebenswelt und Erleben: Beiträge zur Erfahrungspsychologie. Festschrift zum 65. Geburtstag von Gisla Gniech. Lengerich: Pabst Science Publishers (S. 172-181).
„Auch wenn das Handwerkszeug solcher Forschung sich virtuos etablierter Techniken der Empirie und des Experimentierens bedient (in deutlicher Abgrenzung zur dümmlichen - ingnoranten Aufgabe dieser Instrumente) ...“
Reuter, 2002 , S. 180
ACHTUNG!M E T H O D I K ≠M E T H O D O L O G I E
3
4
R-Appetizer
mpg
wt
2
3
4
5
●
●●
●
●
●
●
●
●
●
●
●
●
●
● ●●
●
●
●
●
●●
●
●
●
●
●
● ●
●
●
15 20 25 30
factor(cyl)● 4● 6● 8
5
Jaw-dropping graphics !
rating
density
0.0
0.2
0.4
0.6
0.8
1.0
1.2
2 4 6 8 10
mpaa
NC−17PGPG−13R
6
depth
dens
ity
0.0
0.1
0.2
0.3
0.4
0.5
0.6
56 58 60 62 64 66 68 70
cutFairGoodVery GoodPremiumIdeal
7
8
9
http
://le
arnr
.wor
dpre
ss.c
om/2
009/
04/0
9/gg
plot
2-sa
les-
dash
boar
d/
10
http
://le
arnr
.wor
dpre
ss.c
om/2
009/
04/0
9/gg
plot
2-sa
les-
dash
boar
d/
11
12
http
://le
arnr
.wor
dpre
ss.c
om/2
009/
04/0
9/gg
plot
2-sa
les-
dash
boar
d/
$0$50k
$100k$150k$200k
Revenue
Q1 Q2 Q3 Q4$0
$10k$20k$30k$40k$50k
Profit
Q1 Q2 Q3 Q4
0100200300400
Order Size
Q1 Q2 Q3 Q40
100200300400
New Customers
Q1 Q2 Q3 Q40.00.51.01.52.02.53.0
Customer Satisfaction
Q1 Q2 Q3 Q40%5%
10%15%20%25%
Market Share
Q1 Q2 Q3 Q40%
20%40%60%80%
On−Time Delivery
Q1 Q2 Q3 Q4
$0$20k$40k$60k$80k
$100kChardonnay
Q1 Q2 Q3 Q4$0
$20k$40k$60k$80k
$100kCabernet
Q1 Q2 Q3 Q4$0
$20k$40k$60k$80k
$100kMerlot
Q1 Q2 Q3 Q4$0
$20k$40k$60k$80k
$100kSauvignan Blanc
Q1 Q2 Q3 Q4$0
$20k$40k$60k$80k
$100kZinfandel
Q1 Q2 Q3 Q4
$0$20k$40k$60k$80k
$100kNorth America
Q1 Q2 Q3 Q4$0
$20k$40k$60k$80k
$100kAsia
Q1 Q2 Q3 Q4$0
$20k$40k$60k$80k
$100kEurope
Q1 Q2 Q3 Q4$0
$20k$40k$60k$80k
$100kMiddle East
Q1 Q2 Q3 Q4$0
$20k$40k$60k$80k
$100kSouth America
Q1 Q2 Q3 Q4
North America
Europe
Asia
South America
Middle East
Sales Pipeline
$0 $2k $4k $6k $8k$10k$12k$14k
Probability of Sale
25%
50%
75%
90% The Big Wine StoreWines 'R Us
Fruit of the VineSpirits of the Age
The Beverage CompanySips and Bites
American Vintner's BestBarrel and Keg
CheersHappy Hour
Top 10 Customers
$0 $20k $40k $60k $80k
Sales DashboardAll Currency in USD
13
14
15
DAY 1 Learning grammar
- Basics of the R language
16
Erster Tag = Hürde nehmen
17
18
“Nurse, get on the internet, go to SURGERY.COM, scroll down and click on the ,‘Are you totally lost?‘
icon.“
„Nehmen Sie sich ein Beispiel an Kindern, die das Laufen lernen. Mit der Einstellung von vielen Erwachsenen hätten sie nach dem
ersten Sturz aufgehört und gesagt: "Nee, tut mir leid, auf zwei Beinen gehen ist nicht mein
Ding.“
Dr. Eckart von Hirschhausen 19
ACHTUNG!F l a c h e L e r n k u r v e
R Ressources• R Project Site: www.r-project.org
• Blogs
• www.r-bloggers.com
• http://ryouready.wordpress.com
• eBooks/Wikis/Sites
• Quick-R website
• http://de.wikibooks.org/wiki/GNU_R
• http://addictedtor.free.fr
• R seek (www.rseek.org) 20
Endless on the web!
Basics• R arbeitet im Frage-Anwort Modus
• Navigieren in R Konsole durch Aufwärts und Abwärts Pfeile
• Alles hinter der Raute (#) sind Kommentare und wird von R nicht ausgewertet
• Ein Befehl wird durch ein Semikolon oder durch einen Zeilenumbruch abgeschlossen
• Ein Befehl darf über mehrere Zeilen gehen
• Dezimalstellen sind Punkte, keine Kommas. Kommas haben eine andere Funktion
21
Code : Arithmetik
### Grundlegende arithmetische Operatoren ###
4 + 4! ! ! ! !# Addition4 - 1! ! ! ! # Subtraktion4 / 2! ! ! ! !# Division2 * 2! ! ! ! !# Multiplikation2^2 ! ! ! !! # Potenz2 ** 2!! ! !! # alternative für Potenz5 %/% 2 ! ! !! # Ganzzahlige Division5 %% 2!! ! !! # Modulo Division2 + 2 * 3!! !! # Rechenregeln werden beachtet2 * 2^3! ! !! # (2-1) * (2+2)! ! # Klammern können gesetzt werden wo nötig
22
Code : Zuweisungen### Der Zuweisungsoperator ###
a <- 2 + 2! ! !# Zuweisungsoperator kleiner-Zeichen !# plus minus-Zeichena <- b <- 2 + 2! !# möglich aber unschön!a! ! ! ! !# Variable a enthält nun Wert2 + 2 -> a! ! !# so rum geht es auch, sollte aber !# nicht verwendet werdena = 2 + 2!! !# Zuweisung wird aber klarer durch !# Richtungsangabe des Pfeilsa <- 100! ! !# keine Warnung, wenn eine Variable !# übergespeichert wirda * 10a <- "Ich bin der Inhalt"!# Variablen sind nicht typensicher, !# d.h. sie können Zahlen, Buchstaben !# etc. enthaltena * 10!! ! !# Fehler, da Zeichen mal Zahl
23
Objektbezeichnungen I
• Variablen- / Objektbenennung: können alphanumerisch sein sowie, Punkte und Unterstriche enthalten
object1 <- 10
object1.1 <- “hallo“
object1_1 <- 10
• Darf keine Operatoren enthalten (+, - *, / etc.)
object-1 <- “hallo“
• Objektname darf nicht mit Zahl beginnen bzw. Punkt
24
Objektbezeichnungen II
• Objektname darf nicht mit Zahl beginnen bzw. Punkt gefolgt von einer Zahl
1object <- 10
.1object <- “hallo“
• Groß- und Kleinschreibung wird unterschieden (Nutzung zum Strukturieren von Objektnamen)
myObject <- 10
myobject <- 11
25
Code : Bezeichnung & Stil
neueVariable1 <- 7 neueVariable2=neueVariable1+2! ! # kaum lesbar! schlechter ! ! ! ! ! ! ! ! ! ! ! # Stil!neueVariable2 <- neueVariable1 + 2!# besser, sauber getrennt
Ein R-Styleguidehttp://google-styleguide.googlecode.com/svn/trunk/google-r-style.html
26
Code : Logik I# Logische Operationen
1 == 2!! ! ! # logischer Vergleich1 != 2 ! ! ! # ist ungleich?1 > 2 !! ! ! # 1 größer 2?1 >= 2 ! ! ! # 1 größer gleich 2?1 < 2 !! ! ! # 1 kleiner 21 <= 2 ! ! ! # 1 kleiner gleich 2! 1 <= 2! ! ! # Negierung von 1 kleiner gleich 2
# logisches UND
TRUE & TRUE! ! # TRUETRUE & FALSE!! # FALSEFALSE & TRUE!! # FALSEFALSE & FALSE! # FALSE
27
Code : Logik II
# logisches ODER
TRUE | TRUE! ! # TRUETRUE | FALSEFALSE | TRUEFALSE | FALSE
# KurzformenT !! ! ! ! # Kurzform von TRUEF! ! ! ! ! # Kurzform von FALSE
T | FT & T
28
Funktionen IFunktion (lat. functio = Tätigkeit, Verrichtung)
z.B.:
c() steht für concatenate (verbinden, verketten)
> a <- c(1,2,3)> a[1] 1 2 3
rnorm() für random normal distribution > rnorm(4) [1] -0.3628728 -0.4580532 -1.3729865 -1.5834625
29
Funktionen IIDie Angaben innerhalb einer Klammer von Funktionen heißen Argumente.
> rnorm(4) [1] -0.3628728 -0.4580532 -1.3729865 -1.5834625
Jede Funktion hat ein definiertes Set an Argumenten,die sie verarbeiten kann (s. Dokumentation)
> ?rnorm
Um sich alle möglichen Argumente anzeigen zu lassen> args(rnorm)
30
Funktionen IIIJede Funktion gibt ein Objekt zurück> c(1,2,3)[1] 1 2 3
Ggf. kann dies auch unsichtbar geschehenv <- rnorm(100)hist(v)
a <- hist(v) # Rückgabe der Funktion speicherna
Falls eine Funktion nichts spezifisches zurückgibt,gibt sie ein NULL Objekt (leer) zurück
a <- plot(1:10)a
31
32
“Nurse, get on the internet, go to SURGERY.COM, scroll down and click on the ,‘Are you totally lost?‘
icon.“
### HELP R ###
help.start()!! ! # Hilfe aufrufen. Auch über das # Menü möglich?mean! ! ! ! ! # Hilfe zur Funktion "mean"help(mean)! ! # identisch! !help("mean")!! # identisch! !
33
Hilfe!Die allerwichtigste Funktion!
R-help
Leer
R-help = an R-user best friend !
34
Code : Vorgriff Datentyp Vektor
# Vorgriff auf Datentyp Vektoren (mehr später)
c()!! ! ! ! ! # concatenate (deu. "verbinden")?cc(1,2,3)! ! ! ! # numerischer Vektor! ! ! ! ! ! # Zahl am Anfang des Outputs gibt # Nr. des Elements a <- c(1,2,3)! ! # Speichern in einer Variablenc(a,a)!! ! ! ! # Verknüpfen von zwei Variablenc(1,2,a)! ! ! ! # Verknüpfen von Zahlen und Variablenb <- c(1,2,a,c(1,1))! # flexible Verknüpfungen sind möglich
d <- c(eins=1, zwei=3)!# named vector, die Elemente haben Namen
35
Code : Sequenzen # Vektorsequenzen erzeugen
?seqseq(from=1, to=5)! ! # Sequenz von 1 bis 5seq(from=1, to=5, by=.5) # von 1 bis 5 in Schritten von 0.5seq(1,20)!! ! ! # von eins bis 201:20 ! ! ! ! ! # Kurzschreibweise10:20! ! ! ! ! # von 10 bsi 20(-10):10! ! ! ! # von -10 bis 10
?reprep(x=1, times=10)rep(x=c(1,2), times=10)rep(x=c(1,2), times=c(3,5))rep(x=c(1,2), each=2)rep(x=c(1,2), each=2, times=10)rep(x=c(1,2), each=2, length=8)
36
[1] 10 9 8 7 6 5 4 3 2 1
[1] 1 1 1 1 1 1 1 1 1 1
[1] 1 2 1 2 1 2 1 2 1 2
[1] 1 1 1 1 1 2 2 2 2 2
[1] 1 1 1 1 2 2 2 3 3 4
Your turn!Erzeuge folgende Vektoren, mit jeweils mit 10 Elementen
37
Code : Wichtige Funktionen
# Wichtige Funktionen
a <- c(1.2, 3.3, 6.1, 4.6)max()! ! # Maximum min()! ! # Minimumsqrt()!! # Quadratwurzelround()! ! # rundensum()! ! # Summemean()!! # Mittelwert
length()! # Länge des Vektorsrnorm()! ! # zufällige NV Werte generieren
38
Your turn!
39
1. Erzeuge einen zufälligen Vektor mit der Länge 10 (Tip: benutze die Funktion rnorm())
2. Berechne den Mittelwert mit Hilfe der Funktionen sum() und length()
3.! Berechne den Mittelwert noch einmal mit der Funktion mean()
Remember:help.start()
Code : Konstanten
# in R eingebaute Konstanten
LETTERS! ! ! # Großbuchstaben von A bis Zletters! ! ! # Kleinbuchstaben von a bis zmonth.name! ! # englische Monatsnamenmonth.abb!! ! # englische Monatsnamen abgekürztpi!! ! ! ! # die Zahl Pi
40
Code : Strings
# Umgang mit Strings / Zeichen
?paste!! ! ! ! # Konvertierung in characters und verbindenpaste(1)! ! ! ! ! ! ! ! ! ! ! !paste(1:3)paste(1, "A")paste(c(1:3), c("A", "B", "C"))!! # Vektorweisepaste(c(1:3), c("A", "B"))! ! ! # recycling des kürzeren # Vektors bei ungleicher Längepaste(1, "A", sep="")! ! ! ! ! # Seperatorzeichen festlegenpaste(c(1:3), c("A", "B", "C"), sep="_")! # Seperator festlegenpaste(c(1:3), c("A", "B", "C"),
sep="_", collapse=" ")! ! # Trennzeichen zum Kollabieren
41
"January is month number 1" "February is month number 2" "March is month number 3" "April is month number 4" "May is month number 5" "June is month number 6" "July is month number 7" "August is month number 8" "September is month number 9" "October is month number 10" "November is month number 11" "December is month number 12"
Your turn!Erzeuge folgende Ausgabe in der Konsole, indem
Du paste() und die Konstante month.name nutzt.
42
Code : vectorwise# Vektorwertiges Arbeiten
a <- 1:3b <- 3:1a - b! ! ! ! ! ! # Vektorweise Substraktiona * b! ! ! ! ! ! # Vektorweise Multiplikation
c(1,2,3,4) - c(1,2)!! ! # Was kommt da raus?
x <- c(4.1, 5.0, 6.35) * 2! !# Multiplikation für !# jedes Elementx + 5:7! ! ! ! ! ! # Addition für jedes Element3:5 - 1:6!! ! ! ! ! # Recycling3:5 - 2:3!! ! ! ! ! # Recycling mit Warnung
43
Code : Zugriff
# Zugriff auf Elemente eines Vektors
b <- c(1,2,3,4,5)! ! ! # numerischer Vektorb[1]! ! ! ! ! ! ! # erstes Elementb[c(1,2,3)]! ! ! ! ! # Elemente 1,2,3b[1:3]!! ! ! ! ! ! # Elemente 1,2,3
44
Editoren nutzen
Windows Tinn-R
R Editor
Mac OS Textmate
Datei wird als .R Datei gespeichert und kann so immer wieder genutzt werden
45
Code : Anwendung BMI I
### BMI BEISPIEL FÜR INTERAKTIVE NUTZUNG ###
68/1.70^2 !! ! ! ! ! # Body Mass Index. myBmi <- 68/1.70^2!! ! ! # Wert in ein Objekt speichernmyBmiweight <- c(68, 50, 88, 73)! # Vektor mit Gewichtsdatenweightheight <- c(1.70, 1.63, 1.90, 1.78) # Vektor mit Größen in mheight68 / 1.70^2! ! ! ! ! ! ! # BMI für die erste Personweight[1]/height[1]^2! ! ! ! # BMI für die erste Person
# Wie berechne ich nun den BMI für alle?bmi <- weight/height^2!! ! ! # vektorwertig, intuitiv?
46
Code : Anwendung BMI II
### Standardabweichung "zu Fuss" berechnen
sum.bmi <- bmi[1] + bmi[2] + bmi[3] + bmi[4]!! # Summe der Wertemean.bmi <- sum.bmi/4! ! # Mittelwertsum(bmi)! ! ! ! ! ! # Summesum(bmi)/4! ! ! ! ! # Mittelwertmean(bmi)!! ! ! ! ! # Mittelwert
length(bmi)! ! ! ! ! ! ! ! ! ! # Länge des Vektorssum(bmi)/length(bmi)! ! ! ! ! ! ! # Durchschnitt
47
Code : Anwendung BMI III (bmi[1] – mean.bmi)^2 + (bmi[2] – mean.bmi)^2 + (bmi[3] – mean.bmi)^2 + (bmi[4] – mean.bmi)^2! # SSQ
(bmi - c(mean.bmi, mean.bmi, mean.bmi, mean.bmi))^2
# wie kann ich es einfacher schreiben ?
bmi2 <- (bmi – mean.bmi)^2! ! # mit recycling!!bmi2.sum <- sum(bmi2)! ! ! ! # SSQn <- 4!! ! ! ! ! ! ! ! # Anzahl Wertesd.bmi <- sqrt(bmi2.sum / n-1)! # Wurzel aus SSQ geteilt # durch n-1n <- length(bmi)! ! ! ! ! # Anzahl Werte berechnen
sd.bmi <- sqrt(sum(bmi – mean.bmi)^2)/n-1)
sd(bmi)! ! ! ! # so ist es natürlich viel einfacher
48
Take along!
Selbst wenn etwas nicht in R nicht existiert, kann man es sich
selber programmieren!
49
x <- c(-2,-1,-1,0,1,1,2)y <- c(-1,-2,1,0,2,-1,1)
Your turn!Berechne die geschätzte Kovarianz für folgende
zwei Datenreihen in R „zu Fuß“
50
Code : Navigieren
# Projektordner anlegen /RCourse
# Navigieren in Verzeichnissen
getwd() !! ! ! ! # Unterschied Slash/Backslash Windowssetwd() ! ! ! ! ! # Arbeitsverzeichnis setzensetwd("/Users/markheckmann/")
!! # in Verzeichnis RCourse wechselnsetwd("..") ! ! ! ! # ein Verzeichnis runtersetwd("markheckmann")! ! # ein Verzeichnis hochsetwd("../markheckmann")! # eins runter und wieder eins hoch
51
Your turn!Lege ein Verzeichnis RCourse an (nicht über R) und setze es als neues Arbeitsverzeichnis in R. Lege einen Unterordner data an und wechsele in ihn. Wechsel anschließend wieder in den übergeordneten Ordner.
52
Code : Arbeitsbereich sichern / laden
### Workspace speichern ###
?save.image()
save.image("erster Kurstag.RData")!# Arbeitsbereich speichern
ls()! ! ! ! ! ! # Alle Objekte im Arbeitsbereich !# anzeigenrm()! ! ! ! ! ! # Objekte aus Arbeitsbereich löschenrm(list=ls)! ! ! ! # Alle Objekte aus Arbeitsbereich löschen
load("erster Kurstag.RData")!! # den zuvor gespeicherten ! # Arbeitsbereich ladenls()! ! ! ! ! ! ! ! ! # Objekte sind wieder da
53
Code : Vektoren I
### vector – eindimensionales Datenobjekt ###
a <- c(T, F, T, F)!! ! ! # logischer Vektora <- c(1,2,3,4,5)! ! ! ! # numerischer Vektora <- c("A", "B", "C")! ! ! # character Vektor
c(TRUE, 2, FALSE)! ! ! ! # innerhalb eines Vektors stets # nur ein Typ möglich
c(T, "A", 1)!! ! ! ! # Automatische Umwandlung auf # niedrigstes mögliches Datenniveau
54
Code : Vektoren II
# Zugriff auf eine Elemente durch eckige Klammern
a[1]! ! ! ! # Zugriff auf erstes Element des Vektorsa[c(1,2)]!! ! # Zugriff auf die ersten beiden Elementea[c(2,1)]! !! # umgekehret Reihenfolge
a[c(T,F,F)]! ! # Zugriff durch TRUE/FALSE Vektora[c(T,F)]!! ! # Wieso 2 Elemente?
b <- c(a=1, b=2, c=3)! # Erstellen eines "named" vectorsnames(b)! ! ! ! !# Namen der Vektorelemente anzeigenb["c"]!! ! ! ! !# Zugriff nun auch über den Namen des !# Elements möglich
a[-1]! ! ! ! ! # negatives Indizierena[c(-1,-2)]! ! ! ! # negatives Indizieren
55
Code : Vektoren III
x <- c(NA, 1, 2, NA, 99)! # Vektor mit missing values (NA)x == 1!! ! ! ! ! !# welcher Eintrag ist gleich 1x > 1! ! ! ! ! ! !# welche Einträge sind größer 1x == NA! ! ! ! ! !# welcher ist NA? so falschis.na(x)! ! ! ! ! !# Funktion is.na() nutzenwhich(is.na(x))!! ! !# Einträge mit welchem Indizes sind NA?x[!is.na(x)]!! ! ! !# Einträge auswählen, die nicht NA sindx[x==99] <- NA! ! ! !# Einträge der Zahl 99 mit NA ! ! ! ! ! ! ! ! # überschreiben
56
Oftmals wird 99 oder 999 als Platzhalter für missing values benutzt. Ersetze alle Werte des Vektors, die 99 oder 999 sind mit NA.
x <- c(1,4,3,99,4,3,999,99,3,6,999)
Your Turn!
57
v <- 1:10
Setze alle Elemente des Vektors v, die kleiner gleich 3 sind auf 0, alle die zwischen 4 und 7 sind auf 1 und alle größer sieben auf NA.
[1] 0 0 0 1 1 1 1 NA NA NA
Your Turn!
58
Code : Matrix I
### matrix – zweidimensionales Datenobjekt ###
?matrixmatrix(1:12, nrow=3, ncol=4)!! ! ! # Matrix erstellenmatrix(1:12, nrow=3, ncol=4, byrow=TRUE)! # Matrix reihenweise
e <- matrix(c(1,0,0,0,1,0,0,0,1), 3, 3)! ! # Einheitsmatrixdiag(3)! ! ! ! ! ! ! # Einheitsmatrix per Funktion
is.matrix()
59
Erzeuge eine Matrix M mit 20 Spalten und den folgenden Zeileneinträgen:
Zeile 1: 1, 2, ..., 20 Zeile 2: Zahlen zwischen 2 und 40 mit Abstand 2 Zeile 3: Spalte 1-10 mit Eintrag 1, Spalte 11-20 mit Eintrag 2 Zeile 4: 1,1,2,2,1,1,2,2,... Zeile 5: 1,1,2,2,3,3,4,4,4,4,5,5,5,5,6,6,6,6,6,6 Zeile 6: 1,2,2,2,3,3,3,3,3,3,1,2,2,2,3,3,3,3,3,3
Quelle: Foliensatz von Peter Ruckdeschel / Matthias Kohl. R/S-plus für Einsteiger und Fortgeschrittene
Your Turn!
60
Code : Matrix II# auf Matrixelemente zugreifen
x[1,1]!! ! ! ! # Element erste Zeile, erste Spaltex[ ,1]!! ! ! ! # komplette erste Spaltex[ ,1:2]! ! ! ! # komplette erste und zweite Spaltex[1, ]!! ! ! ! # komplette erste Zeilex[1:2, 2:3]! ! ! # erste & zweite Zeile, zweite & dritte # Spaltex[c(1,3), c(2,4)]
x[-1, -2]!! ! ! # negatives Indizieren; ohne Zeile 1 # und Spalte 2
x > 5! ! ! ! ! # welche Elemente sind größer 5is.na(x)! ! ! ! # Welche Einträge der Matrix sind NA?
61
Code : Matrix III
# Matrixelemente verändernx[1,1] <- 10!! ! # Zahl zu einer Zelle zuweisenx[ ,1] <- 10!! ! # Zahl zu Spalte zuweisen mit # Recyclingx[1, ] <- 10!! ! # Zahl zu Zeile zuweisen
x[1, 2:3] <- c(100,100)! # Zwei Zellen verändern
62
Code : Matrix IV# Zeilen und Spaltennamen hinzufügen
colnames(x)! ! ! ! # Spaltennamen anzeigenrownames(x)! ! ! ! # Zeilennamen anzeigencolnames(x) <- c("Winter", "Frühling", "Herbst", "Winter")! # Spaltennamen setzenrownames(x) <- c("A", "B", "C")! # Zeilennamen setzen
x[, "Winter"]! ! ! ! ! # Zugriff über Namenx[, c("Winter", "Frühling")]!x[, c(1, "Winter")]!! ! ! # geht nicht, da 1 in einem # String konvertiert wird!
rownames(x) <- NULL # Zeilennamen löschen
colnames(m)! ! ! ! ! # Spaltennamencolnames(m)[4]! ! ! ! # Viertes Elementcolnames(m)[4] <- "April"!# Viertes Element verändernm 63
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov DecWoche 1 0 0 1 1 0 3 0 -1 0 -1 -1 0Woche 2 -2 -1 1 0 0 0 1 1 2 -2 -1 -1Woche 3 -1 2 -1 -1 -3 0 3 3 1 -1 0 -1Woche 4 1 0 -2 0 0 0 1 2 1 0 0 0Woche 5 1 1 1 -2 0 -1 1 0 -2 0 0 -2Woche 6 0 0 0 -1 -1 0 0 1 1 1 -1 0Woche 7 1 1 -1 -1 -1 0 0 0 0 -1 1 -1Woche 8 0 1 -3 0 -1 1 2 0 -1 0 0 0Woche 9 -1 0 0 0 -1 0 0 0 2 -1 0 1Woche 10 -1 1 1 0 0 1 0 0 0 1 0 1Woche 11 0 -2 0 0 0 0 0 0 1 0 1 0Woche 12 -1 0 1 -2 -1 -1 0 2 1 1 1 -2Woche 13 2 3 -1 -1 2 1 0 0 1 2 0 -1Woche 14 0 0 0 1 -1 -1 -2 -1 0 1 1 1Woche 15 -1 0 0 1 0 1 -1 0 -1 0 -1 -2Woche 16 0 1 0 -1 0 2 0 -1 -2 -2 -2 -2Woche 17 -1 0 0 -1 0 3 1 1 0 -1 -2 0Woche 18 0 1 -1 0 1 1 -2 -1 2 0 -1 1Woche 19 -3 0 1 1 -2 -2 0 0 1 -2 1 -1Woche 20 2 1 0 -1 2 0 0 1 1 0 -1 2
Your turn!Erstelle folgende Matrix (mit zufälligen Werten):
Tip: nutze rnorm() und round()
64
Code : Matrix V
# Reihenfolge der Spalten der Matrix ändernm[, c(1,3,5,7,9,11,2,4,6,8,10,12)]!!index <- c(1,3,5,7,9,11,2,4,6,8,10,12)m[, index]m[, c(12:1)]
65
Code : Matrix VI# Matrizen verbindencbind ! ! ! # verbinden der Spalten (gleiche Zeilenanzahl # nötig)cbind(m, m)! # m mit m verbinden!! !cbind(m[1:3, 1:3], m[1:3, 9:12])!cbind(m[1:2, 1:3], m[1:4, 1:3])!! # Ungleiche Zeilenanzahl
rbind # verbinden der Zeilen (gleiche # Spaltenanzahl nötig)rbind(m, m)! ! ! ! ! # m zweimal untereinanderrbind(m[1:3, 1:3], m[18:20, 1:3])! # Oberen und unteren # Teil von m verbindenrbind(m[1:3, 1:3], m[18:20, 3:5])! # Achtung Spaltennamen der # ersten Matrix werden genutzt
66
1) Erzeuge eine Matrix M mit 7 Spalten und 7 Zeilen aus zufälligen NV-Werten, die auf eine Stelle gerundet werden.
2) Die Zellen sollen nun durch 999 ersetzt werden:(Zeile, Spalte) (1,1) (4,3) (4,4) (1,7)
3) Alle Einträge die 999 enthalten sollen NA gesetzt werden.
Quelle: Foliensatz von Peter Ruckdeschel / Matthias Kohl. R/S-plus für Einsteiger und Fortgeschrittene
Your Turn!
67
68
69
DAY 2 From ABC to sentences - getting started with data analysis
70
71http://people.hofstra.edu/steven_r_costenoble/MontyHall/MontyHallSim.html
Monty-Hall-Dilemma
72
Angenommen Sie befinden sich in einer Spielshow und haben die Wahl zwischen drei Toren. Hinter einem Tor ist ein Auto, hinter den anderen sind Ziegen. Das Auto und die Ziegen sind vor der Show zufällig hinter die Tore verteilt worden. Die Regeln der Spielshow sind folgende: Nachdem Sie ein Tor gewählt haben bleibt dieses zunächst geschlossen. Der Showmaster Monty Hall, der weiß was sich hinter den Toren befindet, muss nun eine der beiden verbleibenden Tore öffnen, und hinter dem von ihm geöffneten Tor muss sich eine Ziege befinden. Wenn hinter beiden verbleibenden Toren jeweils eine Ziege steht, öffnet er eines der beiden Tore zufällig. Nachdem Monty Hall ein Tor mit einer Ziege geöffnet hat fragt er Sie, ob Sie bei Ihrer ersten Wahl bleiben oder zum letzten verbleibenden Tor wechseln möchten. Nehmen Sie an Sie wählen Tor 1 und der Showmaster öffnet Tor 3 mit einer Ziege. Er fragt Sie dann: „Möchten Sie zu Tor 2 wechseln?“ Ist es zu Ihrem Vorteil, Ihre Wahl zu ändern?
Code : Matrix VII### Rechnen mit Matrizen
A <- matrix(c(1,3,2,5,2,3,1,2,3), ncol=3)At(A)! ! ! ! ! # transponieren einer MatrixA + A! ! ! ! ! # Zellenweise AdditionA * 4! ! ! ! ! # Jede Zelle mal vierA * A! ! ! ! ! # Zellenweise MultiplikationA^2!A %*% A! ! ! ! # MatrixmultiplikationAinv <- solve(A)! # Inverse einer quadratischen MatrixA %*% Ainv! ! ! # Inverse Mal Matrix = EinheitsmatrixAinv %*% A! !A %*% solve(A)
rbind(A, A)! ! ! ! # Zeilen verbindencbind(A, A)! ! ! ! # Spalten verbindencbind(A, rep(1,3))!! # eine Spalte anhängen
rbind(A, A) %*% cbind(A, A)! # Beispiel 73
74
74
Geek Humor!
x <- c(-2,-1,-1,0,1,1,2)y <- c(-1,-2,1,0,2,-1,1)
Beachte: die Designmatrix X enthält eine Spalte mit Einsen für die Konstante!
Your turn!Berechne den Vektor b der Regression y
regrediert auf x in Matrizenform
75
Zur Kontrolle:m <- lm(y ~ x)summary(m)
Code: Faktoren ### factors - für qualitativ unterschiedliche Merkmale
val <- c(1,2,1,1,1,2,3,3)! ! ! ! # neuer Vektorf <- factor(val)fg <- factor(val, levels=1:5)! ! ! # factor erzeugen mit g ! # Levels 1 bis 5
levels(f)! ! ! ! ! ! ! # Bezeichnung der Levelslevels(f) <- c("Treatment 1", "Treatment 2", "Control") f !! # Neue Level Bezeichnungen
factor(c("male", "female", "male", "male")
# Umwandeln eines vector in factorx <- c(1,1,2,2,3,3)! ! ! # neuer Vektorx <- as.factor(x)!! ! ! # umwandeln in factorxlevels(x)! ! ! ! ! !# Bezeichnung der Levelslevels(x) <- c("Treatment 1", "Treatment 2", "Control") ! # Neue Level Bezeichnungen 76
[1] Gruppe 4 Gruppe 4 Gruppe 4 Gruppe 4 Gruppe 3 Gruppe 3 Gruppe 3 Gruppe 2 Gruppe 2 Gruppe 1Levels: Gruppe 1 Gruppe 2 Gruppe 3 Gruppe 4
Your turn!Erzeuge einen factor der folgenden Form:
77
Code: data frames Idata frames
In Matrizen müssen alle Einträge vom selben Typ sein. Z. B. alles numerisch oder alles characters. data frames können pro Spalte unterschiedliche Typen enthalten (Faktoren, numerische Werte, Zeichenketten). Sie müssen jedoch stets dieselbe Anzahl von Einträgen pro Spalte aufweisen.
treat <- c(20, 21, 23, 18, 30)control <- c(19, 21, 20, 23, 18)
d <- data.frame(treat, control)d$treat! ! ! ! ! ! ! # Zugriff mit Dollaroperatord[["treat"]]!! ! ! ! # gibt Vektor zurückd[,1]d[[1]]
78
Code: data frames II### Zugriff auf Elemente eines data frames
d["treat"]! ! ! ! # gibt data frame zurückd[1]
d[1:3, ]! ! ! ! ! # Zeilen 1 bis 3, alle Spaltend[1:3, 1:2]! ! ! ! # Zeilen 1 bis 3, Spalten 1 und 2d[1:3, c("treat", "control")]! # identisch
d[-1,]!! ! ! ! ! # ohne erste Zeiled[-(1:2), -1]! !# ohne erste beiden Zeilen, ohne !# erste Spalte
### Erweiterung des data frames um einen factor
f <- factor(c("m", "m", "w", "w", "w"))data.frame(Geschlecht= f, treat, control)
79
Geschlecht Intervention IQ BMI1 m Control 94.8 22.52 m Treat 113.1 19.63 m Placebo 107.1 24.34 m Control 108.8 9.25 m Treat 102.4 24.56 m Placebo 104.8 23.07 m Control 90.6 17.98 m Treat 102.9 18.09 m Placebo 105.4 17.710 m Control 105.4 14.411 w Treat 107.9 16.012 w Placebo 108.8 18.913 w Control 93.7 19.514 w Treat 113.8 19.415 w Placebo 70.7 16.416 w Control 79.1 21.817 w Treat 116.5 22.318 w Placebo 106.3 19.219 w Control 133.6 20.420 w Treat 79.2 23.3
Your turn! konstruiere folgenden data frame:
(IQ normalverteilt um 100 mit sd=15; BMI normalverteilt um 20, sd=5)
80
Code: Subsets I### data frames subsetting
d[4]! ! ! ! ! ! # Auswahl der vierten Spalted[1:3]!! ! ! ! ! # Spalten 1 bis 3d[c("Geschlecht", "IQ")]! # Nur Geschlecht und IQd[-1]! ! ! ! ! ! # alle Spalten bis auf ersted[c(T,F,T,F)]! ! ! ! # Jede zweite Spalted[c(T, F)]! ! ! ! ! # Jede zweite Spalted[c(F, T)]! ! ! ! ! # Jede zweite Spalte
d["IQ"] > 107! ! ! ! # Welche IQ Werte sind > 107index <- d["IQ"] > 107!! # in Index speichernd[index, ]! ! ! ! ! # Zeilen auswählen mit IQ > 107cbind(d, d$IQ > 107 )! ! # Spalte anfügen, die zeigt, ob
# IQ Werte größer 107 sind
81
IQ BMI Geschlecht Intervention1 109.9 18.9 m Control3 101.2 18.7 m Placebo5 111.4 14.7 m Treat7 104.6 17.3 m Control9 103.7 24.9 m Placebo11 97.1 16.0 w Treat13 89.7 28.7 w Control15 103.2 20.5 w Placebo17 86.6 29.4 w Treat19 89.6 28.3 w Control2 109.1 18.7 m Treat4 110.1 18.0 m Control6 110.3 22.2 m Placebo8 123.5 23.2 m Treat10 107.6 17.8 m Control12 104.2 20.1 w Placebo14 69.2 21.1 w Treat16 96.9 31.0 w Control18 103.9 14.5 w Placebo20 96.4 17.5 w Treat
Your turn!Baue den vorher erzeugten Datensatz um: a) erst die
ungeraden, dann die geraden Zeilen b) neue Spaltenreihenfolge
82
Code: Subsets IInames(d)! ! ! ! ! # Spaltennamen des Datensatzesnames(d)=="IQ"! ! ! # welche Namen sind gleich "IQ"d[names(d)=="IQ"]! ! # subsetting mit logischem Vektornames(d)!="IQ"! ! ! # welche Namen sind nicht "IQ"?d[names(d)!="IQ"]! ! # Spalten, die nicht "IQ" sind auswählend[ ,names(d)!="IQ"]!! # Identisch
index <- d$IQ > 100 & d$Geschlecht=="m" ! # welche Fälle sind Männer mit einem IQ > 100d[index, ]! ! # auswählend[d$Intervention=="Control" | d$Intervention=="Treat",]! ! ! # Intervention ist Control oder Treatd[d$Intervention %in% c("Control", "Treat"),]! ! ! ! ! # alternative Schreibweise
83
Geschlecht Intervention IQ BMI11 w Treat 123.8 21.514 w Treat 96.3 28.517 w Treat 104.3 20.420 w Treat 94.8 14.5
Your turn!Wähle aus dem Datensatz alle Fälle aus, die weiblich sind
und zur Treatmentgruppe gehören
84
Geschlecht Intervention IQ BMI1 m Control 109.9 18.92 m Treat 109.1 18.74 m Control 110.1 18.05 m Treat 111.4 14.76 m Placebo 110.3 22.28 m Treat 123.5 23.210 m Control 107.6 17.8
Your turn!Wähle aus dem data frame jene Fälle aus, die einen IQ innerhalb des
Bereichs 90-110 haben und zugleich Männer sind
85
Code: subset()
### subsets mit subset() erstellen
?subset! ! ! ! ! ! ! ! ! # die subset Funktionsubset(d, subset=IQ < 100 & Geschlecht=="m")!! !
# Logische Auswahlsubset(d, IQ > 120 | IQ < 80)! ! # Logische Auswahl
subset(d, select=c(IQ, Geschlecht))! # Variablenauswahl mit selectsubset(d, select=c("IQ", "Geschlecht")) # identisch
subset(d, IQ > 120, select=c(IQ, Geschlecht))! # kombiniert
86
Geschlecht Intervention IQ BMI1 m Control 102.5 16.72 m Treat 102.3 18.93 m Placebo 101.8 18.25 m Treat 106.7 21.010 m Control 118.9 15.711 w Treat 123.8 21.512 w Placebo 104.8 24.413 w Control 105.7 13.115 w Placebo 100.7 19.217 w Treat 104.3 20.419 w Control 105.0 10.8
Your turn!Wähle aus dem Datensatz mit subset alle Fälle aus, die einen IQ
größer als der Durchschnitt haben, der berechnet wird.
87
Geschlecht Intervention IQ BMI6 m Placebo 84.5 22.27 m Control 80.7 13.810 m Control 118.9 15.711 w Treat 123.8 21.516 w Control 78.9 25.6
Your turn!Wähle aus dem Datensatz mit subset alle Fälle aus, die a) einen IQ
außerhalb des Intervalls [90-110] haben.
... und b) zugleich weiblich sind
Geschlecht Intervention IQ BMI11 w Treat 123.8 21.516 w Control 78.9 25.6
88
packages laden
R-Base installationbasic packages
My ComputerDie R-base Installation enthält sog.packages, in denen bestimmte Funktionen enthalten sind.
packages müssen erst geladenwerden, bevor die in ihnen enthaltenenFunktionen benutzt werden können.
Einige packages werden automatisch geladen, andere müssen nach Bedarfgeladen werden.
> library(package.name)
89
R-Base installationbasic packages
>1500 additional packages My Computer
on demand
CRAN server
Installation per Kommandozeile> install.packages("package.name")
oder per R-Konsolenmenü
packages installieren
90
packages installieren
### packages installieren und laden
install.packages("plyr")! # plyr installierenlibrary(plyr)! ! ! ! # package ladendetach(package:plyr)! ! # package entfernen
describe()! ! ! ! ! # Funktion existiert nichtinstall.packages("psych")!# psych installierenlibrary(psych)! ! ! ! # Paket ladendescribe(rnorm(100))! ! # nun existiert sie
search() !# packages im Suchpfad
91
Code: Daten einlesen I
### EINLESEN VON DATEN IN R ###
?read.csv!! ! ! # Einlesen einer .csv Datei (englisch)?read.csv2! ! ! # Einlesen einer .csv Datei (deutsch)?read.table # für .txt Dateien?read.spss # für .sav Dateien?spss.get # im Hmisc package
setwd("/Users/markheckmann/data") ! ! ! ! ! ! # Arbeitsverzeichnis wechseln
df <- read.table("ngo.txt") # mieten.txt einlesenhead(df) # Zeilen haben keine Überschriftdf <- read.table("ngo.txt", header = TRUE) # Einlesen mit header=TRUEhead(df)
92
Code: Daten einlesen II
?read.csv2 ! ! ! ! # für deutsche .csv Dateiendf <- read.csv2("mieten.csv")head(df)
library(Hmisc)! ! !wow <- spss.get("wow.sav", use.value.labels=TRUE)
library(foreign)wow <- read.spss("wow.sav", to.data.frame=T)
93
Your turn!Lies den Datensatz wow_excerpt.csv ein und
speichere ihn in der Variablen df
94
Code: attach data
# Objekte/Datensätze in den Suchpfad hängen
K1!! ! ! ! ! # Objekt unbekanntattach(wow)! ! ! # Datensätze in den Suchpfad hängenK1!! ! ! ! ! # Objekt nun im Suchpfaddetach(anscombe)! # Datensatz aus Suchpfad entfernenK1!! ! ! ! ! # Objekt wieder unbekannt
search() # packages im Suchpfad
95
Datensatz wow_excerpt.csvGeschlecht 1=keine Angabe , 2=männlich, 3=weiblich Alter 1=keine Angabe, 2=unter 18, 3=18-29, 4=30-40, 5=41-50 , 6=über 50
Zeitaufwand (pro Woche)1=keine Angabe, 2=weniger als 7 Stunden, 3=weniger als 14 Stunden 4=weniger als 20 Stunden, 5=20-30 Stunden, 6=30-40 Stunden, 7=mehr als 40 Stunden
K1 Kontrollverlust: Ich sage mir oft: „Nur noch ein paar Minuten“ und kann dann doch nicht aufhören
K2K3K4
E1 Entzugserscheinungen: Ich beschäftige mich auch während der Zeit, in der ich nicht WoW spiele, gedanklich sehr viel mit dem Spiel.
E2E3E4
T1 Toleranzentwicklung: Mittlerweile verbringe ich mehr Zeit bei WoW als zu Beginn meiner Online- Aktivitäten.
T2T3T4
AL1 Arbeit/Leistung: Meine Leistungen in der Schule/im Beruf leiden unter dem Spielen bei WoW.
Al2AL3Al4
nKsB1 Soziale Beziehungen: Seitdem ich WoW spiele, haben sich einige Freunde von mir zurückgezogen.
nKsB2nKsB3nKsB4
96
EDA - die Daten anschauen### Anschauen der WoW Daten ###
head(wow)!! ! ! # die ersten Zeilennames(wow)! ! ! # Variablennamen
library(psych)! ! # library psych ladendescribe(wow)! ! # Überblick über Datensatz
library(Hmisc)hist.data.frame(wow[1:9])!! # Histogramme der ! ! ! ! ! ! ! ! ! # ersten neuen Variablenhist.data.frame(wow[10:17])! # Histogrammehist.data.frame(wow[18:23])! # Histogramme
multi.hist(wow[1:9])! ! ! # aus psych
pairs(attitude)pairs.panels(attitude)!! ! # aus psychpairs.panels(attitude, lm=TRUE)!
97
Your turn!Lies den Datensatz wow_excerpt.csv ein und
speichere ihn in der Variablen df
Hänge df dann in den Suchpfad, so dass man auf die Variablen ohne Angabe des Datensatzes zugreifen kann. Entferne den Datensatz dann wieder aus dem Suchpfad.
Installiere und lade dann das psych package und die nutze die darin enthaltene Funktion describe(),
um einen ersten Eindruck von den Daten zu bekommen. Danach „entlade“ das package psych.
98
Code: Deskriptive Statistiken
### Deskriptive Statistiken ###
summary(wow)!! ! # summaries der Variablenattach(wow)! ! ! ! # in den Suchpfad hängen
library(psych)! ! ! # psych ladendescribe(wow)! ! ! # Basisstatisiken der Variablen
describe.by(wow[4:11], Geschlecht)!! # Basisstatisiken pro Faktorstufe von Geschlecht
describe.by(wow[4:11], list(Geschlecht, Alter)) # Basisstatisiken pro Faktorstufe von Geschlecht # und Alter
detach(wow)! ! ! ! # Aus dem Suchpfad entfernen
99
crosstabs I
### Häufigkeiten ###
# One Way Tableattach(wow)table(Alter)!! # Häufigkeitstabelle von Alter
# Two Way Tablemytable <- table(Geschlecht, Alter)! # Häufigkeitstabellemytableftable(mytable)!! ! ! # ftable zur schöneren Darstellung
prop.table(mytable) ! ! # Zellen Prozenteprop.table(mytable, 1) ! ! # Zeilen Prozenteprop.table(mytable, 2) ! ! # Spalten Prozente
100
crosstabs II
# Three Way Tablesmt <- table(Geschlecht, Alter, Zeitwaufwand)ftable(mt)
# Tables mit CrossTablelibrary(gmodels)CrossTable(Geschlecht, Alter)CrossTable(Geschlecht, Alter, format="SPSS")
101
Your turn!Mache folgende Häufigkeitstabellen für den wow Datensatz mit CrossTable:1) Alter gegen Zeitaufwand2) Geschlecht gegen Zeitaufwand
Lese danach den Datensatz ngo.csv ein und erstelle a) Kreuztabelle für jahrgang vs. geschlb) Erzeuge Histogramme und Scatterplots für die Variablen mathe, englisch, deutsch
102
WoW Fragebogen
103
Missings NA setzen
# Gibt es „keine Angabe“ Antworten (wie k.A.), # die noch nicht als Missing kodiert sind?
attach(wow)
table(Geschlecht)! ! ! ! !! # Häufigkeitstabellewow$Geschlecht[Geschlecht==1] <- NA!! ! # 1 zu NA umkodierentable(Geschlecht)
table(Alter)!! ! ! ! ! ! ! ! # Häufigkeitstabellewow$Alter[wow$Alter==1] <- NA! ! ! ! # 1 zu NA umkodieren
detach(wow)
104
Rekodieren### Rekodieren ###
# verschiedene Funktionen zum Rekodieren
library(car)wow$K1 <- recode(wow$K1, "1=6; 2=5; 3=4; 4=3; 5=2; 6=1")
library(memisc)!!recode(wow$K1,! ! # rekodieren von K1 A = 1 <- 4, B = 2 <- 3, C = 3 <- 2, D = 4 <- 1)
detach(package:memisc)
105
Faktor definieren# Sind alle qualitativen Merkmale als Faktoren definiert?
wow$Geschlechtwow$Geschlecht <- as.factor(wow$Geschlecht)! # in Faktor umwandelnlevels(wow$Geschlecht) <- c("m", "w")! ! ! # F-stufen benennen
wow$Alterwow$Alter <- as.factor(wow$Alter)! ! ! ! # in Faktor umwandelnlevels(wow$Alter) <- ! ! ! ! ! ! ! ! # F-stufen benennen! ! c("unter 18", "18-29", "30-40", "41-50", "über 50" )!
wow$Zeitaufwandwow$Zeitaufwand <- as.factor(wow$Zeitaufwand)# in Faktor umwandelnlevels(wow$Zeitaufwand) <- ! ! ! ! ! ! # F-Stufen benennen! c("<7 Std.", "< 14 Std.", "< 20 Std.", ! "20-30 Std.", "30-40 Std.", "> 40 Std.") 106
Your turn!Lies den Datensatz wow_excerpt.csv ein und durchlaufe die Schritte:a) missings NA setzenb) Alle qualitativen Merkmale in Faktoren umwandeln und die Faktorstufen benennen
107
108
109
Ein junger Mann ohne Risikofaktoren kommt in die AIDS-Beratung und informiert sich über die gängigenHIV-Tests (ELIZA plus Western-Blot). Der Arzt sagt: „Die beiden kombinierten AIDS-Tests entdecken mit 99,9% Sicherheit das HI-Virus (Sensitivität) und sind sogar mit 99,99% spezifisch, d.h. eine falsch positive Diagnose kommt nur in 0,01% der Fälle vor.“ In der Gruppe, zu der der junge Mann gehört, ist HIV mit 0,01% Grundrate nur wenig verbreitet. Der Test fällt positiv aus! Wie wahrscheinlich ist es nun, dass der Mann HIV hat?
Beratungsgespräch I
110
Von 100.000 Männern ohne Risikofaktoren sind nur etwa 10 mit dem HI-Virus infiziert (Grundrate). Die beiden kombinierten AIDS-Tests entdecken mit 99,9% Sicherheit das AIDS-Virus (Sensitivität), d.h. würde man diese hunderttausend Männer testen, dann würden 10 von 10 HIV-Positiven einen po-sitiven Befund bekommen. Von den 99.990 nicht-infizierten Männern fällt der Test bei 0,01% dieser Personen, also bei un- gefähr 10 Personen, falsch-positiv aus. Wie wahrscheinlich ist eine HIV-Infektion, wenn der Mann positiv testet?
Beratungsgespräch II
111
Gig
eren
zer,
G. (
2008
). D
as E
inm
alei
ns d
er S
keps
is: Ü
ber
den
richt
igen
U
mga
ng m
it Z
ahle
n un
d Ri
siken
. Ber
lin: B
erlin
er T
asch
enbu
ch-V
erl.
Buchtips
112
Gigerenzer, G. (2008). Das Einmaleins der Skepsis: Über den richtigen Umgang mit Zahlen und Risiken. Berlin: Berliner Taschenbuch-Verl.
Dubben, H.-H., & Beck-Bornholdt, H.-P. (2006). Der Hund, der Eier legt: Erkennen von Fehlinformation durch Querdenken. rororo, 62196. Reinbek bei Hamburg: Rowohlt.
113
114
DAY 3 SPSS - das A fehlt nicht umsonst
„und dann rechnen wir mit dem Taschenrechner weiter... !“
Variablen berechnen# Neue Variablen berechnen
wow$KO <- (wow$K1 + wow$K2 + wow$K3 + wow$K4)/4!! # Skala bilden über vier Werte K1-K4
?transform! ! ! # zur Berechnung von Variablenwow <- transform(wow, KO=(K1 + K2 + K3 + K4)/4)!! # neue Variable KO mit tranformwow <- transform(wow, EN=(E1 + E2 + E3 + E4)/4)!! # neue Variable EN wow <- transform(wow, TO=(T1 + T2 + T3 + T4)/4)!! # neue Variable TO wow <- transform(wow, AL=(AL1 + AL2 + AL3 + AL4)/4) # neue Variable AL wow <- transform(wow, NK=(nKsB1 + nKsB2 + nKsB3 + nKsB4)/4)! # neue Variable NK
115
Your turn!Lies den Datensatz wow_excerpt.csv ein und durchlaufe die Schritte:c) Skala berechnend) einen Gesamtwert berechnen über die fünf Skalen
namens „score“, der der Durchschnitt der Skalen KO, EN, TO, AL, NK ist.
116
Pakete installieren
117
• HH
• car
• sm
• gmodels
• nortest
• perturb
• sfsmisc
• QuantPsyc
• TeachingDemos
• gplots
• lmtest
Formulas I### Formulas in R ###Dienen der Beschreibung von statistischen ModellenSind wie kleine eigene Sprache
y ~ model!
Dabei trennt die Tilde1 ("~") die auf der linken Seite angegebene Zielvariable (abhängige Variable, response) von dem auf der rechten Seite angegebenen Rest des Modells (model).
# Operatoren der Formelsprache+! Hinzunahme einer Variablen -! Herausnahme einer Variablen (-1 für Achsenabschnitt) :! Wechselwirkung/Interaktion von Variablen *! Hinzunahme von Variablen und deren Wechselwirkungen .! alle Variablen aus dem Datensatz in das Modell aufnehmen^ !Interaktionen bis zur Ordnung i aufnehmen
118
Formulas II
y ~ x1 ! ! ! ! # Modell mit einem Regressory ~ x1 + 1 !! ! # identischy ~ x1 - 1 ! ! ! !# ein Regressor ohne Konstante
y ~ x1 + x2 ! # zwei Regressoren, keine Interaktiony ~ x1 + x2 + x1:x2 ! # zwei Regressoren plus Interaktion y ~ x1 * x2! ! ! ! # identisch
y ~ .! ! ! ! ! ! # alle Variablen aufnehmen
y ~ x1 + I(x1^2)! ! # quadratischer Term
119
z-Test
120
# Datensatz ladenx <- read.csv2("test.csv")x$gr <- as.factor(x$gr)attach(x)
# z-Test
library(TeachingDemos)z <- rnorm(25, 99, 5)
d <- density(z)!! # Dichteschätzungplot(d)abline(v=100)
z.test(z, 100, 5) z.test(z, 100, 5, alternative="g")z.test(z, 100, 5, alternative="l")
Your turn!IQ ist auf einen Mittelwert von100 mit einer Standardabweichung von 15 normiert (Population). Teste jeweils per z-Test, ob eine der Gruppen (gr) von dem Populationsmittel abweicht.
121
t-Test
122
# t-Test
library(sm)! ! ! !g1 <- x[gr==1,]$iqg2 <- x[gr==2,]$iq
plot(iq ~ gr)! ! ! ! ! # Boxplotsm.density.compare(iq, gr)! # Dichte vergleichen
t.test(g1, g2)! ! ! ! ! ! # unabhängig, zweiseitigt.test(g1, g2, alternative="g")!# einseitig greatert.test(g1, g2, alternative="l")!# einseitig lesser
t.test(g1, g2, paired=TRUE)! ! # abhängig, zweiseitigt.test(iq ~ gender)!! ! ! ! # Formel interface
Your turn!Mache jeweils einen t-Test auf Mittelwertsunterschiede zwischen allen Stufen des Faktors gr und gender bezüglich der Variablen IQ.
123
Varianzhomogenitätstests
# Varianzhomogenität
library(car)!leveneTest(iq ~ gr, data=x)!! ! # Levene Testm <- lm(iq ~ gr, x)leveneTest(m)! ! ! ! ! ! ! ! # mit lm Objekt
bartlett.test(iq ~ gr, data=x)! !! ! ! ! ! ! ! ! ! ! ! ! ! # Bartlett Test
library(HH)hov(iq ~ gr, data=x)! ! ! ! ! # Brown-Forsythplot.hov(iq ~ gr, data=x)! ! ! # visuelle Inspektion
Normalverteilungstests
# Normalverteilungstests
qqnorm(iq)qqline(iq)
shapiro.test(iq)! # Shapiro-Wilk Test
library(nortest)lillie.test(iq)!! # Lilliefors / KS-Test
# Tip: weitere Tests im nortest package
One-Way-ANOVA I
126
### Einfaktorielle Varianzanalyse
library(sm)plot(iq ~ gr)! ! ! ! ! # Box plotsm.density.compare(iq, gr)! # Dichten vergleichen
library(gplots)plotmeans(iq ~ gr)!! ! ! # mean plot mit CIs
m <- aov(iq ~ gr, x)! ! ! # ANOVAsummary(m)! ! ! ! ! ! # Zusammenfassung
Anova(m)! ! ! ! ! ! # in package carAnova(m, white=TRUE)! ! # bei Heteroskedastizität
Posthoc-Tests
# Post-hoc Tests
plotmeans(iq ~ gr)!# mean plot mit Konfidenzgrenzen
pairwise.t.test(iq, gr)
pairwise.t.test(iq, gr, p.adj = "none")! !# ohne Alpha Korrektur
pairwise.t.test(iq, gr, p.adj = "none", pool=F)! !# ohne Alpha Korrektur
pairwise.t.test(iq, gr, p.adj = "bonf") ! !# Bonferroni Korrektur
Your turn!Mache eine Anova über die Variable height über den Faktor gr. Mache als Post-Hoc Tests paarweise t-Tests mit Bonferroni Korrektur.
128
Two-Way-ANOVA
### 2-WAY-ANOVA ###
fit <- aov(iq ~ gr*gender, data=x) summary(fit)
# Two-way Interaction Plotinteraction.plot(gr, gender, iq)interaction.plot(gender, gr, iq)
129
Your turn!Schaue in einer zweifaktoriellen Anova, ob sich die Variable height über die Faktoren gr und gender unterscheidet.
Gebe die Interaktionsplots aus.
130
Code: Lineare Modelle / Regression
# lineare Modelle schätzen
m1 <- lm(iq ~ height, data=x)! ! # Modell mit 1 Regressorm1!! ! ! ! ! ! ! ! !# Modell ausgebensummary(m1)! ! ! ! ! ! !# summary des Modells
m2 <- lm(iq ~ gender*height, data=x) ! ! # zwei Regressoren + Interaktionm2!! ! ! ! ! ! ! # Modell ausgebensummary(m2)! ! ! ! ! # summary des Modells
plot(iq ~ height)! ! ! # iq gegen height plottenabline(m1)! ! ! ! ! # Regressionsgerade hinzufügen
132
Funktionen für lineare Modelle
# Konfidenzintervalle ausgeben und plotten
library(sfsmisc)
attach(df)m <- lm(y1 ~ x1)plot(y1 ~ x1)abline(m)linesHyperb.lm(m, conf=TRUE, col="blue")! # für MittenlinesHyperb.lm(m)! ! ! ! ! ! ! ! # für Individuum
confint(m)! ! # CIs für Paramaterschätzungen
library(QuantPsyc) lm.beta(m) !! # Standardisierte Koeffizienten
Kollinearität
# collinearity diagnostics
library(perturb)n <- 30x1 <- rnorm(n)x2 <- x1*.5 + rnorm(n, , .2)y1 <- 2 + .3*x1 + .7*x2 + rnorm(n, ,.4)df <- data.frame(y1, x1, x2)
m <- lm(y1 ~ x1 + x2, df)summary(m)vif(m)colldiag(m)
Linearitätstests
# linearity diagnostics
library(lmtest)
harvtest(m)! ! ! ! ! ! ! ! # Harvey-Collier Testresettest(m, power=2:3)! ! ! ! # RESET Testraintest(y1 ~ x1 + x2, data=df)!! # Rainbow Test
Your turn!Berechne für die Variablen iq und height eine lineare Regression. Mache einen scatterplot mit Konfidenzintervallen für die Mitten und die Individuen.
Teste abschließend auf Linearität des Modells
136
Code: Modelle vergleichen
# Modelle vergleichen
fit1 <- lm(y1 ~ x1, data=df)fit2 <- lm(y1 ~ x1 + x2, data=df)anova(fit1, fit2)
137
Your turn!Berechne für die Variablen iq eine Regression auf height, gender und gr und mache sukzessiv Vergleichstests mit den Modellen, wobei du mit einem eifachen Modell beginnst und schrittweise immer mehr Variablen aufnimmst, die einen signifikanten Erklärungsbeitrag leisten.
138
Datensatz ngo aufbereiten
139
# Daten Schul Beispiel Kähler einlesenx <- read.csv2("ngo.csv")
# Kategoriale Variablen definierenx$jahrgang <- factor(x$jahrgang, labels=11:13)x$geschl <- factor(x$geschl, ! ! ! ! ! ! labels=c("männlich", "weiblich"))
Kontraste
140
# Dummy- / treatment Kodierungcontr.treatment(3)!! ! ! # baseline ist erstecontr.treatment(3, base=3)! # baseline ist drittecontr.SAS(3)!! ! ! ! ! # baseline ist letzte
# Effektkodierung (sum-to-zero coding)contr.sum(2)contr.sum(3)
# Helmert Kontrastecontr.helmert(4)
# Benutzerdefinierte Kontrastemake.constrast
Varianzanalyse als ALM
141
# Effektkodierung (sum-to-zero) wählencontrasts(x$jahrgang) <- contr.sum(3)
# Modelle berechnenm1 <- lm(deutsch ~ jahrgang, x)
# Modelle vergleichensummary(m1)anova(m1) ! # Vergleich Gesamt- und Nullmodell
Kovarianzanalyse als ALM
142
143
# Modelle berechnenm0 <- lm(deutsch ~ 1, x)m1.j <- lm(deutsch ~ jahrgang, x)m1.m <- lm(deutsch ~ mathe, x)m2 <- lm(deutsch ~ mathe + jahrgang, x)
# Modelle vergleichenanova(m1.j, m2) # Kovariate matheanova(m1.m, m2) # Haupteffekt von jahrganganova(m0, m2) # Vergleich Gesamt- und Nullmodell
Kovarianzanalyse als ALM
Kovarianzanalyse als ALM
144
# Dummy Codierung (treatment coding; Jahrgang 13 als baseline)contrasts(x$jahrgang) <- contr.treatment(3, base = 3)
# Modell berechnenm3 <- lm(deutsch ~ mathe + jahrgang, x)summary(m3)anova(m3)!! ! # Gesamtmodelltest
Kontraste
145
Kontraste
146
# Neue Variable berechnenattach(x)x$jahrges[jahrgang==11 & geschl=="männlich"] <- 1x$jahrges[jahrgang==11 & geschl=="weiblich"] <- 2x$jahrges[jahrgang==12 & geschl=="männlich"] <- 3x$jahrges[jahrgang==12 & geschl=="weiblich"] <- 4x$jahrges[jahrgang==13 & geschl=="männlich"] <- 5x$jahrges[jahrgang==13 & geschl=="weiblich"] <- 6x$jahrges <- factor(x$jahrges)detach(x)
# Modellcon <- cbind("vergleich 1" = c( .5, -.5, 0, .5, 0, -.5))contrasts(x$jahrges) <- conm1 <- lm(mathe ~ jahrges, x)summary(m1)
Your turn!a) Berechne eine Regression von iq auf gr mit Gruppe 2 als Baseline.
b) Füge in das Modell eine Interaktion zwischen gr und height hinzu
147
Code: Faktorenanalyse
### FAKTORENANALYSE ###wow <- na.omit(wow)!! ! ! # Missings entfernen
names(wow)
scree(wow[4:23])! ! ! # Scree plotfa.parallel(wow[1:20])!! # Scree plot
fit <- factanal(wow[4:23], 6, rotation="varimax")print(fit, digits=2, cut=.3, sort=FALSE)
library(psych)fit <- fa(wow[4:23], 6)! # Alternative mit vielen Optionen! ! ! ! ! ! ! ! # an Schätz- und Rotationsverfahrenprint(fit, digits=2, cut=.3)
148
Your turn!Lade die .csv Datei fa_daten.csv und mache mit ihr eine Faktorenanalyse.
149
Code: Hauptkomponenten-analyse (PCA)
150
### PCA ###
wow <- na.omit(wow)!! ! ! # Missings entfernen
fit <- princomp(wow[4:23])loadings(fit)print(loadings(fit), cut=.3)
Code: KTT
151
### Cronbachs Alpha: interne Konsistenz ###
library(psych)
fit <- fa(wow[4:23], 6)! ! # Polung der Variablenprint(fit, cut=.3)
names(wow)alpha(wow[4:7])!! ! ! ! # Item K4 rausalpha(wow[4:6])
alpha(wow[8:11])
alpha(wow[12:15])
152
153library(Rcmdr)Rcmdr()
154
155
156
157
158
159
DAY 4
DAY 4 Great Graphics
Charles J. Minard. Verluste der französischen Armee im Russlandfeldzug 1812-1813. Paris, 20. Nov. 1869
160Muenchen, R. (2009). R for SAS and SPSS users. New
York: Springer, p. 276.
Minard‘s plot made in R
161Peter Aldhous, Haiti Earthquake in Rhttp://www.readwriteweb.com/hack/2011/01/how-a-science-journalist-creat.php
162Peter Aldhous, Earthquakes in Rhttp://www.readwriteweb.com/hack/2011/01/how-a-science-journalist-creat.php
163Paul Butler, Dec 2010. Visualization of facebookusers‘ friendships between citieshttp://www.facebook.com/note.php?note_id=469716398919
„It's not just a pretty picture, it's a reaffirmation of the impact we have in connecting people, even across
oceans and borders“
164Hans Rosling in action: http://www.youtube.com/
watch?v=hVimVzgtD6w
Hans Rosling‘s Gapminder The Power of Visualization
164Hans Rosling in action: http://www.youtube.com/
watch?v=hVimVzgtD6w
Freely available as the Google Visualization API “Motionchart“Can easily be created via the R package “googleVis“
Hans Rosling‘s Gapminder The Power of Visualization
Google MotionChart in R
165
library(googleVis)> Fruits Fruit Year Location Sales Expenses Profit Date1 Apples 2008 West 98 78 20 2008-12-312 Apples 2009 West 111 79 32 2009-12-313 Apples 2010 West 89 76 13 2010-12-314 Oranges 2008 East 96 81 15 2008-12-315 Bananas 2008 East 85 76 9 2008-12-316 Oranges 2009 East 93 80 13 2009-12-317 Bananas 2009 East 94 78 16 2009-12-318 Oranges 2010 East 98 91 7 2010-12-319 Bananas 2010 East 81 71 10 2010-12-31
M1 <- gvisMotionChart(! Fruits, idvar="Fruit", timevar="Year")M1! ! ! ! ! ! ! ! # HTML codeplot(M1)
Google Visualization APIs
166
require(datasets)
states <- data.frame(state.name, state.x77)
G3 <- gvisGeoMap(!states, "state.name", "Illiteracy", !options=list(region="US", ! ! ! ! ! ! ! dataMode="regions",! ! ! ! ! ! ! width=1200, height=800))plot(G3)
Graphic SystemsR Graphic Systems
base graphics grid graphics
various packages
many graphicfunction
lattice ggplot2
167
Graphic SystemsR Graphic Systems
base graphics grid graphics
various packages
many graphicfunction
lattice ggplot2
167
Wiederholung
168
# Datensatz World of Warcraft laden
setwd("/Users/markheckmann/data")! ! # Verzeichnis wechselnwow <- read.csv2("wow_excerpt.csv")!! # Daten einlesen
# neue Variablen anlegen
wow <- transform(wow, K=(K1 + K2 + K3 + K4)/4 )wow <- transform(wow, E=(E1 + E2 + E3 + E4)/4 )wow <- transform(wow, AL=(AL1 + AL2 + AL3 + AL4)/4 )wow <- transform(wow, T=(T1 + T2 + T3 + T4)/4 )wow <- transform(wow, nKsB=(nKsB1 + nKsB2 + nKsB3 + nKsB4)/4 )
wow <- transform(wow, score=(K + E + AL + T + nKsB)/5 )
attach(wow)! ! ! ! ! ! ! # wow in den Suchpfad hängen
Verfügbare Datensätze
### Daten zum experimentieren ###
# Viele Datensätze sind bereits in R vorhanden
data()!! ! ! # zeigt an welche Datensätze existieren
# Laden weiterer Datensätze:
library(datasets)! ! # laden des Pakets datasets
# Wie auch Funktionen sind Datensätze dokumentiert.# Die Doku kann wie folgt aufgerifen werden.
?name_des_datensatzes
169
Grafiken I### einfache Visualisierungen ###
library(ggplot2)! ! ! # ggplot2 laden?diamonds!! ! ! ! ! # diamonds data setattach(diamonds)! ! ! # diamonds in den Suchpfad
?plot! ! ! ! ! ! plot(carat, price)!! ! # einfacher Scatterplotplot(price ~ carat)!! ! # identisch aber mit Formel! ! ! ! ! ! ! ! # Interface geschrieben
?hist! ! ! ! ! ! !# Histogrammlibrary(Hmisc)! ! ! ! # Hmisc Paket ladenhist(score)hist.data.frame(wow[1:16])! # mehrere Histogramme
?qqplot! ! ! ! ! ! # QQ-Plotsqqnorm(score)! ! ! ! # gegen Normalverteilung 170
Grafiken II
?boxplot! ! ! ! ! !boxplot(price ~ clarity)! ! ! # price über clarity
?pairs!! ! ! ! ! !! # Viele Scatterplotspairs(wow[c( "KO","EN","TO",!! ! # Auswahl einiger! ! ! ! "AL","NK","score")])! # Scatterplots
?barplot! ! ! ! ! !# Barchartbarplot(1:10)! ! ! ! ! ! # mit einem Vektorbarplot(matrix(1:9,3))!! ! ! # mit einer Matrixbarplot(table(Geschlecht, ! ! # mit eine table Objekt! ! ! ! Zeitaufwand))barplot(table(color, cut))! ! # mit table Objekt
171
Grafiken III
?coplot! ! # condition plot: scatterplots konditioniert ! ! # nach einer oder mehreren Variablen
! ! ! !coplot(lat ~ long | depth, data = quakes)coplot(lat ~ long | depth * mag, data = quakes)
?dotchart!! ! ! !dotchart(VADeaths)
?stripchart! ! !stripchart(decrease ~ treatment, data = OrchardSprays)stripchart(score ~ Zeitaufwand, data = wow)
172
Your turn!Erzeuge einen conditioned plot (coplot) von score (y-Achse) gegen KO (x-Achse) konditioniert mit dem Faktor Zeitaufwand.
Mache dann einen weiteren Plot mit den beiden konditionalen Faktoren Zeitaufwand und Geschlecht.
173
Your turn!Erzeuge einen dotchart und ein barplot auf dem jeweils Geschlecht gegen Alter zu sehen ist. Nutze hierzu die table() Funktion zur Vorbereitung der Daten.
174
Grafikoptionen ändern I
#### Grafikoptionen verändern ###
# Jede Funktion hat viele Parameter, die verändert # werden können, siehe ?plot und ?par
attach(wow)
plot(KO, score)!! ! ! ! ! ! ! ! # scatter plotplot(KO, score, xlab="Kontrollverlust", ! # Achsen beschriften! ! ylab="Suchtscore")plot(KO, score, ! ! ! ! ! ! ! ! # Überschrift setzen! main="Kontrollverlust vs. Sucht", ! xlab="Kontrollverlust", ylab="Suchtscore")plot(KO, score, col=3)!! ! ! ! ! ! # Farbe ändernplot(KO, score, col=3, pch=15)! ! ! ! # Symbol ändernplot(KO, score, col=3, pch=15, cex=.5)!! # Schriftgröße ändern
175
Grafikoptionen ändern II?barplotbarplot(table(Geschlecht, Zeitaufwand))! # stacked / übereinander!barplot(table(Geschlecht, ! ! ! ! ! # Gruppen nebeneinander! ! Zeitaufwand), beside=TRUE)! barplot(table(Geschlecht, Zeitaufwand), ! # Farbe und Überschrift! ! col=3:4, ! ! main="Zeitaufwand vs. Geschlecht")!
barplot(table(Geschlecht, Zeitaufwand), ! # Gekippt! ! horiz=TRUE)! ! barplot(table(Geschlecht, Zeitaufwand), !# Achsenbeschriftung ! ! cex.names=.7)!! ! ! ! ! ! # kleiner
barplot(table(Geschlecht, Zeitaufwand),! # Legende hinzufügen ! legend.text=c("männlich", "weiblich"),!! ! cex.names=.8)detach(wow) 176
Grafikbeispiel
#### iris dataset #######
?irishist(iris)! ! ! ! ! ! ! # Histogrammepairs(iris[1:4])! ! ! ! ! # Vier Histogrammepairs(iris[1:4], pch=21) # Symbol ändernpairs(iris[1:4], pch=21, !! ! # Farben pro Spezie! ! col=iris$Species) # andere Farben pro Spezie col <- c("red", "green3", "blue")[iris$Species]# Farbvektor zuweisenpairs(iris[1:4], pch=21, col=col)
177
Your turn!Erzeuge folgendes barchart mit der Funktion barplot()
mw
unter 1818−2930−4041−50über 50
Altersverteilung
Anzahl an Personen
Ges
chle
cht
0 50 100 150 200 250 300
178
base graphics I
### Einführung ins base Grafik System ###
# grafische Basiselemente?plot! ! ! ! ! ! ! !# welche Optionen gibt es?
dev.new()!! ! ! ! ! ! # neues Fenster öffnenset.seed(5)! ! ! ! ! ! # Ausgangspunkt für Zufallszahliq <- rnorm(30, 100, 15)! !pisa <- iq*.5+10 + rnorm(30,0,1) # pisa aus iq plus Zufall
plot(iq, pisa)! ! ! ! !# plotten von x gegen yplot(iq, pisa, pch=2)! ! ! # Ändern des Charactersplot(iq, pisa, pch=3)! ! ! # Ändern des Charactersplot(iq, pisa, type="h")! ! # Änderung des type Arguments
179
base graphics II
?linesplot(iq, pisa)! ! ! ! ! ! ! # plotten von x gegen ylines(x=c(60,130), y=c(40,80))! ! # Linie von P(60,40) ! ! ! ! ! ! ! ! ! ! ! # nach P(130,80)lines(x=c(60,130), y=c(40,80), # Linie in anderer Farbe! col=3) lines(x=c(60,130), y=c(40,80), !! # Linie mit anderer Farbe,! ! col=3, lty=3, lwd=2)! ! ! # Typ, Dicke
180
base graphics III?abline
plot(iq, pisa, col="brown", !# plotten von pisa gegen iq pch=16)
abline(v=mean(iq), ! ! ! # vertikale gestrichelte ! ! col="grey", lty=2)!! # graue Linie beim MW von IQ! ! !abline(h=mean(pisa), ! ! ! # hor. Linie beim MW pisa! ! col="grey", lty=2)! ! !abline(v=c(90, 110), ! ! ! # vert Linie bei x=90 und x=110! ! col="blue", lty=3)!! !!abline(lm(pisa ~ iq))!! ! # Regressionslinie pisa ~ iq! ! ! ! ! !
181
Your turn!Erzeuge einen plot mit dem WoW Daten. Plotte AL gegen score in der Farbe blau. Benenne die Achsen und gib der Grafik eine Überschrift.Zeiche dann eine gestrichelte vertikale Linie beim Mittelwert von Al und eine horizontale beim Mittelwert von score ein. Füge zuletzt eine Regressionsgerade in rot hinzu.
●
●
●
●
●
●
●
●
●
●
●●
●
●
●
●
●●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●
●
●
●
●
●
●
●
●
●
●●
●
●●
●
●
●●
●
●
●
●
●
●●
●
●
●
●
●●
●
●
●
●
●
●●
●
●
●
●
●
●
●
●●●
●
●
●
●
●
●
●
●
●
● ●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●
●
●
●
● ●
●
●
●
●●
●
●●
●
●
●
●
●
●
●
●
● ●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●
●
●
●
●
●
●
●
●
●
●
●
●
● ●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●
●
●
●
●
●●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
● ●●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
● ●
●
●
1.0 1.5 2.0 2.5 3.0 3.5 4.0
1.0
1.5
2.0
2.5
3.0
3.5
Übung
negative Konsequenzen
Such
tsco
re
182
base graphics IV
?pointsplot(iq, pisa, type="n")! ! ! # plotten ohne Punktepoints(iq, pisa)! ! ! ! ! # Punkte hinzufügen
?text! ! ! ! ! ! ! ! ! # um Text hinzuzufügentext(72,74, "test text", col="blue")! # Text an Position (72,78)
?mtext!! ! ! ! ! ! ! ! # für margin textmtext(side=3, "test mtext", col="red")! # margin text oben
183
Grafische Bereiche
184
base graphics V
### par settings ###par()! ! ! ! ! # Parameter settings anschauenoldPar <- par()!! ! # Parameter settings speichernplot(1:10)! ! ! ! # einfacher plot
par(mar=c(4,4,4,8))!! # Margin verändernplot(1:10)! ! ! ! # einfacher plot
par(mfrow=c(1,2))! ! # mfrow ändernplot(1:10)! ! ! ! # plot 1plot(1:10)! ! ! ! # plot 2
par(oldPar)! ! ! ! # alte Parameter wieder laden
185
Your turn!Zeichne den plot score (auf y) gegen TO (auf x) (WoW Daten) und direkt daneben das Histogram von score. Nutze hierzu die par() Einstellung mfrow.Zusatzaufgabe: Füge dem plot vorher noch für den Fall mit dem größten und für kleinsten Suchtwert jeweils einen Punkt hinzu, der rot und gefüllt ist.
●
●
●
●
●
●
●
●
●
●
●●●
●
●
●
●●●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●
●
●
●
●
●
●
●●
●
● ●
●
●●
●
●
●●
●
●
●
●
●
●●
●
●
●
●
●●
●
●●
●
●
●●
●
●
●
●
●
●●● ●●
●
●
●
●
●
●
●
●
●●●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●
●●
●
●
●
●
●
●●
●
●
●●
●
●
●
●
●
●
●
●
●
●●
●
●
●
●
●●
●
●
●
●●
●
●
●
● ●
●
● ●
●
●
●
●
●
●
●
●
●●●
●
●
●●
●●
●
●●
●
●
●
●
●
●●
●
●
●
●●
●
●
●
●
●●
●●
●
●
●●
●
●
●
●●
●
●
●
●
●
●
●
●
●
●
●●
●
●
●
●
●
●
● ●●
●
●
●●
●
●
●
●
●
●
●
●●
●
●
●
●●
●
●
●
●
●●
●
●
●
●
●
● ●
●
●
●
●
●
●●
●
●●
●
●
●
●
●
●
●
●
●
●
●
●
●●
●●
●●
●
●
●●
●●
●
●
●●
●●
●
●
●
●
●
●
●
●●
●
●
●
●
●
●
●
●
●●
●
●
●● ●●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●
●
●
●
●
●
●
●
●●
●
●
●●
●
●
●●
●
●
●
●
●●
●
●●
●
●
1.0 2.0 3.0 4.0
1.0
1.5
2.0
2.5
3.0
3.5
TO gegen score
TO
score
●
●
Histogram of score
score
Frequency
1.0 1.5 2.0 2.5 3.0 3.5
020
4060
186
Grafik als Datei
### Grafik-Output in Datei erzeugen ###
jpeg()!! # öffnet einen jpeg devicebmp()! ! # öffnet einen bmp devicepdf()! ! # öffnet einen pdf devicepng()! ! # öffnet einen png device
pdf()! ! # pdf device öffnen plot(1:10)dev.off()!# device schließen
dev.list()! # welche devices sind noch offen?
187
Your turn!Gib die Grafik aus der letzen Übung in eine .pdf Datei aus. Da Du den Code bestimmt in einer Datei gespeichert hast, kann der Plot nun schnell wiederhergestellt werden ;)
188
Graphic SystemsR Graphic Systems
base graphics grid graphics
various packages
many graphicfunction
lattice ggplot2
189
Graphic SystemsR Graphic Systems
base graphics grid graphics
various packages
many graphicfunction
lattice ggplot2
189
190ggplot2 documentation http://had.co.nz/ggplot2
ggplot2Grammar of Graphics
wt
mpg
15
20
25
30
● ●
●●
●●
●
●
●
●●
●●
●
● ●
●
●
●
●
●
●●
●
●
●●
●
●
●
●
●
2 3 4 5wt
mpg
15
20
25
30
● ●
●●
●●
●
●
●
●●
●●
●
●●
●
●
●
●
●
●●
●
●
●●
●
●
●
●
●●
●
●
●
●
●
●
●●
●
●● ● ●
●●●
●●
●
●●
●
●●
●●●
●
●
●●
2 3 4 5
factor(cyl)● 4● 6● 8
wt
mpg
10
15
20
25
30
● ●
●●
●●
●
●●
●●
●●
●
●●
●
●
●
●
●
●●
●
●
●●
●
●
●
●
●●
●●
●
●
●
●
●●
●
●● ● ●
●●●
●●
●
●●
●
●●
●●●
●
●
●●
2 3 4 5
factor(cyl)● 4● 6● 8
wt
mpg
10
15
20
25
30
● ●
●●
●●
●
●
●
●●
●●
●
●●
●
●
●
●
●
●●
●
●
●●
●
●
●
●
●●
●
●
●
●
●
●
●●
●
●● ● ●
●●●
●●
●
●●
●
●●
●●●
●
●
●●
2 3 4 5
factor(cyl)● 4● 6● 8
wt
mpg
10
15
20
25
30
4
●●●
●
●
●
●
●●
●
●●
●●
●
●
●
●
●●
●
●
2 3 4 5
6
●● ●
●●●
●●● ●
●●●
●
2 3 4 5
8
●
●
●●
●
●●
●●●
●
●
●●
●
●
●●
●
●●
●●●
●
●
●●
2 3 4 5
factor(cyl)● 4● 6● 8
qplot(wt, mpg, data = mtcars) + geom_point(aes(color=factor(cyl))) + geom_smooth(method="lm")
+ geom_smooth(aes(group=cyl), method="lm") + facet_grid(.~ cyl)
190ggplot2 documentation http://had.co.nz/ggplot2
ggplot2Grammar of Graphics
wt
mpg
15
20
25
30
● ●
●●
●●
●
●
●
●●
●●
●
● ●
●
●
●
●
●
●●
●
●
●●
●
●
●
●
●
2 3 4 5wt
mpg
15
20
25
30
● ●
●●
●●
●
●
●
●●
●●
●
●●
●
●
●
●
●
●●
●
●
●●
●
●
●
●
●●
●
●
●
●
●
●
●●
●
●● ● ●
●●●
●●
●
●●
●
●●
●●●
●
●
●●
2 3 4 5
factor(cyl)● 4● 6● 8
wt
mpg
10
15
20
25
30
● ●
●●
●●
●
●●
●●
●●
●
●●
●
●
●
●
●
●●
●
●
●●
●
●
●
●
●●
●●
●
●
●
●
●●
●
●● ● ●
●●●
●●
●
●●
●
●●
●●●
●
●
●●
2 3 4 5
factor(cyl)● 4● 6● 8
wt
mpg
10
15
20
25
30
● ●
●●
●●
●
●
●
●●
●●
●
●●
●
●
●
●
●
●●
●
●
●●
●
●
●
●
●●
●
●
●
●
●
●
●●
●
●● ● ●
●●●
●●
●
●●
●
●●
●●●
●
●
●●
2 3 4 5
factor(cyl)● 4● 6● 8
wt
mpg
10
15
20
25
30
4
●●●
●
●
●
●
●●
●
●●
●●
●
●
●
●
●●
●
●
2 3 4 5
6
●● ●
●●●
●●● ●
●●●
●
2 3 4 5
8
●
●
●●
●
●●
●●●
●
●
●●
●
●
●●
●
●●
●●●
●
●
●●
2 3 4 5
factor(cyl)● 4● 6● 8
qplot(wt, mpg, data = mtcars) + geom_point(aes(color=factor(cyl))) + geom_smooth(method="lm")
+ geom_smooth(aes(group=cyl), method="lm") + facet_grid(.~ cyl)
Heute nur eine kurze Einführung in ggplot2.Das Paket kann viel mehr!
Code: preparation
191
### Vorbereitung der Daten ###
# cyl in Faktor umwandelnmtcars$cyl <- as.factor(mtcars$cyl)!!
set.seed(1410) !# Startwert für Zufasllziehung (z.B. ! ! ! ! ! ! ! # mit sample) setzen. So wird es auf ! ! ! ! ! ! ! # allen Rechnern gleich
# 100 Zeilen von diamonds zufällig auswählen dsmall <- diamonds[sample(nrow(diamonds), 100), ]
### normaler R plot ###
attach(mtcars)plot(wt, mpg)detach(mtcars)
Code: scatter plot
192
### qplot - das Pendant zu plot im ggplot2 package ###
# scatter plot
qplot(wt, mpg, data=mtcars)! ! ! ! ! ! # scatter plotqplot(wt, mpg, data=mtcars, geom="point")!! # identischqplot(wt, mpg, data=mtcars, geom="point", ! # mit Achsenbe- main="Überschrift", xlab="X-Achse", ! # zeichnung und ! ! ylab="y-Achse")!! ! ! ! ! ! ! # Überschriftqplot(wt, mpg, data=mtcars, geom="point", ! # Achsen skalieren xlim=c(0,6), ylim=c(0,40))qplot(wt, mpg, data=mtcars, geom="point", ! # logarithmierte ! ! log="x") ! ! ! ! ! ! ! ! ! # x-Achseqplot(wt, mpg, data=mtcars, geom="point", ! # logarithmierte ! ! log="xy") !! ! ! ! ! ! ! ! # x- und y-Achse! ! ! ! ! ! ! ! ! ! !
Your turn!Erzeuge folgende Grafik mit den Variablen carat und price aus dem
Datensatz diamonds
193
Code: mapping to aesthetic properties
194
### mapping of asthetics to geometric objects ###
qplot(wt, data=mtcars, geom="point") !# Fehler: y fehlt?geom_point
qplot(wt, mgp, data=mtcars, geom="point") !# aesthetics x und yqplot(wt, mpg, data=mtcars, geom="point", ! size=cyl) ! ! ! ! ! ! ! ! ! # aesthetic sizeqplot(mpg, wt, data=mtcars, geom="point", ! colour=cyl) ! ! ! ! ! ! # aethetic colorqplot(mpg, wt, data=mtcars, geom="point", ! shape=cyl) ! ! ! ! ! ! ! # aesthetic shape
# kombinieren von mappings
qplot(wt, mpg, data=mtcars, geom="point", ! # shape und color! shape=cyl, colour=cyl)qplot(wt, mpg, data=mtcars, geom="point", ! # shape, color & size! shape=cyl, colour=cyl, size=cyl)
Your turn!Erzeuge folgende Grafik mit den Variablen carat und price aus dem
Datensatz diamonds. Die Achsen sind logarithmiert. Die Farben beziehen sich auf die Variable clarity.
195
Code: mapping vs. setting
196
# setting vs. mapping of aesthetics in qplot
qplot(wt, mpg, data=mtcars, !! ! # Anlegen einer neuer ! ! geom="point", alpha=.3) !! # Variable (mapping) ! ! ! ! ! !qplot(wt, mpg, data=mtcars, !! ! # Direkte Zuweisung ! ! geom="point", alpha=I(.3)) !# mit I() (setting)! ! ! ! ! !
qplot(wt, mpg, data=mtcars, !! ! # setten der Farbe! ! geom="point", color=I("blue")) ! ! ! ! ! !qplot(carat, price, ! ! ! ! ! # setten der Tansparenz! ! data = diamonds, alpha = I(.1)) !! ! !
Your turn!Erzeuge folgende Grafiken mit den Variablen carat und price aus dem
Datensatz diamonds.
197
Code: smoother
198
### weitere geometrische Objekte (geoms)
qplot(wt, mpg, data=mtcars, !! ! ! # wie vorher! ! geom="point")
qplot(wt, mpg, data=mtcars, !! ! ! # zwei geoms, zusätzlich! ! geom=c("point", "smooth"))! ! # smooth
?geom_smooth
qplot(wt, mpg, data=mtcars, !! ! ! # lineare Regression ! ! geom = c("point", "smooth"), ! # durch Wahl der Methode! ! method = "lm")! ! ! ! ! ! # für smooth
Your turn!Erzeuge folgende Grafik mit den Variablen carat und price aus dem
Datensatz diamonds. Die Achsen sind logarithmiert.
199carat
price
103
103.5
104
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
● ●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
10−0.6 10−0.4 10−0.2 100 100.2
Code: facetting
200
# facetting = konditionieren über eine Faktor
qplot(mpg, wt, data=mtcars, facets= . ~ am)! # facets auf x-Achseqplot(mpg, wt, data=mtcars, facets= am ~ .)! # facets auf y-Achseqplot(mpg, wt, data=mtcars, facets=vs ~ am)! # facets beide Achsen
# facetting plus linear smooth geom, d.h plus Regression
qplot(mpg, wt, data=mtcars, facets=. ~ am,! ! geom=c("point", "smooth"), method="lm")
qplot(mpg, wt, data=mtcars, facets=vs ~ am, ! ! geom=c("point", "smooth"), method="lm")
Your turn!Erzeuge folgende Grafik mit den Variablen carat und price aus dem Datensatz diamonds. Achsen sind logarithmiert. Die einzelnen Spalten
sind Levels von color.
201
carat
price
0
5000
10000
15000
20000
D
●
●
●
●●
●
●
●
●
●
●●●
●
●
●
0.5 1.0 1.5 2.0 2.5
E
●
●
●
●
●●●
●●●
●
●
●
●
●
●
●
●
●
0.5 1.0 1.5 2.0 2.5
F
●
●●●
●
●
●
●
●
●●
●
●
●
●
0.5 1.0 1.5 2.0 2.5
G
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●●
0.5 1.0 1.5 2.0 2.5
H
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
0.5 1.0 1.5 2.0 2.5
I
●
●
●●
●
●
●
●
0.5 1.0 1.5 2.0 2.5
J
●
●
●
●●●
●
0.5 1.0 1.5 2.0 2.5
color● D● E● F● G● H● I● J
Code: histogram
202
### qplot versucht die gewünschte Diagramm Art zu erraten ###
# histogram
qplot(carat, data=diamonds)! ! # bei einer gegebenen Variablen ! ! ! ! ! ! ! ! ! ! # erzeugt qplot ein Histogramm! ! ! ! ! ! ! ! ! !qplot(carat, data=diamonds, !! # explizite Wahl des geoms! ! geom="histogram")
qplot(carat, data=diamonds, !! # Einstellen der Klassierungs-! ! geom="histogram", !! ! # breite mit binwidth! ! binwidth=0.01)
Code: boxplot, jitter
203
# boxplot
qplot(clarity, price, data=dsmall, ! ! geom="boxplot")qplot(clarity, price, data=dsmall, ! geom=c("boxplot", "point"))! ! # zwei geoms. Die Punkte ! ! ! ! ! ! ! ! ! ! ! ! # über dem Boxplot
# jitter (~“zittern“)
qplot(clarity, price, data=dsmall, !! # jitter statt point um! ! geom=c("boxplot", "jitter"))!! # die Punkte zu ! ! ! ! ! ! ! ! ! ! ! ! # differenzieren
Code: barplot I
204
### barplot?geom_bar
# für nominale Datenqplot(cut, data = dsmall, geom="bar")! ! # barplotqplot(cut, data = dsmall, geom="bar", !! # mapping von fill! fill=clarity)
qplot(cut, data = dsmall, geom="bar", !! # stacked barplot ist! ! fill=clarity, position="stack")!! # Voreinstellung
qplot(cut, data = dsmall, geom="bar", !! # dodged barplot =! ! fill=clarity, position="dodge")!! # Säulen nebeneinander
qplot(cut, data = dsmall, geom="bar", !! # fill bringt Balnken ! ! fill=clarity,position="fill")! ! # auf gleiche Länge ~ ! ! ! ! ! ! ! ! ! ! ! ! # „spineplot“
Code: barplot II+ themes
205
### barplot mit metrischen Daten
qplot(carat, data = diamonds, ! ! ! # carat ist metrisch, so dass! ! fill=clarity, geom="bar", ! ! # eine Klassierung erstellt! ! binwidth = 0.05, xlim=c(1,3))! # wird
qplot(carat, data = diamonds, ! ! ! # nutzen von fill auch hier ! ! fill=clarity, geom="bar", ! ! # möglich! ! binwidth = 0.05, xlim=c(1,3), ! ! position="fill")
### changing themes
# Das Standard-Thema von ggplot2 ist für Veröffentlichungen oftmals ungeeignet, da es zuviel grau enthält. Andere Farbzusammenstellungen (Themen) sind verfügbar.
qplot(carat, price, data=dsmall) + theme_bw()
+ theme_bw()! ! ! # schwarz/weiß Thema+ theme_grey()! ! # standard Thema
Your turn!
Erzeuge folgende Grafik mit den Variablen carat
und price aus dem Datensatz diamonds.
Die vertikale Unterteilung ist color.
206
Your turn!
Erzeuge folgende Grafik mit der Variablen carat
aus dem Datensatz diamonds. Die vertikale Unterteilung ist color, die Farben clarity.
207
208ggplot2 documentation http://had.co.nz/ggplot2
ggplot2Grammar of Graphics
wt
mpg
15
20
25
30
● ●
●●
●●
●
●
●
●●
●●
●
● ●
●
●
●
●
●
●●
●
●
●●
●
●
●
●
●
2 3 4 5wt
mpg
15
20
25
30
● ●
●●
●●
●
●
●
●●
●●
●
●●
●
●
●
●
●
●●
●
●
●●
●
●
●
●
●●
●
●
●
●
●
●
●●
●
●● ● ●
●●●
●●
●
●●
●
●●
●●●
●
●
●●
2 3 4 5
factor(cyl)● 4● 6● 8
wt
mpg
10
15
20
25
30
● ●
●●
●●
●
●●
●●
●●
●
●●
●
●
●
●
●
●●
●
●
●●
●
●
●
●
●●
●●
●
●
●
●
●●
●
●● ● ●
●●●
●●
●
●●
●
●●
●●●
●
●
●●
2 3 4 5
factor(cyl)● 4● 6● 8
wt
mpg
10
15
20
25
30
● ●
●●
●●
●
●
●
●●
●●
●
●●
●
●
●
●
●
●●
●
●
●●
●
●
●
●
●●
●
●
●
●
●
●
●●
●
●● ● ●
●●●
●●
●
●●
●
●●
●●●
●
●
●●
2 3 4 5
factor(cyl)● 4● 6● 8
wt
mpg
10
15
20
25
30
4
●●●
●
●
●
●
●●
●
●●
●●
●
●
●
●
●●
●
●
2 3 4 5
6
●● ●
●●●
●●● ●
●●●
●
2 3 4 5
8
●
●
●●
●
●●
●●●
●
●
●●
●
●
●●
●
●●
●●●
●
●
●●
2 3 4 5
factor(cyl)● 4● 6● 8
qplot(wt, mpg, data = mtcars) + geom_point(aes(color=factor(cyl))) + geom_smooth(method="lm")
+ geom_smooth(aes(group=cyl), method="lm") + facet_grid(.~ cyl)
208ggplot2 documentation http://had.co.nz/ggplot2
ggplot2Grammar of Graphics
wt
mpg
15
20
25
30
● ●
●●
●●
●
●
●
●●
●●
●
● ●
●
●
●
●
●
●●
●
●
●●
●
●
●
●
●
2 3 4 5wt
mpg
15
20
25
30
● ●
●●
●●
●
●
●
●●
●●
●
●●
●
●
●
●
●
●●
●
●
●●
●
●
●
●
●●
●
●
●
●
●
●
●●
●
●● ● ●
●●●
●●
●
●●
●
●●
●●●
●
●
●●
2 3 4 5
factor(cyl)● 4● 6● 8
wt
mpg
10
15
20
25
30
● ●
●●
●●
●
●●
●●
●●
●
●●
●
●
●
●
●
●●
●
●
●●
●
●
●
●
●●
●●
●
●
●
●
●●
●
●● ● ●
●●●
●●
●
●●
●
●●
●●●
●
●
●●
2 3 4 5
factor(cyl)● 4● 6● 8
wt
mpg
10
15
20
25
30
● ●
●●
●●
●
●
●
●●
●●
●
●●
●
●
●
●
●
●●
●
●
●●
●
●
●
●
●●
●
●
●
●
●
●
●●
●
●● ● ●
●●●
●●
●
●●
●
●●
●●●
●
●
●●
2 3 4 5
factor(cyl)● 4● 6● 8
wt
mpg
10
15
20
25
30
4
●●●
●
●
●
●
●●
●
●●
●●
●
●
●
●
●●
●
●
2 3 4 5
6
●● ●
●●●
●●● ●
●●●
●
2 3 4 5
8
●
●
●●
●
●●
●●●
●
●
●●
●
●
●●
●
●●
●●●
●
●
●●
2 3 4 5
factor(cyl)● 4● 6● 8
qplot(wt, mpg, data = mtcars) + geom_point(aes(color=factor(cyl))) + geom_smooth(method="lm")
+ geom_smooth(aes(group=cyl), method="lm") + facet_grid(.~ cyl)
ACHTUNGwir haben nur einen kleinen Ausschnitt aus
ggplot2 gesehen. Viele Aspekte, die die Stärken
der Grammar of Graphics ausmachen, wurden heute wenig berücksichtigt.Das Paket kann viel mehr!
Deducer - getting interactive
209
Great package for interactive data analysis suitable for R beginners
www.deducer.org
Go to website and install: install.packages("Deducer",,"http://rforge.net/")
More ressourceshttp://www.youtube.com/user/MrIanfellows
Es ist geschafft!
210