# Zeilen die mit dem selben Zeichen wie diese beginnen, sind Kommentarzeilen. # Sie werden von R ignoriert und dienen dem Benutzer als Notiz. # Dieses R Skript soll Zeile für Zeile ausgeführt werden. # Auf Windows: Öffne das Skript über das Menü (Datei -> Skript öffnen), # und führe im Skript-Fenster mit der Tastenkombination Ctrl-R Zeile für Zeile aus. # Auf Macintosh: Öffne das Skript über das Menü # und führe im Skript-Fenster mit der Tastenkombination CMD-Return Zeile für Zeile aus. # Beliebiges System mit Emacs, bei dem "Emacs Speaks Statistics" installiert ist # (siehe http://ess.r-project.org/): # Öffne das Skript mit Emacs. Ist der Cursor in Emacs in einem # Skript-Fenster, so erscheint eine Schaltfläche, um einzelne Zeilen auszuführen. # Beliebiges System: Kopiere (copy-paste) Zeile für Zeile in die R Konsole (suche nach '>') # Zusätzlich können zwischendurch bei Bedarf eigene Befehle in der R Konsole ausgeführt werden. # Durch schnelles Durchklicken durch die Befehle lernt man nichts, # also bei jedem Befehl mitdenken. Dies erfordert einiges an Zeit. # Pausen zwischendurch sind empfehlenswert. ############################################################### ############################################################### ## ## Abschnitt 1: ## Erste Schritte: R als Taschenrechner 3+4 3+2*2 # Selbstverständlich 'Punkt vor Strich' (3+2)*2 exp(1) # 'exp()' ist die Exponentialfunktion. exp(log(5)) # 'log()' ist der natürliche Logarithmus log(8,base=2) # Logarithmus zur Basis 2 sqrt(9) # Die Wurzelfunktion (SQuare RooT) sqrt(8) 3^3 1.2 # Dezimalzahlen werden mit '.' dargestellt 1,2 # Die deutsche Notation führt zu einem Fehler ######################### ## Abschnitt 2: ## Hilfe: help("log") # Zeige die Hilfeseite zum Befehl 'log()' an. ?sin # Dasselbe wie help("sin") help.start() # Startet den Browser mit einer Html-Seite zu verschiedenen Manuals help.search("t-Test") # Listet alle Befehle auf, die etwas mit 't-Test' zu tun haben. ######################### ## Abschnitt 3: ## Variablennamen a <- 3 # Die Variable 'a' hat nun den Wert '3' a b <- 4 b a+b b = 5 # dasselbe wie b <- 5, ist aber unübersichtlich b 4 -> b # sogar das geht, ist aber unübersichtlich b ######################### ## Abschnitt 4: ## Vektoren ## Jede Zusammenfassung von Dingen gleicher Art wird in R als 'Vektor' bezeichnet ## Benutze c() (c wie "concatenate", "coerce", "combine",...), ## um Dinge zu einem "Vektor" zusammenzufassen: c(1,2,4) # Vektor von (ganzen) Zahlen x <- c(1,2.3,pi) # Vektor von (reellen) Zahlen class(x) # Was ist der Typ des Objektes x? c( c(1,2), c(3,pi,4) ) # c() fügt mehrere Vektoren zu einem Vektor zusammen z <- c( "a", "Zeichenkette", "Dies ist ein Text") z # Vektor von Zeichenketten class(z) # Der Typ von z ist 'character', also eine Zeichenkette # Grundrechenarten und Funktionen wirken auf Vektoren elementweise. 4*c(1,2,4) # ergibt den Vektor (4*1,4*2,4*4) c(1,2,4)+c(2,3,5) # ergibt den Vekotr (1+2,2+3,4+5) c(1,2)+c(2,3,1,5) # dasselbe wie c(1,2,1,2)+c(2,3,1,5) # Sind die Vektorenl}ngen unterschiedlich, so wird der kürzere # periodisch fortgesetz. c(1,2,4)*c(2,3,1) # ergibt den Vektor (1*2,2*3,4*1) c(1,2,3)^2 # ergibt den Vektor (1^2,2^2,3^2) c(1,2,3,4,5)^c(2,3) # ergibt den Vektor (1^2,2^3,3^2,4^3,5^2); ignoriere die Warnung exp(c(1,4,log(2))) # ergibt (exp(1), exp(4), 2) ## Nützliche Zahlenfolgen erzeugen: 1:5 # dasselbe wie c(1,2,3,4,5) (1:5)*2 # dasselbe wie c(1,2,3,4,5)*2 rep(3,5) # dasselbe wie c(3,3,3,3,3); 'rep' ist kurz für 'replicate' rep( c(2,7) ,3) # ergibt c(2,7,2,7,2,7); repliziere c(2,7) dreimal seq(from=0,to=1,by=0.1) # Sequenz von 0 bis 1 in 0.1-Schritten # ergibt c(0,0.1,0.2,0.3,...,0.9,1) ## Komponentenweise Vergleiche x <- c(1,3,5,3) x == 3 # komponentenweiser Test auf Gleichheit # ergibt (FALSE,TRUE,FALSE,TRUE) x > 3 # ergibt (FALSE,FALSE,TRUE,FALSE) x != 5 # komponentenweiser Test auf Ungleichheit # ergibt (TRUE,TRUE,FALSE,TRUE) ## Indizierung von Vektoren x <- c(3:6) x x[4] # 4. Element des Vektors x x[c(2,4)] # 2. und 4. Element; x[2,4] funktioniert nicht x[c(FALSE,FALSE,TRUE,TRUE)] # dasselbe wie x[c(3,4)] # Indizierung mit TRUE/FALSE Vektor x[x>4] # Beachte x>4 ist gleich (FALSE,FALSE,TRUE,TRUE) # Indizierung mit Wahr/Falsch-Aussagen ist unheimlich praktisch; Beispiel: groesse <- 1.70 + seq(from=0.01,to=0.1,by=0.01) fangort <- rep(c("Kathmandu","Bangkok"),5) groesse[fangort=="Bangkok"] ######################### ## Abschnitt 5: ## Mittelwert, Varianz und Standardabweichung einer Stichprobe x <- c(4:6,0,-5) x length(x) # Länge des Vektors sum(x) # Summe des Vektors: 4+5+6+0-5 mean(x) # Mittelwert: sum(x)/length(x) # (4+5+6+0-5)/5 var(x) # Varianz: sum( (x-sum(x))^2 ) / (length(x)-1) # ( (4-1)^2+(5-1)^2+(6-1)^2+(0-1)^2+(-5-1)^2 )/4 sd(x) # Standardabweichung: sqrt( var(x) ) median(x) # Die Hälfte der Werte liegt unterhalb, die Hälfte # der Werte liegt oberhalb eines Medians ######################### ## Abschnitt 6: ## Plotten x <- seq(from=0,to=1,by=0.1) plot(x,col="red") plot(x,x^2,col="red") plot(x,x^2,col="red",pch=16) # Als point character: 16 steht für volle Kreise plot(x,x^2,col="red",type="l") # Als plot-Typ: Linien statt Punkte plot(sin,from=-3,to=3) # Plotte die Sinus-Funktion zwischen -3 und 3 abline(v=2) # Fügt eine vertikale Linie durch (2,0) hinzu abline(h=1) # Fügt eine horizontale Linie durch (0,1) hinzu ######################### ## Abschnitt 7: ## Zufallszahlen erzeugen und darstellen # Die Normalverteilung ist die wichtigste Verteilung. # Sehen wir uns ihre Verteilung an und ziehen zufällige Werte. # In R ist - dnorm() der Befehl für die Dichtefunktion # - rnorm() der Befehl zum Generieren zufälliger (random) Werte plot(dnorm,from=-3,to=3) # Dichtefunktion der standard Normalverteilung x <- rnorm(10) # Generiere 10 Werte einer standard Normalverteilung x y <- rnorm(1000) # Generiere 1000 Werte einer standard Normalverteilung hist(y) # Das Histogramm von y hist(y, breaks=seq(from=-4,to=4,by=0.2), col="orange") # Feinere Einteilung z <- 1:6 sample(z, size=6) # Zieht 6 Werte aus z ohne Zurücklegen; # es werden hier alle Werte in zufälliger Reihenfolge gezogen s <- sample(z, size=10, replace=TRUE) s # Zieht 10 Werte aus z MIT Zurücklegen; # dies ist eine Simulation eines zehnmaligen Würfelwurfes mean(s) # Mittelwert des samples sd(s) # Standardabweichung des samples sample(z, size=10, replace=TRUE) ######################### ## Abschnitt 8: ## Schleifen summe <- 0 for( a in c(1,4,6,8)) { summe <- summe + a cat("a hat jetzt den Wert ",a,"\n") ## '\n' fügt einen Zeilenumbruch ein } summe sum(c(1,4,6,8)) ######################### ## Abschnitt 9: ## Datenstrukturen # Statistische Daten werden in R als data frames gespeichert. bavaria <- data.frame(city=c("Munich","Nuremberg","Augsburg"), area=c(310.43,186.38,146.93), popul=c(1356594,500132,263477)) bavaria # Beachte die Tabellenstruktur wie in Excel bavaria$city # Zugriff auf Spalten mit dem '$'-operator bavaria$area class(bavaria$city) # Der Typ ist nicht 'character', sondern 'factor'; dazu später mehr class(bavaria$area) bavaria$area[1] # bavaria$area ist ein Vektor, Zugriff auf Elemente mit [] bavaria$city[2] bavaria[1] # Auch [] funktioniert bei data frames. # Das Resultat ist ein einelementiger data frame. class(bavaria[1]) length(bavaria[1]) bavaria[[1]] # Dasselbe wie bavaria$city bavaria[1,2] # Indizierung wie bei Matrizen: Erste Zeile, zweite Spalte bavaria[3,1] # Indizierung wie bei Matrizen: Dritte Zeile, erste Spalte bavaria[2:3,1:2] # Zeilen 2 und 3, Spalten 1 und 2 bavaria[2:3,] # Alle Einträge der zweiten und dritten Zeile bavaria[,2:3] # Alle Einträge der zweiten und dritten Spalte bavaria[ bavaria$area<200 , ] # Alle Zeilen mit bavaria$area < 200 bavaria[ bavaria$area<200, c("city","area") ] # Jedesmal 'bavaria$' zu tippen ist umständlich city # Existiert nicht attach(bavaria) # Kopiert alle Elemente an einen Ort (sog. Suchpfad), an # dem R die Variablen findet. 'attach' = anhängen city # 'city', 'area' und 'popul' sind nun bekannt bavaria[ area<200, c("city","area") ] mean(area) var(area) detach(bavaria) # Löscht 'city', 'area' und 'popul' aus dem Suchpfad city # Ist wieder unbekannt ######################### ## Abschnitt 10: ## Daten einlesen # Sind die Daten durch Leerzeichen und/oder Tabulatoren getrennt, # so verwende den Befehl 'read.table()'. # Sind die Daten durch Kommata getrennt, # so verwende den Befehl 'read.csv()' ('csv'= comma separated values). # Die erste Zeile einer Datendatei enthält üblicherweise keine Daten, # sondern die Namen der Spalten. Verwende in diesem Fall # das Argument 'header=TRUE', ansonsten 'header=FALSE'. # Die Datei 'swarth.dat' sei im aktuellen Verzeichnis gespeichert. # Da aktuelle Verzeichnis erhält man mit getwd(). # Um zu einem anderen Verzeichnis zu wechseln, verwende 'setwd("verzeichnispfad")' finches <- read.table("swarth.dat",header=TRUE) finches head(finches) # Zeigt nur die ersten 6 Zeilen an attach(finches) # 'Insel' und 'Schnabel' sind nun bekannt mean(Schnabel) # mittlere Schnabellänge über alle Inseln sd(Schnabel) # Standardabweichung der Schnabellänge über alle Inseln mean(Schnabel[Insel=="Floreana"]) # mittlere Schnabellänge auf der Insel 'Floreana' detach(finches) # Sind die Daten in deutscher Dezimalschreibweise, so verwende # das Argument 'dec=","', das ',' als Dezimalzeichen vereinbart. ######################### ## Abschnitt 11: ## Daten grafisch darstellen mit boxplot(), stripchart() oder hist() # Boxplots werden in der Vorlesung noch ausführlich besprochen. # Die ~-Formel 'Schnabel~Insel' unterteilt den Schnabel-Vektor # in Untergruppen entsprechend 'Insel'. # In Worten: 'Schnabel in Abhängigkeit von Insel' attach(finches) # 'finches' wurde in Abschnitt 10 definiert boxplot(Schnabel~Insel) plot(Schnabel~Insel) # derselbe Plot (hier ist wichtig, dass Insel eine Faktor-Variable ist plot(Insel,Schnabel) # derselbe Plot (hier ist wichtig, dass Insel eine Faktor-Variable ist stripchart(Schnabel~Insel) # generiert ein sogenanntes Streudiagramm (oder Scatterplot) stripchart(Schnabel~Insel,pch=16,col="steelblue",ylim=c(0.5,3.5),method="stack") # ylim=c(0.5,3.5): Die drei Inseln werden bei (1,2,3) eingezeichnet. # Durch ylim=c(0.5,3.5) wird oben und unten um 0.5 eingerückt # method="stack": sich überlappende Punkte werden übereinander gestapelt. stripchart(Schnabel~Insel,pch=16,col="tomato2",ylim=c(0.5,3.5),method="jitter") # method="jitter": Punkte werden etwas gerüttelt, indem jeder Punkt um einen # zufälligen Wert verschoben wird colors() # Übersicht über alle vordefinierten Farben hist(Schnabel) # Histogramm abline(v=mean(Schnabel)) # Fügt eine vertikale Linie durch den Mittelwert hinzu abline(v=mean(Schnabel),lwd=3) # Nun mit Liniendicke=3 (line width) abline(v=mean(Schnabel)+sd(Schnabel),lwd=3,lty="dashed") # Eine gestrichelte (dashed) Linie durch Mittelwert + Standardabweichung abline(v=mean(Schnabel)-sd(Schnabel),lwd=3,lty="dashed") # Eine gestrichelte (dashed) Linie durch Mittelwert - Standardabweichung detach(finches) ######################### ## Abschnitt 12: ## Visualisieren von Verteilungen durch Dichtepolygone attach(finches) # 'finches' wurde in Abschnitt 10 definiert # So sehen die Histogramme aus hist(Schnabel[Insel=="Santa_Cruz"], main="Beobachtete Schnabellängen auf Santa Cruz") hist(Schnabel[Insel=="Floreana"], main="Beobachtete Schnabellängen auf Floreana") # Nun berechnen wir die Histogramme ohne sie zu plotten (plot=FALSE) h.SCru <- hist(Schnabel[Insel=="Santa_Cruz"], plot=FALSE) h.Fl <- hist(Schnabel[Insel=="Floreana"], plot=FALSE) # Die Balken des Historgramms sind um h.Fl$mids konzentriert und # haben die Höhe h.Fl$dens. Durch diese Punkte zeichnen wir nun # das Dichtepolygon. # Erzeuge zunächst einen "leeren" Plot plot(-1,-1, main="Dichtepolygone der Schnabellängenverteilungen", sub="auf den Inseln Floreana und Santa Cruz", xlim=c(min(h.SCru$mids, h.Fl$mids), max(h.SCru$mids, h.Fl$mids)), ylim=c(0,max(h.SCru$dens, h.Fl$dens)), xlab="Beobachtete Schnabellänge",ylab="Dichte") # füge nun die Dichtepolygone hinzu: points(h.SCru$mids, h.SCru$dens, lty=1, lwd=2, type="l") points(h.Fl$mids, h.Fl$dens, lty=3, lwd=2, type="l") detach(finches) ######################### ## Abschnitt 13: ## Faktoren # Im Finken-Beispiel aus Abschnitt 10 ist 'Insel' eine sogenannte Faktor-Variable. attach(finches) class(Insel) Insel # Faktor-Variablen dienen dazu, Daten in Untergruppen zu gruppieren # Für Fortgeschrittene: # Wird eine numerische Variable beim Einlesen fälschlicherweise als Faktor-Variable # eingestuft, so kann man dies per Hand wie folgt korrigieren: f <- factor(c(3,5,4,10)) f as.numeric(f) # Hierdurch wird die interne Representation der Faktor-levels # als numerischer Vektor aufgefasst. as.numeric(as.vector(f)) # Dies liefert das gewünschte Ergebnis. as.vector(f) # Liefert die Bezeichnungen der Levels als Zeichenvektor. ######################### ## Abschnitt 14: ## Sitzung beenden q() # Die letzten beiden Abschnitte sind für Fortgeschrittene und sollten vielleicht nocht nicht # von Anfängern gelesen werden. ################################################## ################################################## ## Abschnitt 15: ## Anwendungsbeispiel mit Darwin-Finken ## Benutzen Sie setwd("C:where/your/data/are") oder den entsprechenden Menue-Eintrag, um R mitzuteilen, ## wo die Daten zu finden sind. finches <- read.table("FinchesSulloway.txt",header=TRUE,sep="\t") # read data from file attach(finches) boxplot(BeakH~SpeciesID) boxplot(WingL~SpeciesID) stripchart(WingL~SpeciesID,method="stack",vertical=TRUE) #pdf(file="wingbox.pdf",width=10,height=7) boxplot(WingL~IslandID,col="yellow",horizontal=TRUE,main="Wing Lengths by Island") #dev.off() #pdf(file="wingstrip.pdf",width=10,height=7) stripchart(WingL~IslandID,method="stack",col="red",cex=3,lwd=2) #dev.off() #pdf(file="wingboxstrip.pdf",width=10,height=7) boxplot(WingL~IslandID,col="yellow",horizontal=TRUE,main="Wing Lengths by Island") stripchart(WingL~IslandID,method="jitter",col="red",cex=3,pch=1,lwd=2,add=TRUE) #dev.off() #pdf(file="winghist.pdf",width=10,height=7) h1 <- hist(WingL[IslandID==""],freq=FALSE,col="#FF990044",xlim=c(50,95),breaks=-1:10*5+50, main="Histogramm (Densities!) with transparen colors",xlab="Wing Lengths") h2 <- hist(WingL[IslandID=="SCris_Chat"],freq=FALSE,col="#FF009944",breaks=-1:10*5+50,add=TRUE) h3 <- hist(WingL[IslandID=="Flor_Chrl"],freq=FALSE,col="#00FF0044",breaks=-1:10*5+50,add=TRUE) h4 <- hist(WingL[IslandID=="Snti_Jams"],freq=FALSE,col="#0000FF44",breaks=-1:10*5+50,add=TRUE) legend(80,0.18,legend=c("","SCris_Chat","Flor_Chrl","Snti_Jams"), col=c("#FF990044","#FF009944","#00FF0044","#0000FF44"),pch=16) #dev.off() #pdf(file="wingbar.pdf",width=10,height=7) M <- rbind(h1$counts,h2$counts,h3$counts,h4$counts) colnames(M) <- h1$mids barplot(M,beside=TRUE,col=c("#FF9900","#FF0099","#00FF00","#0000FF"),main="Barplot of Wing Lengths (Numbers)") legend(40,6,legend=c("","SCris_Chat","Flor_Chrl","Snti_Jams"),col=c("#FF9900","#FF0099","#00FF00","#0000FF"),pch=16) #dev.off() #pdf(file="wingdens.pdf",width=10,height=7) plot(h1$mids,h1$density,col="#FF9900",lwd=3,t="l",xlim=c(50,100),main="Density Polygons", xlab="Wing Lengths",ylab="Density") lines(h2$mids,h2$density,col="#FF0099",lwd=3) lines(h3$mids,h3$density,col="#00FF00",lwd=3) lines(h4$mids,h4$density,col="#0000FF",lwd=3) legend(80,0.18,legend=c("","SCris_Chat","Flor_Chrl","Snti_Jams"),col=c("#FF9900","#FF0099","#00FF00","#0000FF"),pch=16) #dev.off() #pdf(file="beakbox.pdf",width=10,height=7) boxplot(BeakH~SpeciesID,col="yellow",main="Beak Sizes by Species") #dev.off() #pdf(file="beakboxstrip.pdf",width=10,height=7) boxplot(BeakH~SpeciesID,col="yellow",main="Beak Sizes by Species") stripchart(BeakH~SpeciesID,method="jitter",vertical=TRUE,add=TRUE,pch=1,col="red") #dev.off() detach(finches) ######################### ## Abschnitt 16: ## Verschiedene Spielereien für Fortgeschrittene c(1,2,4) %*% c(2,3,1) # Skalarprodukt # Verschachtelte Schleifen x <- c() for ( i in 1:3) { x[i] <- 0 for (j in (1:3)) { cat(i," plus ",j," gibt ",i+j,"\n") x[i] <- x[i]+i*j } } x ## Farbenlehre fuer Fortgeschrittene: y <- rnorm(100,mean=50,sd=10) hist(y,breaks=0:20*5,col="tomato") colors() mycolor <- rgb(red=0.0,green=0.3,blue=0.8,alpha=0.5) mycolor hist(x,breaks=0:20*5,col=mycolor,add=TRUE) x <- rep(0:100,101)/100 y <- rep(0:100,rep(101,101))/100 plot(x,y,col=rgb(red=x,green=y,blue=0),pch=15) plot(x,y,col=rgb(red=x,green=y,blue=1.0),pch=15) # Indizierung von Vektoren mit Namen x <- 1:5 names(x) <- c("Charles","Robert","Darwin","Albert","Einstein") x x[c("Robert","Charles")] x[["Robert"]] x[[c("Robert","Charles")]] # Does not work x<0 x[x<0] ## Listen V <- c(2,3,4) V[2]+V[3] L <- list(2,3,4) L L[2]+L[3] class(L[ 2 ] ) class(L[[ 2 ]] ) L[[2]] + L[[3]] L <- list(c(1,"hello",3) , c(4,5)) L L[1] L[2] L[2][1] L[[2]][1] class(L) class(L[1]) class(L[[1]]) L <- list( Joe=c(1,"hello",3) , Jack=c(4,5)) L[1] L[[1]] L["Joe"] L[["Joe"]] L$Joe