Jakob Richter

Statistik, R, Fotografie und Sonstiges

lapply() und sapply() – Der Einstieg in die apply-Funktionen.

Warum gerade lapply() und keine der gebräuchlicheren Funktionen apply Funktionen aus R? Ganz einfach: lapply() ist die Grundfunktion und die anderen Funktionen bauen auf dieser Funktionsweise auf. Da man lapply() nicht nur auf Vektoren, sondern auch auf Listen anwenden kann bietet es ungeahnte (vllt. auch unausdenkbare) Möglichkeiten der Verwendung. Aus diesem Grund ist das Beispiel auch äußerst praxisunrelevant.

Funktionsweise lapply()

Versuch eines Schemas: So ungefähr arbeitet lapply().


Weiterlesen »

Schnelleres R dank Kompilierung (also ohne apply())

Inspiriert durch diesen Blogbeitrag wollte ich die Vorkompilierung selbst einmal ausprobieren und auch mit dem so hoch gelobten apply() vergleichen um mich von der Effektivität zu überzeugen.
Weiterlesen »

Daten im R-Quelltext hinterlegen.

Ok, dieses Beispiel wird man wohl selten gebrauchen, aber vielleicht mag es mal nützlich sein, wenn man jemandem ein wenig R-Code schicken will, der mit einem Datensatz arbeitet, ihr ihm aber nicht den kompletten Datensatz schicken wollt/könnt/dürft. Gleichzeitig sollte alles in einer Datei sein, damit der Empfänger nicht die Mühe hat alles noch mal einlesen zu müssen.

Funktioniert auch gut, wenn man sich nur selbst ein paar Daten ausdenken will, mit denen man etwas testen möchte. So erspart man sich lästiges c("a","b", usw.).

So geht’s:

1
2
3
4
5
6
datentxt <- "	lcavol	lweight	age	lbph	svi	lcp	gleason	pgg45	lpsa	train
1	-0.579818495	2.769459	50	-1.38629436	0	-1.38629436	6	  0	-0.4307829	T
2	-0.994252273	3.319626	58	-1.38629436	0	-1.38629436	6	  0	-0.1625189	T
3	-0.510825624	2.691243	74	-1.38629436	0	-1.38629436	7	 20	-0.1625189	T"
 
daten <- read.table(textConnection(datentxt))

Die ersten Textzeilen aus dem Prostata-Datensatz markieren, kopieren und dann datentxt <- "HIER" einfügen. Dabei darauf achten keine neuen Zeilenumbrüche einzubauen.

Hübscher Quellcode mit Latex und Beamer

Listings in LaTex und die Beamer-class
Aus gegebenem Anlass mal ein kurzer Beitrag, wie man Quelltext hübsch in eine LaTeX-Präsentation mit der Beamer-Class einbaut.
Anstelle der bekannten Verbatim-Umgebung wird hier auf das (auch für Berichte empfehlenswerte) Paket listings gesetzt.
Einge recht gute und knappe Hilfe findet man bei wikibooks.org

Vorteile:

  • farbiger Code
  • kein Problem mit langen Zeilen

Nachteile:

  • keine ;)

Weiterlesen »

Workflow für Simulationsstudien

Eine häufige Aufgabe ist es, für verschiedene Parameter ein und die selbe Simulation mit R durchzuführen und dann die Ergebnisse auszuwerten. Persönlich bevorzuge ich es, erst alles zu simulieren und dann auszuwerten. Dieses Vorgehen hat mehrere Vorteile: Bei langandauernden Simulationen müssen diese nur einmalig ausgeführt werden. Außerdem: Wenn ich mit meiner Auswertung unzufrieden bin, kann ich einfach die Auswertungsprozedur modifizieren ohne noch einmal alles durchlaufen lassen zu müssen und der Quelltext ist auch nachvollziehbarer. Insbesondere ist das Vorgehen aber auch angepasst auf die grafische Darstellung und Auswertung mit ggplot2.
Weiterlesen »

merge() – eine kleine Einleitung

Es kann sein, dass man in die Situation kommt verschiedene Datensätze miteinander kombinieren zu wollen. In einer Tabelle steht vielleicht für verschiedene Lebensmittel die Energiewerte und Vitamingehalte und in einer anderen Tabelle steht wie viel von welchem Lebensmittel eine Person gegessen hat. Will man jetzt schnell berechnen, wie viele kcal jede Person zu sich genommen hat kann man das schnell und elegant durch mergen der Datensätze, gefolgt von aggregate() um die kcal für jeden Patienten zusammenzurechnen.
Das ist natürlich nur ein dämliches Beispiel. Der geneigte R-Nutzer wird schon seine eigenen Anwendungen finden. Oft ist es auch viel einfacher Berechnungen an einem Datensatz durchzuführen als Funktionen zu basteln, die sich Daten aus mehreren Datensätzen zusammensuchen.
Weiterlesen »

Geokoordinaten mit R und Google finden (einfach, ohne API)

Dies ist eine verblüffend leichte Übung, da Google einem direkt ein csv-File (Beispiel) ausspuckt, welches natürlich sehr einfach zu lesen ist. Weil es so einfach ist hier nur wenig Text und der Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
reisetrip < - c("Berlin","Potsdam","Magdeburg","Hannover","Minden","Bielefeld","Dortmund")
breiten <- NULL
langen <- NULL
for(i in seq_along(reisetrip)){
  query <- paste(strsplit(reisetrip[i]," ")[[1]], collapse="%20") #Leerzeichen mit %20 codieren
  query <- paste("http://maps.google.com/maps/geo?q=",query,"&output=csv&num=1",sep="")
  res <- read.table(query,sep=",")
  cat("Ort #",i,"von",length(reisetrip),";",reisetrip[i],"\n")
  Sys.sleep(runif(1,0.1,2.5)) #Wir warten ein wenig, damit Google nicht sauer wird.
  langen[i] <- res[,4] #longitude
  breiten[i] <- res[,3] #latitude
}
plot(langen,breiten,type="l", ylim=range(breiten)+c(-0.1,+0.1), xlim=range(langen)+c(-2,+0.5))
points(langen,breiten,pch=19)
text(langen,breiten,reisetrip,pos=2)

Warnungen bezüglich unvollständiger letzter Zeilen können getrost vernachlässigt werden

plot()
Weiterlesen »

aggregate() – Teil 2

Teil 1 findet sich hier: aggregate() – der Anfang

Der erste Teil lieferte ein einfaches Beispiel zur Nutzung der aggregate()-Funktion. Widmen wir uns nun einem etwas komplexeren Fall.

Verschiedene Gruppen erzeugen

Zunächst simulieren wir uns wieder einmal ein Datensatz mit ein paar Versuchsperson und ihrem Gewicht vor der Studie (gewicht1) und ihrem Gewicht nach der Studie (gewicht2). Außerdem brauchen wir natürlich noch Gruppen, die wir untersuchen wollen. Weisen wir den Versuchspersonen also noch zufällig eine Haarfarbe und die Therapie (1 Wöchige Diät aus ausschließlich Salat oder Pizza) zu.

1
2
3
4
5
6
7
8
set.seed(110)
gewicht1 < - rnorm(100,mean=90,sd=15) #Gewichte der Versuchspersonen vor dem Essen
gewicht2 <- rnorm(100,mean=100,sd=20) #Gewichte nach dem Essen
gewichte <- cbind.data.frame(gewicht1,gewicht2) #Datensatz mit beiden Gewichten
gewichte <- cbind(gewichte,zunahme=gewichte$gewicht2 - gewichte$gewicht1)    #die Zunahme hinzufügen
haarfarben <- sample(c("blond","rot","brünett","schwarz"),size=100,rep=T)
essen <- sample(c("Salat","Pizza"),size=100,rep=T)
einteilung <- list(haarfarbe=haarfarben,essen=essen)

In den letzten Zeilen haben wir also einen Vektor erzeugt mit 100 Zuteilungen für die Haarfarbe und 100 Zuteilungen für das Essen, was die Versuchspersonen verabreicht bekommen.

Was wird aggregate() jetzt tun?

Ganz einfach: Für alle Werte des Eingabevektors, die die gleiche Kombination von haarfarbe und essen haben wird die Funktion FUN= aufgerufen. Wenn die Funktion z.B. mean ist, wird das arithmetische Mittel von jeweils gewicht1, gewicht2 und zunahme gebildet von den Personen, die die gleiche Haarfarbe und die gleiche Diät hatten.
Weiterlesen »

Faltung der Hypergeometrischen Verteilung

Die Faltung von Wahrscheinlichkeitsdichten ist nichts weiter als die Berechnung der Wahrscheinlichkeitsdichte der Summe von Zufallsvariablen, also z.B. die Dichte von X_1+X_2 oder auch X_1+X_2+X_3. Das heißt, wir interessieren uns im diskreten Fall für die Wahrscheinlichkeit P(X+Y=z). Die Berechnung ist recht einfach, wenn X und Y unabhängig voneinander sind: P(X+Y=z)=\sum_{i=0}^z P(X=i) \cdot P(Y=z-i)

Wie berechnet man jetzt jedoch in R möglichst effektiv die Addition von sehr vielen Zufallsvariablen? Zunächst sollte klar werden, dass man “bottom up” – wie der Informatiker es sagen würde – vorgehen muss. Also es können in einem Schritt immer nur die Dichte der Summe von zwei Zufallsvariablen berechnet werden, da für die Berechnung der Dichte von drei aufsummierten Zufallsvariablen die Dichte von zwei aufsummierten Zufallsvariablen bereits bekannt sein muss. Weiterlesen »

aggregate() – der Anfang

Jetzt möchte ich nur kurz die mir sehr lieb gewonnene R-Funktion aggregate() vorstellen. Wer die Funktionen sapply(), apply(), lapply() usw. schon kennt und gerne nutzt, ist vermutlich auch schon ab und zu auf das Problem gestoßen, dass man evtl. auch über mehrere Zeilen hinweg eine Funktion anwenden möchte.

Nutzfälle

Was ist z.B. wenn wir das arithmetische Mittel von immer 3 aufeinanderfolgenden Daten in einem Datensatz berechen wollen? Betrachten wir folgendes Beispiel:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
X < - rep(c(4,10,16),length.out=12)
Y <- runif(12)
XY <- cbind.data.frame(X,Y)
head(XY) #sollte ungefähr so aussehen
#    X          Y
# 1  4 0.05644781
# 2 10 0.58944284
# 3 16 0.35899530
# 4  4 0.07475402
# 5 10 0.75567801
# 6 16 0.94060689
jeweils <- 3
teile <- ceiling((1:nrow(XY))/jeweils)
teile
# [1] 1 1 1 2 2 2 3 3 3 4 4 4
aggregate(XY,by=list(teile),FUN=mean)
#   Group.1  X         Y
# 1       1 10 0.6196099
# 2       2 10 0.5319404
# 3       3 10 0.4377502
# 4       4 10 0.4572320
#Beachte: (4+10+16)/3=10

Weiterlesen »

Archiv

  • 2012 (28)