Hur man räknar efter grupp i R

Att räkna med flera grupper - ibland kallat korstabrapporter - kan vara ett användbart sätt att titta på data som sträcker sig från opinionsundersökningar till medicinska tester. Till exempel, hur röstade människor efter kön och åldersgrupp? Hur många programutvecklare som använder både R och Python är män mot kvinnor?

Det finns många sätt att göra denna typ av räkning efter kategorier i R. Här vill jag dela några av mina favoriter.

För demos i den här artikeln använder jag en delmängd av Stack Overflow Developers-undersökningen, som undersöker utvecklare om dussintals ämnen, allt från löner till tekniker som används. Jag slår ner det med kolumner för språk, kön och om de kodar som en hobby. Jag lade också till min egen LanguageGroup-kolumn för huruvida en utvecklare rapporterade med R, Python, båda eller ingen av dem.

Om du vill följa med har den sista sidan i den här artikeln instruktioner om hur du laddar ner och vred data för att få samma datamängd som jag använder.

Data har en rad för varje enkätsvar och de fyra kolumnerna är alla tecken.

str (mydata) 'data.frame': 83379 obs. av 4 variabler: $ Kön: chr "Man" "Man" "Man" "Man" ... $ LanguageWorkedWith: chr "HTML / CSS; Java; JavaScript; Python" "C ++; HTML / CSS; Python" "HTML / CSS "" C; C ++; C #; Python; SQL "... $ Hobbyist: chr" Ja "" Nej "" Ja "" Nej "... $ LanguageGroup: chr" Python "" Python "" Varken "" Python "...

Jag filtrerade rådata för att göra korstabellerna mer hanterbara, inklusive att ta bort saknade värden och bara ta de två största könen, man och kvinna.

Vaktmästarpaketet

Så, vad är könsfördelningen inom varje språkgrupp? För denna typ av rapportering i en dataram är ett av mina gå-till-verktyg portvaktens tabyl()funktion. 

Grundfunktionen tabyl()returnerar en dataram med räkningar. Det första kolumnnamnet du lägger till i ett tabyl()argument blir raden och det andra kolumnen

bibliotek (vaktmästare) tabyl (mydata, Gender, LanguageGroup)

Kön Båda varken Python R Man 3264 43908 29044 969 Kvinna 374 3705 1940 175

Vad som är trevligt med tabyl()är att det också är mycket lätt att generera procent. Om du vill se procent för varje kolumn istället för råa summor, lägg till adorn_percentages("col"). Du kan sedan leda dessa resultat till en formateringsfunktion som  adorn_pct_formatting().

tabyl (mydata, Gender, LanguageGroup)%>%

adorn_percentages ("col")%>%

adorn_pct_formatting (siffror = 1)

Kön Båda varken Python R Man 89,7% 92,2% 93,7% 84,7% Kvinna 10,3% 7,8% 6,3% 15,3%

Lägg till om du vill se procent efter rad adorn_percentages("row")

Om du vill lägga till en tredje variabel, till exempel Hobbyist, är det också enkelt.

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

adorn_percentages ("col")%>%

adorn_pct_formatting (siffror = 1)

Det blir dock lite svårare att visuellt jämföra resultat på mer än två nivåer på detta sätt. Den här koden returnerar en lista med en dataram för varje tredje nivå val:

$ Nej Kön Båda varken Python R Man 79,6% 86,7% 86,4% 74,6% Kvinna 20,4% 13,3% 13,6% 25,4% $ Ja Kön Båda varken Python R Man 91,6% 93,9% 95,0% 88,0% Kvinna 8,4% 6,1% 5,0% 12,0%

CGPfunktionspaketet

CGPfunctions-paketet är värt att titta på några snabba och enkla sätt att visualisera korsstabsdata. Installera den från CRAN med det vanliga install.packages("CGPfunctions").

Paketet har två funktioner av intresse för granskning av korstabeller: PlotXTabs()och PlotXTabs2(). Den här koden returnerar stapeldiagram över data (första grafen nedan):

bibliotek (CGPfunktioner)

PlotXTabs (mydata)

Skärmdump av Sharon Machlis,

PlotXTabs2(mydata) skapar en graf med ett annat utseende och några statistiska sammanfattningar (andra grafen till vänster).

Om du inte behöver eller vill ha dessa sammanfattningar kan du ta bort dem med results.subtitle = FALSE, till exempel  PlotXTabs2(mydata, LanguageGroup, Gender, results.subtitle = FALSE).

Skärmdump av Sharon Machlis,

PlotXTabs2()har ett par dussin argumentalternativ, inklusive titel, bildtext, förklaringar, färgschema och en av fyra plottyper: sida, stack, mosaik eller procent. Det finns också alternativ som ggplot2-användare känner till, till exempel ggtheme och palett. Du kan se mer information i funktionens hjälpfil.

Vtree-paketet

Paketet vtree genererar grafik för korstabeller i motsats till grafer. Kör vtree()huvudfunktionen på en variabel, t.ex. 

bibliotek (vtree)

vtree (mydata, "LanguageGroup")

ger dig detta grundläggande svar:

Sharon Machlis,

Jag är inte intresserad av färginställningarna här, men du kan byta i en RColorBrewer-palett. vtree palett argument använder palettnummer , inte namn, du kan se hur de är numrerade i paketdokumentationen för vtree. Jag kunde till exempel välja 3 för gröna och 5 för purpur. Tyvärr ger dessa standardvärden dig en mer intensiv färg för lägre antal, vilket inte alltid är meningsfullt (och inte fungerar bra för mig i det här exemplet). Jag kan ändra det standardbeteendet med sortfill = TRUEatt använda den mer intensiva färgen för det högre värdet. 

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

Sharon Machlis,

Om du tycker att den mörka färgen gör det svårt att läsa text finns det några alternativ. Ett alternativ är att använda det vanliga argumentet, till exempel  vtree(mydata, "LanguageGroup", plain = TRUE). Ett annat alternativ är att sätta en enda fyllningsfärg i stället för en palett med hjälp av fillcolorargument, till exempel  vtree(mydata, LanguageGroup", fillcolor = "#99d8c9").

För att titta på två variabler i en korstabellrapport, lägg bara till ett andra kolumnnamn och palett eller färg om du inte vill ha standard. Du kan använda det vanliga alternativet eller ange två paletter eller två färger. Nedan valde jag specifika färger istället för paletter, och jag roterade också grafen för att läsa vertikalt.

vtree (mydata, c ("LanguageGroup", "Kön"),

fillcolor = c (LanguageGroup = "# e7d4e8", Kön = "# 99d8c9"),

horizon = 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)

Med att trädet blir så upptaget tror jag att det hjälper att ha antingen räkningen eller procenten som nodetiketter, inte båda. Så det sista argumentet i koden ovan  showcount = FALSE,, ställer in grafen så att den bara visar procent och inte räknas.

Sharon Machlis,

Mer räknas efter gruppalternativ

Det finns andra användbara sätt att gruppera och räkna i R, inklusive bas R, dplyr och data.table. Base R har  xtabs()funktionen specifikt för denna uppgift. Observera formelsyntaxen nedan: en tilde och sedan en variabel plus en annan variabel.

xtabs (~ LanguageGroup + Kön, data = mindata)

Könspråk Grupp Man Kvinna Båda 3264374 Varken 43908 3705 Python 29044 1940 R 969 175

dplyrs count()funktion kombinerar "gruppera efter" och "räkna rader i varje grupp" till en enda funktion.

bibliotek (dplyr)

min_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

Som med de flesta data är ggplot2 ett bra val för att visualisera sammanfattade resultat. Den första ggplotdiagrammet nedan plottar LanguageGroup på X-axeln och antalet för varje på Y-axeln. Fyllfärg representerar om någon säger att de kodar som en hobby. Och facet_wrap säger: Skapa ett separat diagram för varje värde i kolumnen Kön.

bibliotek (ggplot2)

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

geom_bar (stat = "identitet") +

facet_wrap (facetter = vars (Kön))

Sharon Machlis,

Eftersom det finns relativt få kvinnor i urvalet är det svårt att jämföra procentsatser mellan kön när båda graferna använder samma Y-axel skala. Jag kan dock ändra det så att varje graf använder en separat skala genom att lägga till argumentet scales = “free_y”till facet_wrap()funktionen:

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

geom_bar (stat = "identitet") +

facet_wrap (facetter = vars (Kön), skalor = "fri_y")

Nu är det lättare att jämföra flera variabler efter kön.

För fler R-tips, gå till sidan "Gör mer med R" på eller kolla in YouTube-spellistan "Gör mer med R".

Se nästa sida för information om hur man laddar ner och vred data som används i denna demo.