Dieser Beitrag gibt einen kurzen Überblick über die Aggregatfunktion, wie sie für Daten verwendet wird.frames und präsentiert einige interessante Anwendungen: von den trivialen, aber handlichen bis zu den kompliziertesten Problemen, die ich mit Aggregate gelöst habe.
Aggregate
ist eine Funktion in base R, die, wie der Name schon sagt, das eingegebene data.frame
df aggregieren kann, indem sie eine durch den Parameter FUN
angegebene Funktion auf jede Spalte von Subdaten anwendet.frames, die durch den Eingabeparameter by
definiert werden.
Der Parameter by
muss ein list
sein. Da data.frame
jedoch als (benannte) Spaltenlisten behandelt werden, können eine oder mehrere Spalten eines data.frame
auch als by
Parameter übergeben werden. Interessanterweise werden diese Spalten nicht an die Funktion FUN
übergeben, wenn diese Spalten dieselbe data.frame
wie die als x
eingegebene haben.
Die anzuwendende Funktion muss a vector
akzeptieren können (da sie mit Teilen einer Spalte von a data.frame
als Eingabe aufgerufen wird).
Die Unterdaten.frames, die durch den Eingabeparameter by
definiert werden, können als logische Indizierung betrachtet werden:
d.f <- data.frame(rating = c("AAA", "A", "A", "AAA", "BB", "BB", "AAA", "A"))i <- 1by <- d.f$ratingsub.data.frame <- d.f, ]
und tun dies für jeden i
zwischen 1 und length(unique(by))
. Beachten Sie, dass die Variable by
nicht mit einer (oder mehreren) Spalten von data.frame
übereinstimmen muss, sondern alles sein kann. Daher kann man die aggregate
-Funktionalität reproduzieren, indem ein for
-Zyklus die Zyklusvariable über die eindeutigen Werte der als by
übergebenen Variablen ausführt und ein sapply
die als FUN
übergebene Funktion auf jede Spalte des data.frame
-Sub anwendet.Daten.Rahmen. Eine solche Problemumgehung wäre jedoch sehr schwierig zu dokumentieren, da unklar wäre, was (und warum) dieser Code tatsächlich tut.
Aggregate
gibt immer ein data.frame
als Ergebnis zurück. Dieses data.frame
enthält die (jetzt eindeutigen) Werte aus dem Eingabeparameter by
als erste Spalte und dann Spalten, die die Ergebnisse des Aufrufs der Funktion im Parameter FUN
enthalten, der auf die Teile der Spalten des eingegebenen data.frame
angewendet wird. Es ist interessant festzustellen, dass, wenn die Funktion FUN
mehrere Werte zurückgibt, die Klasse der Spalten des Ergebnisses data.frame
list
oder etwas ist, in das a list
umgewandelt werden kann (siehe das letzte Beispiel unten).
Es ist wichtig zu beachten, dass der Funktionsaufruf auf namenlose Vektoren und nicht auf benannte Spalten von a data.frame
angewendet wird und daher weder auf die Namen von data.frame
noch auf Spaltenreferenzen wie s.d.f
.
Grundlegende Beispiele
Die grundlegendsten Verwendungen von Aggregate beinhalten Basisfunktionen wie mean
und sd
. Es ist in der Tat eine der häufigsten Verwendungen von aggregate
, um den Mittelwert oder andere Eigenschaften von Stichprobengruppen zu vergleichen.
Kürzlich habe ich Berechnungen aus einer Excel-Tabelle reproduziert. Die meisten Formeln waren Zwischensummen und Gesamtsummen. Die Excel-Tabelle war für diesen Zweck nicht sehr komfortabel organisiert: Summen über Zeilen, Spalten und Summen dieser Summen wurden verwendet. In R habe ich die Daten in eine Sternschemadarstellung geändert (wenn alle Metadaten zeilenweise dargestellt werden und jeder Wert eine eigene Zeile erhält), indem ich das Paket reshape2
und melt
verwendet und dann aggregate
entlang verschiedener Variablen verwendet habe, um die verschiedenen Summen zu erhalten. Je weniger Variablen Sie in by
verwenden, desto aggregierter ist das Endergebnis: Die Gesamtsumme entlang einer Dimension verwendet diese Dimension einfach als „by“, während Zwischensummen mit mehreren Variablen als by
erreicht werden können. Die FUN
war in diesem Fall natürlich sum
.
Eine praktische Verwendung von Aggregate und einer Basisfunktion ist das Abrufen der Anzahl der Erscheinungen der verschiedenen Werte:
Meine bevorzugte Verwendung von Aggregate mit einer Basisfunktion ist das Abrufen des letzten Tages eines jeden Monats in einer Reihe von Daten. Dazu kann man den folgenden Code verwenden (vorausgesetzt, Ihre Daten werden im Format „JJJJ-MM-TT“ als Zeichenfolgen oder als Date
):
Dies war sehr praktisch bei der Arbeit mit Bankinformationen, bei denen der letzte Tag des Monats sowohl von Feiertagen als auch von Wochenenden abhing.
Erweiterte Verwendungen
Erweiterte Verwendungen von aggregate
hängen vom Schreiben eigener function
ab, z. B. anonyme Funktionen, die als Parameter FUN
übergeben werden. Dazu kann man die Syntax
# do not run the syntaxaggregate(x = d.f, by = by.list, FUN = function(s.d.f){y <- s.d.f; return(y)}
Die Einsatzmöglichkeiten reichen vom Aufruf komplexer Portfoliorisikometriken für die homogenen Risikogruppen eines Portfolios über die Anpassung einer Verteilung an Stichprobenkategorien bis hin zu allem, was man sich vorstellen kann.
Hier ist ein Beispiel mit einer „komplexen“ Portfoliorisikometrik (Exposition gegenüber verschiedenen Gegenparteien in verschiedenen Anlageklassen):
Hier ist die Verwendung der Funktion aggregate()
.
Als nächstes: Anpassung einer Gaußschen Verteilung an Beobachtungen nach Kategorien:
Im Folgenden verwenden wir die Funktion aggregate()
, um den Mittelwert und die Standardabweichung nach Kategorien zu ermitteln.
Dieses letzte Beispiel zeigt einige interessante Eigenschaften. Erstens müssen die Variablen data.frame
bis aggregate
und die Liste der Variablen by
nicht identisch sein. Während dies an anderen Stellen des Beitrags impliziert ist, ist dies ein explizites Beispiel für ein solches Setup. Zweitens ist die als FUN
übergebene Funktion nicht nur eine anonyme Funktion, sondern wird von einer Funktion mit mehr als einem Eingabeparameter curried. Aus der Zwei-Eingangsvariablen-Funktion fitdistr
wurde eine Funktion einer einzelnen Eingangsvariablen observations
erstellt: Fixieren einer der Eingangsvariablen durch Setzen von densfun = "normal"
. Drittens ist der Rückgabewert nicht auf den vollständigen Rückgabewert der Funktion fitdistr
beschränkt, sondern auf das Element estimate
aus dem Rückgabewert. Und zu guter Letzt besteht der Rückgabewert der an FUN
übergebenen anonymen Funktion aus zwei Variablen und nicht nur aus einer. Interessanterweise konvertiert aggregate den Rückgabewert von list
in a matrix
und benennt die Elemente für uns. Diese Namen können jedoch nicht verwendet werden, um auf die Spalten der Matrix zu verweisen. Sie können sie jedoch wie folgt referenzieren:
distr.estimate$observation] 3.016988
Abschließende Worte
Ich hoffe, dass Sie das oben Genannte nützlich gefunden haben. Jetzt, da Sie mit aggregate
besser vertraut sind, ist es Zeit für die Wahrheit: Alles oben Genannte und vieles mehr kann mit data.table
und mit einer viel schnelleren Leistung erreicht werden. data.table
hat jedoch eine komplexe Syntax und man muss wirklich verstehen, wie die Dinge unter der Haube funktionieren, während aggregate
einfach und aufschlussreich ist. Bis Sie sowohl mit der Logik der Aggregation als auch mit der Syntax von data.table
vertraut sind, ist es eine lohnende Investition, den Code zuerst mit aggregate
zu schreiben und ihn dann durch Umschreiben mit data.table
zu optimieren.
Für diejenigen unter Ihnen, die interessiert sind, kommt ein spezieller Beitrag, in dem das Obige mit data.table
zusammen mit einigen zusätzlichen Anwendungsfällen, die für data.table
spezifisch sind, wiederholt wird.