Как да броим по групи в R

Преброяването от множество групи - понякога наричани отчети за кръстосани таблици - може да бъде полезен начин за разглеждане на данни, вариращи от проучвания на общественото мнение до медицински тестове. Например как хората гласуваха по пол и възрастова група? Колко разработчици на софтуер, които използват и R, и Python, са мъже срещу жени?

Има много начини да се направи този вид преброяване по категории в R. Тук бих искал да споделя някои от любимите ми.

За демонстрациите в тази статия ще използвам подмножество от проучването Stack Overflow Developers, което изследва разработчиците по десетки теми, вариращи от заплати до използвани технологии. Ще го разбия с колони за използваните езици, пол и ако те кодират като хоби. Също така добавих собствената си колона LanguageGroup за това дали разработчик съобщава, че използва R, Python, и двете, или нито един от двамата.

Ако искате да продължите, последната страница на тази статия съдържа инструкции как да изтеглите и преборите данните, за да получите същия набор от данни, който използвам.

Данните имат един ред за всеки отговор на анкетата и четирите колони са всички знаци.

str (mydata) 'data.frame': 83379 obs. от 4 променливи: $ Пол: chr "Man" "Man" "Man" "Man" ... $ LanguageWorkedWith: chr "HTML / CSS; Java; JavaScript; Python" "C ++; HTML / CSS; Python" "HTML / CSS "" C; C ++; C #; Python; SQL "... $ Хобист: chr" Да "" Не "" Да "" Не "... $ LanguageGroup: chr" Python "" Python "" Нито "" Python "...

Филтрирах суровите данни, за да направя кръстосаните таблици по-управляеми, включително премахване на липсващи стойности и вземане само на двата най-големи пола, Мъж и Жена.

Пакетът на чистача

И така, каква е разбивката по пол във всяка езикова група? За този тип отчитане в рамка с данни един от инструментите ми за преминаване е функцията на портиера tabyl()

Основната tabyl()функция връща рамка с данни с броя. Името на първата колона, която добавяте към tabyl()аргумент, се превръща в реда , а втората колона

библиотека (портиер) tabyl (mydata, Gender, LanguageGroup)

Пол и двамата, нито Python R Man 3264 43908 29044 969 Жена 374 3705 1940 175

Хубавото tabyl()е, че е много лесно да се генерират и проценти. Ако искате да видите проценти за всяка колона вместо необработени суми, добавете adorn_percentages("col"). След това можете да прехвърлите тези резултати във функция за форматиране като  adorn_pct_formatting().

tabyl (mydata, Gender, LanguageGroup)%>%

adorn_percentages ("col")%>%

adorn_pct_formatting (цифри = 1)

Пол И Нито Python R Мъж 89,7% 92,2% 93,7% 84,7% Жена 10,3% 7,8% 6,3% 15,3%

За да видите проценти по ред, добавете adorn_percentages("row")

Ако искате да добавите трета променлива, като Hobbyist, това също е лесно.

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

adorn_percentages ("col")%>%

adorn_pct_formatting (цифри = 1)

Обаче става малко по-трудно визуално да се сравняват резултатите в повече от две нива по този начин. Този код връща списък с един кадър от данни за всеки избор от трето ниво:

$ Без пол И двете Нито Python R Man 79.6% 86.7% 86.4% 74.6% Жена 20.4% 13.3% 13.6% 25.4% $ Да Пол И Нито Python R Man 91.6% 93.9% 95.0% 88.0% Жена 8.4% 6.1% 5.0% 12.0%

Пакетът CGPfunctions

Пакетът CGPfunctions си струва да разгледате някои бързи и лесни начини за визуализиране на данни от кръстосани таблици. Инсталирайте го от CRAN с обичайното install.packages("CGPfunctions").

Пакетът има две интересни функции за изследване на кръстосани таблици: PlotXTabs()и PlotXTabs2(). Този код връща стълбовидни графики на данните (първата графика по-долу):

библиотека (CGPфункции)

PlotXTabs (mydata)

Снимка на екрана от Шарън Маклис,

PlotXTabs2(mydata) създава графика с различен вид и някои статистически обобщения (втора графика вляво).

Ако не се нуждаете или искате тези обобщения, можете да ги премахнете с results.subtitle = FALSE, като  PlotXTabs2(mydata, LanguageGroup, Gender, results.subtitle = FALSE).

Снимка на екрана от Шарън Маклис,

PlotXTabs2()има няколко дузини опции за аргументи, включително заглавие, надпис, легенди, цветова схема и един от четирите типа сюжети: страна, стек, мозайка или процент. Има и опции, познати на потребителите на ggplot2, като ggtheme и палитра. Можете да видите повече подробности в помощния файл на функцията.

Пакетът vtree

Пакетът vtree генерира графики за кръстосани таблици, за разлика от графиките. Стартиране на основната vtree()функция на една променлива, като 

библиотека (vtree)

vtree (mydata, "LanguageGroup")

ви дава този основен отговор:

Шарън Маклис,

Тук не съм запален по подразбиране на цветовете, но можете да сменяте в палитра RColorBrewer. Аргументът на палитрата на vtree използва номера на палитри , а не имена; можете да видите как са номерирани в документацията за пакета vtree. Можех да избера 3 за Зелените и 5 за Лилавите, например. За съжаление, тези настройки по подразбиране ви дават по-интензивен цвят за по-ниски числа, което не винаги има смисъл (и не работи добре за мен в този пример). Мога да променя това поведение по подразбиране, за sortfill = TRUEда използвам по-интензивния цвят за по- висока стойност. 

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

Шарън Маклис,

Ако откриете, че тъмният цвят затруднява четенето на текст, има някои опции. Единият вариант е да се използва обикновеният аргумент, като например  vtree(mydata, "LanguageGroup", plain = TRUE). Друга възможност е да зададете един цвят на запълване вместо палитра, като използвате fillcolorаргумента, като например  vtree(mydata, LanguageGroup", fillcolor = "#99d8c9").

За да разгледате две променливи в отчета за кръстосани таблици, просто добавете име на втора колона и палитра или цвят, ако не искате по подразбиране. Можете да използвате обикновената опция или да посочите две палитри или два цвята. По-долу избрах специфични цветове вместо палитри и също завъртях графиката, за да чета вертикално.

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

fillcolor = c (LanguageGroup = "# e7d4e8", Пол = "# 99d8c9"),

horiz = FALSE)

Шарън Маклис,

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)

С дървото получават толкова зает, мисля, че е хубаво да имате или броя или процента като възел етикети, не и двете. Така че последният аргумент в горния код  showcount = FALSE, задава графиката да показва само проценти, а не отчита.

Шарън Маклис,

Още преброяване по групови опции

Има и други полезни начини за групиране и броене в R, включително база R, dplyr и data.table. Base R има  xtabs()функцията специално за тази задача. Обърнете внимание на синтаксиса на формулата по-долу: тилда и след това една променлива плюс друга променлива.

xtabs (~ LanguageGroup + Gender, data = mydata)

Пол Език Група Мъж Жена И двамата 3264 374 Нито 43908 3705 Python 29044 1940 R 969 175

Функцията на dplyr count()комбинира „групиране по“ и „преброяване на редове във всяка група“ в една функция.

библиотека (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

Както при повечето данни, ggplot2 е добър избор за визуализиране на обобщени резултати. Първата графика на ggplot отдолу начертава LanguageGroup по оста X и броя за всеки по оста Y. Цвят на запълване представлява дали някой казва, че кодира като хоби. И, facet_wrap казва: Направете отделна графика за всяка стойност в колоната Пол.

библиотека (ggplot2)

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

geom_bar (stat = "идентичност") +

facet_wrap (фасети = vars (Пол))

Шарън Маклис,

Тъй като в извадката има сравнително малко жени, е трудно да се сравнят процентите между половете, когато и двете графики използват една и съща скала на оста Y. Мога обаче да променя това, така че всяка графика използва отделен мащаб, като добавя аргумента scales = “free_y”към facet_wrap()функцията:

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

geom_bar (stat = "идентичност") +

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

Сега е по-лесно да сравнявате множество променливи по пол.

За повече съвети за R отидете на страницата „Направете повече с R“ на или разгледайте плейлиста „Направете повече с R“ в YouTube.

Вижте следващата страница за информация за това как да изтеглите и разправяте данни, използвани в тази демонстрация.