Menu

Raggruppare e riassumere in R (aggregate, tapply, dplyr)

Tutti i modi per calcolare statistiche per gruppo in R: contare con table(), tapply() per una statistica per gruppo, l'interfaccia a formula di aggregate() e il group_by() con summarize() di dplyr.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Contare le righe per gruppo: table()

La domanda di raggruppamento più semplice è "quanti di ciascuno?", e R base risponde in una sola chiamata. table() conta quante volte compare ogni valore:

Una colonna dà i conteggi per valore; due colonne danno una tabella di contingenza completa (regioni sulle righe, piani sulle colonne). Per sapere "che quota?" avvolgila in prop.table(table(...)). table() è la strada più rapida verso una risposta sulle frequenze in tutto R: non ricorrere a niente di più pesante quando ti serve solo un conteggio.

Una statistica per gruppo: tapply()

tapply(values, groups, function) divide il primo vettore secondo il secondo e applica la funzione a ogni pezzo:

Il risultato è un vettore con nomi, con le etichette dei gruppi come nomi e le statistiche come valori, ed è perfetto per consultazioni rapide (means["EU"]). Il nome si legge come "table apply": applicare una funzione lungo una tabella di raggruppamento. Appartiene alla stessa famiglia di sapply() e lapply(), trattate nella guida alla famiglia apply.

Il limite di tapply() è la forma: un vettore con nomi è scomodo da unire, rappresentare in un grafico o continuare a elaborare. Quando il riepilogo è un passaggio intermedio e non la risposta finale, vuoi indietro un data frame, ed è proprio quello che restituisce lo strumento successivo.

Il cavallo da tiro delle formule: aggregate()

aggregate() è il group-by completo di R base: restituisce un data frame, e la sua interfaccia a formula si legge come la frase che diresti. value ~ group significa "value, suddiviso per group":

Aggiungere raggruppatori è solo un + altra_colonna nella formula: la seconda chiamata somma per ogni combinazione di regione e trimestre. Puoi anche aggregare più colonne di valori insieme con cbind(a, b) ~ group. Dato che l'output è un normale data frame, si inserisce direttamente in un merge, un ordinamento o un grafico: è lo strumento base da usare di default per i riepiloghi per gruppo.

Un comportamento silenzioso da conoscere: l'interfaccia a formula scarta le righe con NA in una qualsiasi colonna usata prima di aggregare. Di solito è quello che vuoi; ogni tanto è la spiegazione di un conteggio che sembra basso.

Il modo dplyr: group_by() + summarize()

Lo standard moderno è lo schema a due verbi di dplyr: group_by() dichiara il raggruppamento, summarize() riduce ogni gruppo a una riga, calcolando tutte le statistiche che nomini (statico; la sandbox esegue solo R base):

library(dplyr)

sales |>
    group_by(region) |>
    summarize(
        n     = n(),
        total = sum(amount),
        avg   = mean(amount)
    )

Qui dplyr supera davvero R base: più statistiche per gruppo in una sola chiamata leggibile (a aggregate() servono contorsioni per farlo), in più n() gratis, e il risultato scorre dritto nella pipe successiva. (summarise() è la stessa funzione, con la grafia britannica.)

Una cosa che spiazza chi inizia: con più raggruppatori, summarize() toglie solo l'ultimo, lasciando il risultato ancora raggruppato, e stampa un messaggio a riguardo. Di' esplicitamente cosa vuoi con l'argomento .groups: summarize(avg = mean(amount), .groups = "drop") restituisce un data frame semplice, non raggruppato, ed è la buona abitudine di default. Un data frame raggruppato che si infila nel codice successivo fa lavorare mutate() e compagnia per gruppo senza avvisarti: una fonte classica di risultati confusi.

Come scegliere tra loro

  • Un conteggio: table(), niente batte una sola chiamata.
  • Una statistica, un'occhiata veloce: tapply(), e leggi la risposta dal vettore con nomi.
  • Data frame in uscita, ambiente solo base: aggregate() con una formula.
  • Più statistiche, parte di una pipeline, o qualsiasi cosa ambiziosa: group_by() |> summarize().

Non c'è una risposta sbagliata tra queste: calcolano tutte gli stessi numeri. Ma scegliere lo strumento in base alla forma di output che ti serve ti risparmia il passaggio di conversione dopo. Medie, mediane e dispersioni vere e proprie sono trattate in statistica descrittiva.

Esempio svolto: mtcars per numero di cilindri

Tutto insieme su un dataset integrato: per numero di cilindri, quante auto ci sono e i loro consumi e potenza medi:

Undici auto a 4 cilindri con una media di circa 26.7 mpg, sette a 6 cilindri intorno a 19.7, quattordici a 8 cilindri intorno a 15.1, e la potenza che va nella direzione opposta. Due chiamate, un'intera tabella di riepilogo: è proprio il tipo di domanda a cui serve l'aggregazione per gruppi.

Cosa ti porti a casa

  • table() per i conteggi, prop.table() per le quote.
  • tapply(values, groups, fn) restituisce un vettore con nomi: occhiate veloci, consultazioni facili.
  • aggregate(value ~ group, data, FUN) restituisce un data frame; + aggiunge raggruppatori, cbind() aggiunge colonne di valori.
  • Il group_by() |> summarize(n = n(), avg = mean(x), .groups = "drop") di dplyr è lo standard moderno per riepiloghi con più statistiche.
  • Scegli in base alla forma dell'output; sui numeri sono tutti d'accordo.

Prossimo passo: combinare tabelle che condividono una chiave, con merge() e la famiglia di join di dplyr.

Domande frequenti

Come si calcola la media per gruppo in R?

R base ha due strumenti: tapply(df$value, df$group, mean) restituisce un vettore con nomi delle medie per gruppo, e aggregate(value ~ group, data = df, FUN = mean) restituisce lo stesso risultato come data frame. In dplyr: df |> group_by(group) |> summarize(avg = mean(value)).

Come si contano le occorrenze per gruppo in R?

table(df$group) conta le righe per ogni valore del gruppo in una sola chiamata; table(df$a, df$b) incrocia due colonne in una tabella di contingenza. In dplyr, count(df, group) fa lo stesso e restituisce un data frame, più comodo da continuare a elaborare.

Cosa fa aggregate() in R?

aggregate() divide un data frame secondo una o più colonne di raggruppamento, applica una funzione a ogni pezzo e restituisce un data frame di risultati. L'interfaccia a formula si legge in modo naturale: aggregate(sales ~ region + quarter, data = df, FUN = mean) significa sales, raggruppato per region e quarter, in media.

Qual è la differenza tra tapply e aggregate?

Stesso calcolo, forma di output diversa. tapply() restituisce un vettore con nomi (o un array con due raggruppatori): comodo per consultazioni rapide. aggregate() restituisce un data frame: meglio quando il risultato alimenta altre analisi, un merge o un grafico. Nel dubbio, aggregate().

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA