代码之家  ›  专栏  ›  技术社区  ›  Twitch_City

数据帧的子集和求和

  •  0
  • Twitch_City  · 技术社区  · 13 年前

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

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

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

    任何想法都将不胜感激!

    3 回复  |  直到 13 年前
        1
  •  4
  •   Arun    13 年前

    使用@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
    

    等效地,如果您不介意稍后设置列名,则可以更直接地获得结果,使用 table 具有 as.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]
    

    也可以一次性设置列名。

        2
  •  3
  •   alexwhan    13 年前

    因为你没有使用 set.seed 在创建数据时,我无法将此解决方案与您的示例进行比较,但我认为这正是您想要的。我正在使用来自的函数 reshape2 plyr 以获取数据摘要。

    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
    
        3
  •  -1
  •   texb    13 年前

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

    table(rowSums(data),data[,1])
    
    推荐文章