Come contare per gruppo in R

Il conteggio per più gruppi, a volte chiamato rapporti a campi incrociati, può essere un modo utile per esaminare i dati che vanno dai sondaggi di opinione pubblica ai test medici. Ad esempio, come hanno votato le persone per sesso e fascia di età? Quanti sviluppatori di software che usano sia R che Python sono uomini contro donne?

Ci sono molti modi per fare questo tipo di conteggio per categorie in R. Qui, vorrei condividere alcuni dei miei preferiti.

Per le demo in questo articolo, userò un sottoinsieme del sondaggio Stack Overflow Developers, che esamina gli sviluppatori su dozzine di argomenti che vanno dagli stipendi alle tecnologie utilizzate. Lo ridurrò con colonne per le lingue utilizzate, il sesso e se codificano come hobby. Ho anche aggiunto la mia colonna LanguageGroup per indicare se uno sviluppatore ha segnalato di utilizzare R, Python, entrambi o nessuno dei due.

Se desideri seguire, l'ultima pagina di questo articolo contiene le istruzioni su come scaricare e gestire i dati per ottenere lo stesso set di dati che sto utilizzando.

I dati hanno una riga per ogni risposta al sondaggio e le quattro colonne sono tutte caratteri.

str (mydata) 'data.frame': 83379 obs. di 4 variabili: $ Gender: chr "Man" "Man" "Man" "Man" ... $ LanguageWorkedCon: chr "HTML / CSS; Java; JavaScript; Python" "C ++; HTML / CSS; Python" "HTML / CSS "" C; C ++; C #; Python; SQL "... $ Hobbyist: chr" Sì "" No "" Sì "" No "... $ LanguageGroup: chr" Python "" Python "" Né "" Python "...

Ho filtrato i dati grezzi per rendere più gestibili le tabelle a campi incrociati, inclusa la rimozione dei valori mancanti e l'utilizzo solo dei due sessi più grandi, Uomo e Donna.

Il pacchetto del bidello

Allora, qual è la ripartizione di genere all'interno di ogni gruppo linguistico? Per questo tipo di segnalazione in un data frame, uno dei miei strumenti preferiti è la tabyl()funzione del pacchetto bidello . 

La tabyl()funzione di base restituisce un frame di dati con i conteggi. Il nome della prima colonna che aggiungi a un tabyl()argomento diventa la riga e il secondo la colonna

libreria (bidello) tabyl (mydata, Gender, LanguageGroup)

Genere Entrambi Né Python R Uomo 3264 43908 29044969 Donna 374 3705 1940175

La cosa bella tabyl()è che è anche molto facile generare percentuali. Se vuoi vedere le percentuali per ogni colonna invece dei totali non elaborati, aggiungi adorn_percentages("col"). È quindi possibile reindirizzare questi risultati in una funzione di formattazione come  adorn_pct_formatting().

tabyl (mydata, Gender, LanguageGroup)%>%

adorn_percentages ("col")%>%

adorn_pct_formatting (cifre = 1)

Genere Entrambi Né Python R Uomo 89,7% 92,2% 93,7% 84,7% Donna 10,3% 7,8% 6,3% 15,3%

Per vedere le percentuali per riga, aggiungi adorn_percentages("row")

Se vuoi aggiungere una terza variabile, come Hobbyist, anche questo è facile.

tabyl (mydata, Gender, LanguageGroup, Hobbyist)%>%

adorn_percentages ("col")%>%

adorn_pct_formatting (cifre = 1)

Tuttavia, in questo modo diventa un po 'più difficile confrontare visivamente i risultati su più di due livelli. Questo codice restituisce un elenco con un frame di dati per ogni scelta di terzo livello:

$ No Genere Entrambi Né Python R Uomo 79,6% 86,7% 86,4% 74,6% Donna 20,4% 13,3% 13,6% 25,4% $ Sì Sesso Entrambi Né Python R Uomo 91,6% 93,9% 95,0% 88,0% Donna 8,4% 6,1% 5,0% 12,0%

Il pacchetto CGPfunctions

Vale la pena dare un'occhiata al pacchetto CGPfunctions per alcuni modi semplici e veloci per visualizzare i dati dei campi incrociati. Installalo da CRAN con il solito install.packages("CGPfunctions").

Il pacchetto ha due funzioni di interesse per esaminare i campi incrociati: PlotXTabs()e PlotXTabs2(). Questo codice restituisce grafici a barre dei dati (primo grafico sotto):

libreria (funzioni CGP)

PlotXTabs (mydata)

Schermata di Sharon Machlis,

PlotXTabs2(mydata) crea un grafico con un aspetto diverso e alcuni riepiloghi statistici (secondo grafico a sinistra).

Se non hai bisogno o desideri quei riepiloghi, puoi rimuoverli con results.subtitle = FALSE, ad esempio  PlotXTabs2(mydata, LanguageGroup, Gender, results.subtitle = FALSE).

Schermata di Sharon Machlis,

PlotXTabs2()ha un paio di dozzine di opzioni di argomento, inclusi titolo, didascalia, legende, combinazione di colori e uno dei quattro tipi di trama: lato, pila, mosaico o percentuale. Ci sono anche opzioni familiari agli utenti di ggplot2, come ggtheme e palette. Puoi vedere maggiori dettagli nel file della guida della funzione.

Il pacchetto vtree

Il pacchetto vtree genera grafici per tabelle a campi incrociati anziché grafici. Esecuzione della vtree()funzione principale su una variabile, come 

libreria (vtree)

vtree (mydata, "LanguageGroup")

ti dà questa risposta di base:

Sharon Machlis,

Non mi piacciono i colori predefiniti qui, ma puoi scambiarli in una tavolozza RColorBrewer. L'argomento palette di vtree usa i numeri di tavolozza , non i nomi; puoi vedere come sono numerati nella documentazione del pacchetto vtree. Ad esempio, potrei scegliere 3 per i verdi e 5 per i viola. Sfortunatamente, quelle impostazioni predefinite ti danno un colore più intenso per i numeri di conteggio inferiori , il che non ha sempre senso (e non funziona bene per me in questo esempio). Posso modificare il comportamento predefinito con sortfill = TRUEper utilizzare il colore più intenso per il valore più alto. 

vtree (mydata, "LanguageGroup", palette = 3, sortfill = TRUE)

Sharon Machlis,

Se trovi che il colore scuro rende difficile la lettura del testo, ci sono alcune opzioni. Un'opzione è usare l' argomento semplice , come  vtree(mydata, "LanguageGroup", plain = TRUE). Un'altra opzione è impostare un singolo colore di riempimento invece di una tavolozza, utilizzando l' fillcolorargomento, ad esempio  vtree(mydata, LanguageGroup", fillcolor = "#99d8c9").

Per esaminare due variabili in un report a campi incrociati, è sufficiente aggiungere un secondo nome di colonna e tavolozza o colore se non si desidera l'impostazione predefinita. È possibile utilizzare l'opzione normale o specificare due tavolozze o due colori. Di seguito ho scelto colori specifici invece delle tavolozze e ho anche ruotato il grafico per leggere verticalmente.

vtree (mydata, c ("LanguageGroup", "Gender"),

fillcolor = c (LanguageGroup = "# e7d4e8", Gender = "# 99d8c9"),

horiz = FALSE)

Sharon Machlis,

You can add more than two categories, although it gets a bit harder to read and follow as the tree grows. If you’re only interested in some of the branches, you can specify which to display with the keep argument. Below, I set vtree() to show only people who use R without Python or who use both R and Python.

vtree(mydata, c("Gender", "LanguageGroup", "Hobbyist"),

horiz = FALSE, fillcolor = c(LanguageGroup = "#e7d4e8",

Gender = "#99d8c9", Hobbyist = "#9ecae1"),

keep = list(LanguageGroup = c("R", "Both")), showcount = FALSE)

Con l'albero che diventa così occupato, penso che sia utile avere il conteggio o la percentuale come etichette dei nodi, non entrambi. Quindi l'ultimo argomento nel codice sopra  showcount = FALSE,, imposta il grafico per visualizzare solo le percentuali e non i conteggi.

Sharon Machlis,

Conta di più per opzioni di gruppo

Esistono altri modi utili per raggruppare e contare in R, inclusi base R, dplyr e data.table. Base R ha la  xtabs()funzione specifica per questo compito. Nota la sintassi della formula di seguito: una tilde e quindi una variabile più un'altra variabile.

xtabs (~ LanguageGroup + Gender, data = mydata)

Genere Linguaggio Gruppo Uomo Donna Entrambi 3264374 Nessuno 43908 3705 Python 29044 1940 R 969175

La count()funzione di dplyr combina "raggruppa per" e "conta le righe in ogni gruppo" in un'unica funzione.

libreria (dplyr)

my_summary%

count(LanguageGroup, Gender, Hobbyist, sort = TRUE)

my_summary LanguageGroup Gender Hobbyist n 1 Neither Man Yes 34419 2 Python Man Yes 25093 3 Neither Man No 9489 4 Python Man No 3951 5 Both Man Yes 2807 6 Neither Woman Yes 2250 7 Neither Woman No 1455 8 Python Woman Yes 1317 9 R Man Yes 757 10 Python Woman No 623 11 Both Man No 457 12 Both Woman Yes 257 13 R Man No 212 14 Both Woman No 117 15 R Woman Yes 103 16 R Woman No 72

In the three lines of code below, I load the data.table package, create a data.table from my data, and then use the special .N data.table symbol that stands for number of rows in a group. 

library(data.table)

mydt <- setDT(mydata)

mydt[, .N, by = .(LanguageGroup, Gender, Hobbyist)]

Visualizing with ggplot2

Come con la maggior parte dei dati, ggplot2 è una buona scelta per visualizzare i risultati riepilogati. Il primo grafico ggplot sotto mostra LanguageGroup sull'asse X e il conteggio per ciascuno sull'asse Y. Il colore di riempimento rappresenta se qualcuno dice di codificare come hobby. E, facet_wrap dice: Crea un grafico separato per ogni valore nella colonna Sesso.

libreria (ggplot2)

ggplot (my_summary, aes (LanguageGroup, n, fill = Hobbyist)) +

geom_bar (stat = "identity") +

facet_wrap (facets = vars (Gender))

Sharon Machlis,

Poiché ci sono relativamente poche donne nel campione, è difficile confrontare le percentuali tra i sessi quando entrambi i grafici utilizzano la stessa scala dell'asse Y. Posso cambiarlo, però, quindi ogni grafico utilizza una scala separata, aggiungendo l'argomento scales = “free_y”alla facet_wrap()funzione:

ggplot (my_summary, aes (LanguageGroup, n, fill = Hobbyist)) +

geom_bar (stat = "identity") +

facet_wrap (facets = vars (Gender), scale = "free_y")

Ora è più facile confrontare più variabili in base al sesso.

Per ulteriori suggerimenti R, vai alla pagina "Fai di più con R" o controlla la playlist di YouTube "Fai di più con R".

Vedere la pagina successiva per informazioni su come scaricare e gestire i dati utilizzati in questa demo.