Вот решения, исправляющие три подхода (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)