Как считать Да / Нет ответов и группировать их? - PullRequest
0 голосов
/ 01 декабря 2018

У меня есть опрос из файла Excel, который выглядит следующим образом:

  party          question1         question2
1 Republican       Yes                No
2 Democrat         No                 Yes
3 Libertarian      No                 No
4 Green            No                 Yes
5 Republican       Yes                Yes
6 Constitution     Yes                No
7 Democrat         Yes                Yes
8 Democrat         No                 No

Я хочу, чтобы число «Да» и «Количество раздач по партиям» было примерно таким:

party           Yes   No
Republican       5    4
Democrat         1    3
Libertarian      5    6
Constitution     2    4
Green            4    1

В конце концов я хочу сделать из этого график.Я искал повсюду и пробовал кое-что, самым близким был

res1 <-as.data.frame(aggregate(question1, list(party), table))

, что приводит к этому

             Group.1 x.No x.Yes
1 constitution          2    12
2   democratic         21   267
3        green          4    21
4  libertarian         12    39
5   republican         27   155

, который кажется великолепным, за исключением случаев, когда я View(res1) показывает толькокак "5 obs. of 2 variables".Я вижу только столбец Group1 и столбец x.No.Мне нужны столбцы «Да» и «Нет», чтобы я мог их отобразить.

Я также попробовал пакет plyr, но он не работает для меня, понятия не имею, почему.Я попытался сделать это в Rstudio через sqldf, используя некоторые CASE функции, но, если бы я попытался изменить его, это привело бы к ошибке.

Как вы можете сказать, я абсолютный новичок, я ценю любую помощь вамможете дать мне.

Ответы [ 3 ]

0 голосов
/ 01 декабря 2018

Вот способ с xtabs после переформатирования данных.

long <- reshape2::melt(df1, id.vars = "party")
xtabs( ~ party + value, long)
#              value
#party          No Yes
#  Constitution  1   1
#  Democrat      3   3
#  Green         1   1
#  Libertarian   2   0
#  Republican    1   3

Данные.

df1 <- read.table(text = "
party          question1         question2
1 Republican       Yes                No
2 Democrat         No                 Yes
3 Libertarian      No                 No
4 Green            No                 Yes
5 Republican       Yes                Yes
6 Constitution     Yes                No
7 Democrat         Yes                Yes
8 Democrat         No                 No                  
", header = TRUE)
0 голосов
/ 02 декабря 2018

Вот решения, исправляющие три подхода (sqldf, aggregate, plyr), которые использовались в этом вопросе.Мы предполагаем, что ввод фрейма данных равен DF, как это определено в примечании в конце.

1) sqldf С sqldf:

library(sqldf)

sqldf("select party, 
              sum(question1 = 'No') + sum(question2 = 'No') as No,
              sum(question1 = 'Yes') + sum(question2 = 'Yes') as Yes
       from DF
       group by party")

или еслиу вас есть более 2 вопросов, динамически создавать оператор SQL.Аргумент verbose= покажет оператор, который он фактически отправляет в SQLite, и вы можете его опустить, если вам это не нужно.

library(sqldf)

yes <- paste(sprintf("sum(%s = 'Yes')", names(DF)[-1]), collapse = " + ")
no <- paste(sprintf("sum(%s = 'No')", names(DF)[-1]), collapse = " + ")

fn$sqldf("select party, $no No, $yes Yes from DF group by party", verbose = TRUE)

2) агрегат Чтобы сделать это с агрегатомпопробуйте следующее.Агрегатный оператор создает фрейм данных с двумя столбцами, второй столбец которого является многоколоночной матрицей, а последний необязательный оператор преобразует его в обычный фрейм данных с 3 столбцами.Это также работает, если есть более 2 вопросов.

ag <- aggregate(list(Answer = 1:nrow(DF)), DF["party"], 
  function(i) c(No = sum(DF[i, -1] == 'No'), Yes = sum(DF[i, -1] == 'Yes')))
do.call("data.frame", ag)

или поочередно:

yesNo <- data.frame(Yes = rowSums(DF[-1] == "Yes"), No = rowSums(DF[-1] == "No"))
aggregate(yesNo, DF[1], sum)

3) plyr С пакетом plyr мы можем использовать этот код:

library(plyr)

ddply(DF, .(party), summarize,
   No = sum(question1 == 'No') + sum(question2 == 'No'),
   Yes = sum(question1 == 'Yes') + sum(question2 == 'Yes'))

или если может быть более 2 вопросов:

Count_No <- function(data) sum(data[, -1] == "No")
Count_Yes <- function(data) sum(data[, -1] == "Yes")
ddply(DF, .(party), c(No = Count_No, Yes = Count_Yes))

или поочередно с помощью yesNo из (2):

ddply(yesNo, .(party = DF$party), colSums)

Примечание

Ввод DF в воспроизводимом виде:

Lines <- "
  party          question1         question2
1 Republican       Yes                No
2 Democrat         No                 Yes
3 Libertarian      No                 No
4 Green            No                 Yes
5 Republican       Yes                Yes
6 Constitution     Yes                No
7 Democrat         Yes                Yes
8 Democrat         No                 No"
DF <- read.table(text = Lines)
0 голосов
/ 01 декабря 2018

Мы можем сделать это с tidyverse путем преобразования в «длинный» формат с gather, получить частоту с помощью «счетчика» и spread в «широкий» формат

library(tidyverse)
gather(df1, key, val, question1:question2) %>%
   count(party, val) %>%
   spread(val, n)

Также с использованием base R

table(data.frame(df1[1], value = unlist(df1[-1])))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...