Jakob Richter

apply() hoch 3

Nach dem Beitrag zu lapply() und sapply() möchte ich hier nun das etwas mächtigere (?) apply() vorstellen, was man in R wohl kaum missen will.

Ich werde kurz zeigen wie mit apply() Matrizen und data.frames zeilen- sowie spaltenweise Ausgewertet werden können. Nach dieser sehr leichten Übung widmen wir uns einem etwas trickreicherem Beispiel, in dem wir mehrere gleichartige Tabellen (also Matrizen bzw. data.frames) der gleichen Zeilen- und Spaltenanzahl vorliegen haben. Hier möchten wir die Informationen aus immer den gleichen Zellen zusammenfassen.
Read the rest of this entry »

Formeln in R (Teil 1)

Formeln (formula) werden in R an vielen verschiedenen Stellen genutzt. Natürlich für die lineare (lm()) und logistische Regression (glm(type="logit")), aber auch für die Survivalanalyse und das Cox-Modell (library("survival"); coxph()) um nur einige Beispiele zu nennen.

Zuerst der ganz allgemeine Aufbau einer formel
abhängige Variable ~ erklärende Variablen
(Ein kleiner Tipp für Mac-Nutzer an dieser Stelle: ~ lässt sich schreiben mit [alt] + N)
Die Formel y ~ x kann also verstanden werden als x erklärt y oder y ist abhängig von x.

Sicherlich bekannt ist, dass wir mehrere erklärende Variablen (EV) mit + verbinden können: y ~ x1 + x2
Doch es gibt zahlreiche weitere Möglichkeiten die rechte Seite der Formel aufzubauen:
Read the rest of this entry »

Zeilen in einer Matrix verdoppeln.

Hier ein kleiner Tipp aus dem R-Praxisleben. Beispiel: In einer Matrix (respektive data.frame) jede Zeile verdoppeln.

1
2
3
4
5
6
daten < - mtcars
 
#Doppelte Zeilen direkt untereinander
daten_doppelt <- daten[rep(1:nrow(daten),each=2),]
#Doppelte untereinander
daten_doppelt2 <- daten[rep(1:nrow(daten),times=2),]

Ja das ist wirklich nicht schwer. Die Grundidee: Die Selektionsvektoren, welche immer in den eckigen Klammern stehen, kann man natürlich auch nutzen um bestimmte Zeilen mehrfach zu wählen.

Damit es nicht nur bei diesem simplen Beispiel bleibt, was vielleicht jedem eingefallen wäre, noch ein paar Ideen, wie man mit dieser simplen Methode auch wesentlich komplexere Verdopplungen durchführen kann.
Read the rest of this entry »

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


Read the rest of this entry »

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.
Read the rest of this entry »

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.
Read the rest of this entry »

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

Read the rest of this entry »