detta inlägg ger en kort genomgång av den sammanlagda funktionen som används för data.ramar och presenterar några intressanta användningsområden: från det triviala men praktiska till de mest komplicerade problemen jag har löst med aggregat.
Aggregate
är en funktion i bas R som, som namnet antyder, kan aggregera den inmatade data.frame
d.f genom att tillämpa en funktion som anges av parametern FUN
på varje kolumn med underdata.ramar definierade av inmatningsparametern by
.
parametern by
måste vara list
. Eftersom data.frame
hanteras som (namngivna) listor med kolumner kan en eller flera kolumner med en data.frame
också skickas som parametern by
. Intressant, om dessa kolumner är av samma data.frame
som den som matas in som x
, överförs inte dessa kolumner till funktionen FUN
.
funktionen som ska tillämpas måste kunna acceptera en vector
(eftersom den kommer att anropas med delar av en kolumn med en data.frame
som inmatning).
deldata.ramar definierade av inmatningsparametern by
kan betraktas som logisk indexering:
d.f <- data.frame(rating = c("AAA", "A", "A", "AAA", "BB", "BB", "AAA", "A"))i <- 1by <- d.f$ratingsub.data.frame <- d.f, ]
och gör detta för varje i
mellan 1 och length(unique(by))
. Observera att variabeln by
inte behöver överensstämma med en (eller flera) kolumn i data.frame
men kan vara vad som helst. Därför kan man reproducera aggregate
– funktionaliteten med en for
– cykel som kör cykelvariabeln över de unika värdena för variabeln som passerat som by
och en sapply
som tillämpar funktionen som passerat som FUN
till varje kolumn i data.frame
sub.data.ram. En sådan lösning skulle dock vara mycket svår att dokumentera, eftersom det skulle vara oklart vad (och varför) den här koden faktiskt gör.
Aggregate
returnerar alltid en data.frame
som ett resultat. Denna data.frame
kommer att innehålla (nu unika) värden från inmatningsparametern by
som den första kolumnen och sedan kolumner som innehåller resultaten av samtalet till funktionen i parametern FUN
som tillämpas på delarna av kolumnerna i den inmatade data.frame
. Det är intressant att notera att om funktionen FUN
returnerar flera värden, kommer klassen av kolumnerna i resultatet data.frame
att vara list
eller något a list
kan gjutas till (se det sista exemplet nedan).
det är viktigt att notera att funktionsanropet tillämpas på namnlösa vektorer snarare än namngivna kolumner av en data.frame
och därmed hänvisar till namnen på data.frame
kommer inte att fungera, inte heller kommer kolumnreferenser som s.d.f
.
grundläggande exempel
de mest grundläggande användningarna av aggregat involverar basfunktioner som mean
och sd
. Det är verkligen en av de vanligaste användningarna av aggregate
för att jämföra medelvärdet eller andra egenskaper hos provgrupper.
nyligen reproducerade jag beräkningar från ett Excel-ark. De flesta formler var delsummor och totalsummor. Excel-arket var inte särskilt bekvämt organiserat för detta ändamål: summor över rader, kolumner och summor av dessa summor användes. I R har jag ändrat data till en stjärnschemarepresentation (när alla metadata representeras radvis och varje värde får sin egen rad) med reshape2
paket och melt
sedan används aggregate
längs olika variabler för att få de olika summorna. Ju mindre variabler du använder i by
desto mer aggregerade slutresultatet: totalsumman längs en dimension använder helt enkelt den dimensionen som ”av”, medan delsummor kan uppnås med flera variabler som by
. FUN
i detta fall var naturligtvis sum
.
en praktisk användning av aggregat och en basfunktion är att få antalet framträdanden av de olika värdena:
min favorit användning av aggregat med en basfunktion är att få den sista dagen i varje månad i en serie datum. För att göra det kan man använda följande kod (förutsatt att dina datum lagras i ett” ÅÅÅÅ-MM-DD ” – format som strängar eller som Date
):
detta kom väl till pass när du arbetar med bankinformation där den sista dagen i månaden berodde på bank helgdagar samt helger.
avancerade användningar
mer avancerade användningar av aggregate
beror på att du skriver din egen function
, t.ex. anonyma funktioner som vidarebefordras som parametern FUN
. För att göra det kan man använda syntaxen
# do not run the syntaxaggregate(x = d.f, by = by.list, FUN = function(s.d.f){y <- s.d.f; return(y)}
de möjliga användningsområdena sträcker sig från att ringa komplexa portföljriskmätningar för de homogena riskgrupperna i en portfölj genom att anpassa en distribution till kategorier av prover till allt du kan avbilda, verkligen.
här är ett exempel med ett ”komplext” portföljriskvärde (exponering mot olika motparter i olika tillgångsklasser):
här är användningen av aggregate()
funktion.
Nästa upp: montera en Gaussisk fördelning till observationer efter kategorier:
nedan använder vi funktionen aggregate()
för att hitta medelvärdet och standardavvikelsen efter kategorier.
detta sista exempel visar flera intressanta egenskaper. För det första behöver data.frame
till aggregate
och listan över by
variabler inte vara samma. Även om detta antyds på andra ställen i inlägget är detta ett uttryckligt exempel på en sådan inställning. För det andra är funktionen som skickas som FUN
inte bara en anonym funktion, den är curried från en funktion med mer än en ingångsparameter. En funktion av en enda ingångsvariabel observations
har skapats från funktionen med två ingångar fitdistr
: fixa en av ingångsvariablerna genom att ställa in densfun = "normal"
. För det tredje, snarare än att returnera hela returvärdet för funktionen fitdistr
, är returvärdet begränsat till elementet estimate
från returvärdet. Och sist men inte minst består returvärdet för den anonyma funktionen som skickas till FUN
av två variabler och inte bara en. Intressant, aggregate kastar returvärdet från list
till en matrix
och namnger elementen för oss. Dessa namn kan dock inte användas för att referera till kolumnerna i matrisen. Du kan dock referera till dem enligt följande:
distr.estimate$observation] 3.016988
avslutande ord
jag hoppas att du har hittat ovanstående användbara. Nu när du är mer bekant med aggregate
är det dags för sanningen: allt ovan och mycket mer kan göras med data.table
och med en mycket snabbare prestanda. Men data.table
har en komplex syntax och man måste verkligen förstå hur saker fungerar under huven, medan aggregate
är enkel och insiktsfull. Tills du är bekväm med både logiken för aggregering och syntaxen för data.table
är det en värdig investering att först skriva koden med aggregate
och sedan optimera den genom att skriva om den med data.table
.
för dig som är intresserad kommer ett dedikerat inlägg där ovanstående är redone med data.table
, tillsammans med några ytterligare användningsfall som är specifika för data.table
.