我有一个类似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中执行此操作,但是我尝试对其进行更改的尝试会出现错误。
您可以说我是一个绝对的初学者,感谢您能给我的任何帮助。
答案 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)