acest post oferă o scurtă trecere în revistă a funcției agregate utilizate pentru date.cadre și prezintă câteva utilizări interesante: de la triviale, dar la îndemână la cele mai complicate probleme pe care le-am rezolvat cu aggregate.
Aggregate
este o funcție din baza R care, după cum sugerează și numele, poate agrega data.frame
d.f introdus prin aplicarea unei funcții specificate de parametrul FUN
la fiecare coloană de sub-date.cadre definite de parametrul de intrare by
.
parametrul by
trebuie să fie list
. Cu toate acestea, deoarece data.frame
sunt tratate ca liste (numite) de coloane, una sau mai multe coloane ale unui data.frame
pot fi transmise și ca parametru by
. Interesant, dacă aceste coloane sunt de aceeași data.frame
ca cea introdusă ca x
, acele coloane nu sunt transmise funcției FUN
.
funcția de aplicat trebuie să poată accepta un vector
(deoarece va fi apelat cu părți dintr-o coloană a unui data.frame
ca intrare).
sub-date.cadrele definite de parametrul de intrare by
pot fi considerate indexare logică:
d.f <- data.frame(rating = c("AAA", "A", "A", "AAA", "BB", "BB", "AAA", "A"))i <- 1by <- d.f$ratingsub.data.frame <- d.f, ]
și faceți acest lucru pentru fiecare i
între 1 și length(unique(by))
. Rețineți că variabila by
nu trebuie să fie de acord cu una (sau mai multe) coloane din data.frame
, dar ar putea fi orice. Prin urmare, se poate reproduce funcționalitatea aggregate
printr-un ciclu for
care rulează variabila ciclului peste valorile unice ale variabilei transmise ca by
și un sapply
care aplică funcția transmisă ca FUN
la fiecare coloană a sub-ului data.frame
.data.cadru. Cu toate acestea, o astfel de soluție ar fi foarte dificil de documentat, deoarece nu ar fi clar ce (și de ce) face acest cod.
Aggregate
returnează întotdeauna un data.frame
ca rezultat. Acest data.frame
va conține valorile (acum unice) din parametrul de intrare by
ca prima coloană și apoi coloane care conțin rezultatele apelului către funcția din parametrul FUN
aplicat părților coloanelor din data.frame
introdus. Este interesant de observat că dacă funcția FUN
returnează mai multe valori, clasa coloanelor rezultatului data.frame
va fi list
sau ceva la care se poate arunca list
(Vezi ultimul exemplu de mai jos).
este important să rețineți că apelul de funcții este aplicat vectorilor fără nume, mai degrabă decât coloanelor numite ale unui data.frame
și, prin urmare, referindu-se la numele data.frame
nu va funcționa și nici referințele coloanelor, cum ar fi s.d.f
.
Exemple de bază
cele mai de bază utilizări ale agregatului implică funcții de bază precum mean
și sd
. Este într-adevăr una dintre cele mai frecvente utilizări ale aggregate
pentru a compara media sau alte proprietăți ale grupurilor de eșantioane.
recent am reprodus calcule dintr-o foaie Excel. Majoritatea formulelor erau subtotaluri și totaluri mari. Foaia Excel nu a fost organizată foarte confortabil în acest scop: s-au folosit sume pe rânduri, coloane și totaluri ale acestor sume. În R, am schimbat datele într-o reprezentare a schemei stea (când toate metadatele sunt reprezentate în rând și fiecare valoare primește propriul rând) folosind pachetul reshape2
și melt
apoi am folosit aggregate
de-a lungul diferitelor variabile pentru a obține totalurile diferite. Cu cât folosiți mai puține variabile în by
, cu atât rezultatul final este mai agregat: totalul general de-a lungul unei dimensiuni folosește pur și simplu acea dimensiune ca „by”, în timp ce subtotalele pot fi obținute folosind mai multe variabile ca by
. FUN
în acest caz a fost, desigur, sum
.
o utilizare la îndemână a agregatului și a unei funcții de bază este obținerea numărului de apariții ale diferitelor valori:
utilizarea mea preferată a agregatului cu o funcție de bază este obținerea ultimei zile a fiecărei luni dintr-o serie de date. Pentru a face acest lucru, se poate utiliza următorul cod (presupunând că datele dvs. sunt stocate într-un format” AAAA-LL-ZZ ” ca șiruri sau ca Date
):
acest lucru a fost foarte util atunci când lucrați cu informații bancare în care ultima zi a lunii depindea de sărbătorile bancare, precum și de weekend-uri.
utilizări avansate
utilizările mai avansate ale aggregate
depind de scrierea propriei function
, de exemplu funcțiile anonime transmise ca parametru FUN
. Pentru a face acest lucru, se poate utiliza sintaxa
# do not run the syntaxaggregate(x = d.f, by = by.list, FUN = function(s.d.f){y <- s.d.f; return(y)}
utilizările posibile variază de la apelarea valorilor complexe de risc de portofoliu pentru grupurile de risc omogene ale unui portofoliu prin montarea unei distribuții la categorii de eșantioane la orice puteți imagina, într-adevăr.
Iată un exemplu cu o valoare a riscului de portofoliu „complexă” (expunere la diferite contrapărți din diferite clase de active):
aici este utilizarea aggregate()
funcție.
următoarea: montarea unei distribuții gaussiene la observații pe categorii:
mai jos folosim funcția aggregate()
pentru a găsi media și deviația standard pe categorii.
acest ultim exemplu prezintă câteva proprietăți interesante. În primul rând, variabilele data.frame
la aggregate
și lista variabilelor by
nu trebuie să fie aceleași. Deși acest lucru este implicat în alte locuri ale postării, acesta este un exemplu explicit al unei astfel de configurații. În al doilea rând, funcția transmisă ca FUN
nu este doar o funcție anonimă, ci este curried dintr-o funcție cu mai mult de un parametru de intrare. O funcție a unei variabile de intrare unică observations
a fost creată din funcția variabilă cu două intrări fitdistr
: fixarea uneia dintre variabilele de intrare prin setarea densfun = "normal"
. În al treilea rând, în loc să returneze valoarea returnată completă a funcției fitdistr
, valoarea returnată este limitată la elementul estimate
din valoarea returnată. Și nu în ultimul rând, valoarea returnată a funcției anonime transmisă la FUN
constă din două variabile și nu numai una. Interesant este că aggregate aruncă valoarea returnată de la list
la matrix
și numește elementele pentru noi. Cu toate acestea, aceste nume nu pot fi folosite pentru a face referire la coloanele matricei. Cu toate acestea, le puteți referi după cum urmează:
distr.estimate$observation] 3.016988
Cuvinte de închidere
sper că ați găsit cele de mai sus utile. Acum că sunteți mai familiarizați cu aggregate
, este timpul pentru adevăr: totul de mai sus și multe altele se pot face cu data.table
și cu o performanță mult mai rapidă. Cu toate acestea, data.table
are o sintaxă complexă și trebuie să înțelegem cu adevărat cum funcționează lucrurile sub capotă, în timp ce aggregate
este simplu și perspicace. Până când nu vă simțiți confortabil atât cu logica agregării, cât și cu sintaxa data.table
, este o investiție demnă să scrieți Mai întâi codul folosind aggregate
și apoi să îl optimizați rescriindu-l folosind data.table
.
pentru cei dintre voi care sunt interesați, vine o postare dedicată în care cele de mai sus sunt refăcute cu data.table
, împreună cu câteva cazuri de utilizare suplimentare specifice data.table
.