0

我的目标是:给定一个二分响应的数据框(例如,0 和 1),我如何生成一个汇总矩阵:1)有两列(一列用于正确回答第一个问题,另一列用于错误回答), 2) 具有与获得特定总分的个人数量有关的行。

例如,假设我有 50 个受访者和 5 个问题。这意味着有 6 种响应模式(全部不正确/0,然后是 1、2、3 和 4 正确,最后全部正确/1)。我希望得到的矩阵对象看起来像:

... INCORRECT ..... CORRECT   <-- pertaining to a 0 or 1 on the first item respectively

[1]... 10 ............ 0      <-- indicating people who, after responded 0 on the first question, responded 0 on all questions (5 zeroes)
[2]... 8  ............ 2      <-- indicating 12 people who got 1 correct (8 got the first question incorrect, 2 got the first question correct)
[3]... 4 ............. 8      <-- indicating 12 people who got 2 correct (4 got the first question incorrect but got 2 of the other questions correct, 8 got the first question and 1 other correct)
[4]... 6 ............. 3      <-- indicating 9 people who got 3 correct
[5]... 3 ............. 4      <-- indicating 7 people who got 4 correct
[6]... 0 ............. 8      <-- pertaining to the 8 people who answered all 5 questions correctly (necessarily indicating they got the first question correct).

我的思路是,我需要按第一个问题的表现(一次工作一列)拆分数据框,并找到每一行(参与者)的总分,然后将它们列在第一列中;然后对第二个做同样的事情?

这将被构建到一个包中,所以我试图弄清楚如何只使用基本函数来做到这一点。

这是一个类似于我将使用的示例数据集:

n <- 50
z <- c(0, 1)
samp.fun <- function(x, n){
    sample(x, n, replace = TRUE)
}

data <- data.frame(0)
for (i in 1:5){
    data[1:n, i] <- samp.fun(z, n)
}
names(data)[1:5] <- c("x1", "x2", "x3", "x4", "x5")

任何想法将不胜感激!

4

3 回答 3

4

使用@alexwhan 的数据,这是一个data.table解决方案:

require(data.table)
dt <- data.table(data)

dt[, list(x1.incorrect=sum(x1==0), x1.correct=sum(x1==1)), keyby=total]
#    total x1.incorrect x1.correct
# 1:     0            2          0
# 2:     1            7          1
# 3:     2            9          8
# 4:     3            7          6
# 5:     4            0          7
# 6:     5            0          3

等效地,如果您不介意稍后设置列名,则可以更直接地获得结果,使用tablewithas.list如下:

dt[, as.list(table(factor(x1, levels=c(0,1)))), keyby=total]
#    total 0 1
# 1:     0 2 0
# 2:     1 7 1
# 3:     2 9 8
# 4:     3 7 6
# 5:     4 0 7
# 6:     5 0 3

as.list(.)注意:你可以用这样的包装setNames()

dt[, setNames(as.list(table(factor(x1, levels=c(0,1)))), 
           c("x1.incorrect", "x1.correct")), keyby = total]

也可以一次性设置列名。

于 2013-03-16T08:26:18.143 回答
3

因为您在创建数据时没有使用set.seed,所以我无法根据您的示例检查此解决方案,但我认为这就是您所追求的。我正在使用函数 fromreshape2plyr来获取数据摘要。

library(reshape2)
library(plyr)
#create data
set.seed(1234)
n <- 50
z <- c(0, 1)
samp.fun <- function(x, n){
  sample(x, n, replace = TRUE)
}

data <- data.frame(0)
for (i in 1:5){
  data[1:n, i] <- samp.fun(z, n)
}
names(data)[1:5] <- c("x1", "x2", "x3", "x4", "x5")
data$id <- 1:50

#First get the long form to make summaries on
data.m <- melt(data, id.vars="id")

#Get summary to find total correct answers
data.sum <- ddply(data.m, .(id), summarise,
                  total = sum(value))

#merge back with original data to associate with id
data <- merge(data, data.sum)
data$total <- factor(data$total)

#summarise again to get difference between patterns
data.sum2 <- ddply(data, .(total), summarise,
               x1.incorrect = length(total) - sum(x1),
               x1.correct = sum(x1))
data.sum2
#   total x1.incorrect x1.correct
# 1     0            2          0
# 2     1            7          1
# 3     2            9          8
# 4     3            7          6
# 5     4            0          7
# 6     5            0          3
于 2013-03-16T04:44:45.750 回答
-1

不错的谜题 - 如果我做对了,这也应该这样做:

table(rowSums(data),data[,1])
于 2013-03-16T19:06:55.903 回答