如何计算是/否答复并将其分组?

时间:2018-12-01 17:57:39

标签: r

我有一个类似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软件包,但是它对我不起作用,不知道为什么。 我尝试使用一些CASE函数通过sqldf在Rstudio中执行此操作,但是我尝试对其进行更改的尝试会出现错误。

您可以说我是一个绝对的初学者,感谢您能给我的任何帮助。

3 个答案:

答案 0 :(得分:2)

我们可以使用tidyverse来做到这一点,方法是将gather转换为'long'格式,将'count'的频率获取,并将spread转换为'wide'格式

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])))

答案 1 :(得分:2)

在重新格式化数据之后,这里是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)

答案 2 :(得分:2)

以下是解决问题中尝试的三种方法(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")

,或者如果您有两个以上的问题,则动态创建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)汇总。要进行汇总,请尝试以下操作。聚合语句创建一个两列数据框,其第二列是多列矩阵,最后一条语句(可选)将其转换为普通的三列数据框。如果有两个以上的问题,这也适用。

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'))

或者如果有两个以上的问题:

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

或交替使用(2)中的yesNo

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)