Wie man nach Gruppen in R zählt

Das Zählen nach mehreren Gruppen - manchmal auch als Kreuztabellenberichte bezeichnet - kann eine nützliche Methode sein, um Daten zu betrachten, die von Meinungsumfragen bis zu medizinischen Tests reichen. Wie haben die Menschen zum Beispiel nach Geschlecht und Altersgruppe abgestimmt? Wie viele Softwareentwickler, die sowohl R als auch Python verwenden, sind Männer gegen Frauen?

Es gibt viele Möglichkeiten, diese Art des Zählens nach Kategorien in R durchzuführen. Hier möchte ich einige meiner Favoriten teilen.

Für die Demos in diesem Artikel verwende ich eine Teilmenge der Umfrage zu Stapelüberlaufentwicklern, in der Entwickler zu Dutzenden von Themen befragt werden, die von Gehältern bis zu verwendeten Technologien reichen. Ich werde es mit Spalten für verwendete Sprachen, Geschlecht und ob sie als Hobby codieren, zusammenfassen. Ich habe auch meine eigene LanguageGroup-Spalte hinzugefügt, um festzustellen, ob ein Entwickler R, Python, beide oder keine verwendet hat.

Wenn Sie mitmachen möchten, finden Sie auf der letzten Seite dieses Artikels Anweisungen zum Herunterladen und Verwirren der Daten, um denselben Datensatz zu erhalten, den ich verwende.

Die Daten haben eine Zeile für jede Umfrageantwort, und die vier Spalten sind alle Zeichen.

str (mydata) 'data.frame': 83379 obs. von 4 Variablen: $ Geschlecht: chr "Mann" "Mann" "Mann" "Mann" ... $ LanguageWorkedWith: chr "HTML / CSS; Java; JavaScript; Python" "C ++; HTML / CSS; Python" "HTML / CSS "" C; C ++; C #; Python; SQL "... $ Hobbyist: chr" Ja "" Nein "" Ja "" Nein "... $ Sprachgruppe: chr" Python "" Python "" Weder "" Python "...

Ich habe die Rohdaten gefiltert, um die Kreuztabellen übersichtlicher zu gestalten, einschließlich des Entfernens fehlender Werte und der Verwendung der beiden größten Geschlechter, Mann und Frau.

Das Hausmeisterpaket

Wie ist die Aufteilung der Geschlechter in jeder Sprachgruppe? Für diese Art der Berichterstellung in einem Datenrahmen ist die tabyl()Funktion des Hausmeisterpakets eines meiner bevorzugten Tools . 

Die Grundfunktion tabyl()gibt einen Datenrahmen mit Zählwerten zurück. Der erste Spaltenname, den Sie einem tabyl()Argument hinzufügen, wird zur Zeile und der zweite zur Spalte

Bibliothek (Hausmeister) Tabyl (MyDaten, Geschlecht, Sprachgruppe)

Geschlecht beide weder Python R Mann 3264 43908 29044 969 Frau 374 3705 1940 175

Das Schöne daran tabyl()ist, dass es auch sehr einfach ist, Prozente zu generieren. Wenn Sie Prozente für jede Spalte anstelle von Rohsummen anzeigen möchten, fügen Sie hinzu adorn_percentages("col"). Sie können diese Ergebnisse dann in eine Formatierungsfunktion wie z  adorn_pct_formatting().

tabyl (mydata, Gender, LanguageGroup)%>%

adorn_percentages ("col")%>%

adorn_pct_formatting (Ziffern = 1)

Geschlecht beide weder Python R Mann 89,7% 92,2% 93,7% 84,7% Frau 10,3% 7,8% 6,3% 15,3%

Fügen Sie hinzu, um Prozente nach Zeilen anzuzeigen adorn_percentages("row")

Wenn Sie eine dritte Variable wie Hobbyist hinzufügen möchten, ist dies ebenfalls einfach.

tabyl (mydata, Geschlecht, Sprachgruppe, Bastler)%>%

adorn_percentages ("col")%>%

adorn_pct_formatting (Ziffern = 1)

Auf diese Weise wird es jedoch etwas schwieriger, die Ergebnisse in mehr als zwei Ebenen visuell zu vergleichen. Dieser Code gibt eine Liste mit einem Datenrahmen für jede Auswahl der dritten Ebene zurück:

$ Nein Geschlecht beide weder Python R Mann 79,6% 86,7% 86,4% 74,6% Frau 20,4% 13,3% 13,6% 25,4% $ Ja Geschlecht beide weder Python R Mann 91,6% 93,9% 95,0% 88,0% Frau 8,4% 6,1% 5,0% 12,0%

Das CGPfunctions-Paket

Das CGPfunctions-Paket ist einen Blick wert, um schnell und einfach Kreuztabellendaten zu visualisieren. Installieren Sie es von CRAN mit dem üblichen install.packages("CGPfunctions").

Das Paket verfügt über zwei interessante Funktionen zum Untersuchen von Kreuztabellen: PlotXTabs()und PlotXTabs2(). Dieser Code gibt Balkendiagramme der Daten zurück (erstes Diagramm unten):

Bibliothek (CGP-Funktionen)

PlotXTabs (mydata)

Screenshot von Sharon Machlis,

PlotXTabs2(mydata) Erstellt ein Diagramm mit einem anderen Aussehen und einige statistische Zusammenfassungen (zweites Diagramm links).

Wenn Sie diese Zusammenfassungen nicht benötigen oder möchten, können Sie sie mit entfernen results.subtitle = FALSE, z  PlotXTabs2(mydata, LanguageGroup, Gender, results.subtitle = FALSE).

Screenshot von Sharon Machlis,

PlotXTabs2()Es gibt ein paar Dutzend Argumentoptionen, darunter Titel, Beschriftung, Legenden, Farbschema und einen von vier Diagrammtypen: Seite, Stapel, Mosaik oder Prozent. Es gibt auch Optionen, die ggplot2-Benutzern bekannt sind, wie z. B. ggtheme und palette. Weitere Details finden Sie in der Hilfedatei der Funktion.

Das vtree-Paket

Das vtree-Paket generiert Grafiken für Kreuztabellen im Gegensatz zu Grafiken. Ausführen der vtree()Hauptfunktion für eine Variable, z 

Bibliothek (vtree)

vtree (mydata, "LanguageGroup")

Sie erhalten diese grundlegende Antwort:

Sharon Machlis,

Ich bin nicht begeistert von den Farbstandards hier, aber Sie können eine RColorBrewer-Palette austauschen. vtree Palette Argument verwendet Palette Nummern , keine Namen; Wie sie nummeriert sind, können Sie der Dokumentation zum vtree-Paket entnehmen. Ich könnte zum Beispiel 3 für Grüne und 5 für Purpur wählen. Leider geben Ihnen diese Standardeinstellungen eine intensivere Farbe für Zahlen mit niedrigerer Anzahl, was nicht immer sinnvoll ist (und in diesem Beispiel für mich nicht gut funktioniert). Ich kann dieses Standardverhalten ändern, sortfill = TRUEum die intensivere Farbe für den höheren Wert zu verwenden. 

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

Sharon Machlis,

Wenn Sie feststellen, dass die dunkle Farbe das Lesen von Text erschwert, gibt es einige Optionen. Eine Möglichkeit besteht darin, das einfache Argument zu verwenden, z  vtree(mydata, "LanguageGroup", plain = TRUE). Eine andere Möglichkeit besteht darin, eine einzelne Füllfarbe anstelle einer Palette mithilfe des fillcolorArguments festzulegen, z  vtree(mydata, LanguageGroup", fillcolor = "#99d8c9").

Um zwei Variablen in einem Kreuztabellenbericht anzuzeigen, fügen Sie einfach einen zweiten Spaltennamen und eine Palette oder Farbe hinzu, wenn Sie die Standardeinstellung nicht möchten. Sie können die Option Plain verwenden oder zwei Paletten oder zwei Farben angeben. Unten habe ich bestimmte Farben anstelle von Paletten ausgewählt und das Diagramm gedreht, um es vertikal zu lesen.

vtree (mydata, c ("Sprachgruppe", "Geschlecht"),

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

Horizont = FALSCH)

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)

Da der Baum so beschäftigt ist, denke ich, dass es hilfreich ist, entweder die Anzahl oder den Prozentsatz als Knotenbezeichnungen zu haben, nicht beide. Mit diesem letzten Argument im obigen Code wird  showcount = FALSEdas Diagramm so eingestellt, dass nur Prozent und keine Zählwerte angezeigt werden.

Sharon Machlis,

Mehr Anzahl nach Gruppenoptionen

Es gibt andere nützliche Möglichkeiten zum Gruppieren und Zählen in R, einschließlich Basis R, dplyr und data.table. Base R hat die  xtabs()Funktion speziell für diese Aufgabe. Beachten Sie die folgende Formelsyntax: eine Tilde und dann eine Variable plus eine weitere Variable.

xtabs (~ Sprachgruppe + Geschlecht, Daten = mydata)

Geschlecht SpracheGruppe Mann Frau Beide 3264 374 Weder 43908 3705 Python 29044 1940 R 969 175

Die count()Funktion von dplyr kombiniert "Gruppieren nach" und "Zeilen in jeder Gruppe zählen" zu einer einzigen Funktion.

Bibliothek (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

Wie bei den meisten Daten ist ggplot2 eine gute Wahl, um zusammengefasste Ergebnisse zu visualisieren. Das erste ggplot-Diagramm unten zeigt die Sprachgruppe auf der X-Achse und die Anzahl für jede auf der Y-Achse. Die Füllfarbe gibt an, ob jemand sagt, dass er als Hobby codiert. Und facet_wrap sagt: Erstellen Sie für jeden Wert in der Spalte Geschlecht ein separates Diagramm.

Bibliothek (ggplot2)

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

geom_bar (stat = "identity") +

facet_wrap (facets = vars (Geschlecht))

Sharon Machlis,

Da die Stichprobe relativ wenige Frauen enthält, ist es schwierig, Prozentsätze zwischen den Geschlechtern zu vergleichen, wenn beide Diagramme dieselbe Y-Achsen-Skala verwenden. Ich kann das jedoch ändern, sodass jedes Diagramm eine separate Skala verwendet, indem ich scales = “free_y”der facet_wrap()Funktion das Argument hinzufüge :

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

geom_bar (stat = "identity") +

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

Jetzt ist es einfacher, mehrere Variablen nach Geschlecht zu vergleichen.

Weitere R-Tipps finden Sie auf der YouTube-Wiedergabeliste „Do More With R“ auf der Seite „Do More With R“.

Auf der nächsten Seite finden Sie Informationen zum Herunterladen und Verwirren von Daten, die in dieser Demo verwendet werden.