Questo post fornisce una breve revisione della funzione aggregata utilizzata per i dati.cornici e presenta alcuni usi interessanti: dai banali ma maneggevoli ai problemi più complicati che ho risolto con aggregate.
Aggregate
è una funzione in base R che può, come suggerisce il nome, aggregare il data.frame
d.f immesso applicando una funzione specificata dal parametro FUN
a ciascuna colonna di sottodati.fotogrammi definiti dal parametro di input by
.
Il parametro by
deve essere un list
. Tuttavia, poiché gli data.frame
sono gestiti come elenchi di colonne (denominati), una o più colonne di un data.frame
possono anche essere passate come parametro by
. È interessante notare che, se queste colonne hanno lo stesso data.frame
di quello immesso come x
, tali colonne non vengono passate alla funzione FUN
.
La funzione da applicare deve essere in grado di accettare un vector
(poiché verrà chiamata con parti di una colonna di un data.frame
come input).
I dati secondari.i frame definiti dal parametro di input by
possono essere considerati come indicizzazione logica:
d.f <- data.frame(rating = c("AAA", "A", "A", "AAA", "BB", "BB", "AAA", "A"))i <- 1by <- d.f$ratingsub.data.frame <- d.f, ]
e farlo per ogni i
tra 1 e length(unique(by))
. Si noti che la variabile by
non deve essere d’accordo con una (o più) colonna di data.frame
ma potrebbe essere qualsiasi cosa. Quindi, è possibile riprodurre la funzionalità aggregate
con un ciclo for
che esegue la variabile cycle sui valori univoci della variabile passata come by
e un sapply
applicando la funzione passata come FUN
a ciascuna colonna del sub data.frame
.dati.cornice. Tale soluzione tuttavia sarebbe molto difficile da documentare, in quanto non sarebbe chiaro cosa (e perché) questo codice stia effettivamente facendo.
Aggregate
restituisce sempre un data.frame
come risultato. Questo data.frame
conterrà i valori (ora univoci) del parametro di input by
come prima colonna e quindi colonne contenenti i risultati della chiamata alla funzione nel parametro FUN
applicato alle parti delle colonne del data.frame
immesso. È interessante notare che se la funzione FUN
restituisce più valori, la classe delle colonne del risultato data.frame
sarà list
o qualcosa a list
può essere lanciato (vedi l’ultimo esempio sotto).
È importante notare che la chiamata di funzione viene applicata a vettori senza nome piuttosto che a colonne denominate di un data.frame
e quindi fare riferimento ai nomi di data.frame
non funzionerà, né i riferimenti a colonne come s.d.f
.
Esempi di base
Gli usi più basilari di aggregate coinvolgono funzioni di base come mean
e sd
. È infatti uno degli usi più comuni di aggregate
per confrontare la media o altre proprietà dei gruppi di campioni.
Recentemente ho riprodotto i calcoli da un foglio Excel. La maggior parte delle formule erano subtotali e totali generali. Il foglio Excel non è stato organizzato molto comodamente per questo scopo: sono state utilizzate somme su righe, colonne e totali di tali somme. In R, ho cambiato i dati in una rappresentazione dello schema a stella (quando tutti i metadati sono rappresentati a righe e ogni valore ottiene la propria riga) usando reshape2
pacchetto e melt
quindi usato aggregate
lungo diverse variabili per ottenere i diversi totali. Meno variabili si utilizzano in by
più aggregato è il risultato finale: il totale complessivo lungo una dimensione utilizza semplicemente tale dimensione come “by”, mentre i subtotali possono essere raggiunti utilizzando più variabili come by
. Il FUN
in questo caso era ovviamente sum
.
Un uso pratico di aggregate e una funzione di base sta ottenendo il numero di apparizioni dei vari valori:
Il mio uso preferito di aggregate con una funzione di base sta ottenendo l’ultimo giorno di ogni mese in una serie di date. Per fare ciò, è possibile utilizzare il seguente codice (supponendo che le date siano memorizzate in un formato” AAAA-MM-GG ” come stringhe o come Date
):
Questo è stato molto utile quando si lavora con informazioni bancarie in cui l’ultimo giorno del mese dipendeva dalle festività bancarie e dai fine settimana.
Usi avanzati
Usi più avanzati di aggregate
dipendono dalla scrittura del proprio function
, ad esempio funzioni anonime trasmesse come parametro FUN
. Per fare ciò, è possibile utilizzare la sintassi
# do not run the syntaxaggregate(x = d.f, by = by.list, FUN = function(s.d.f){y <- s.d.f; return(y)}
I possibili usi vanno dalla chiamata di metriche di rischio di portafoglio complesse per i gruppi di rischio omogenei di un portafoglio tramite l’adattamento di una distribuzione a categorie di campioni a qualsiasi cosa si possa immaginare, davvero.
Ecco un esempio con una metrica del rischio di portafoglio “complesso” (esposizione a diverse controparti in diverse classi di attività):
Ecco l’uso della funzione aggregate()
.
Avanti: adattare una distribuzione gaussiana alle osservazioni per categorie:
Di seguito usiamo la funzione aggregate()
per trovare la media e la deviazione standard per categorie.
Quest’ultimo esempio presenta diverse proprietà interessanti. Innanzitutto, data.frame
a aggregate
e l’elenco delle variabili by
non devono essere uguali. Mentre questo è implicito in altri punti del post, questo è un esempio esplicito di tale configurazione. In secondo luogo, la funzione passata come FUN
non è solo una funzione anonima, viene corrotta da una funzione con più di un parametro di input. Una funzione di una singola variabile di ingresso observations
è stata creata dalla funzione variabile a due ingressi fitdistr
: fissa una delle variabili di ingresso impostando densfun = "normal"
. In terzo luogo, anziché restituire il valore di ritorno completo della funzione fitdistr
, il valore di ritorno è limitato all’elemento estimate
dal valore di ritorno. E, ultimo ma non meno importante, il valore restituito della funzione anonima passata a FUN
consiste di due variabili e non solo una. È interessante notare che aggregate lancia il valore restituito da list
a matrix
e nomina gli elementi per noi. Tuttavia, questi nomi non possono essere utilizzati per fare riferimento alle colonne della matrice. È tuttavia possibile fare riferimento a loro come segue:
distr.estimate$observation] 3.016988
Parole di chiusura
Spero che tu abbia trovato utile quanto sopra. Ora che hai più familiarità con aggregate
, è il momento della verità: tutto quanto sopra e molto altro può essere fatto con data.table
e con prestazioni molto più veloci. Tuttavia, data.table
ha una sintassi complessa e bisogna davvero capire come funzionano le cose sotto il cofano, mentre aggregate
è semplice e perspicace. Fino a quando non ti senti a tuo agio sia con la logica di aggregazione che con la sintassi di data.table
, è un investimento degno scrivere prima il codice usando aggregate
e poi ottimizzarlo riscrivendolo usando data.table
.
Per quelli di voi che sono interessati, sta arrivando un post dedicato in cui quanto sopra è rifatto con data.table
, insieme ad alcuni casi d’uso aggiuntivi specifici per data.table
.