分体式样设计

时间:2013-08-28 14:37:30

标签: r data-manipulation

我目前正在处理一个包含大约9,000个属于不同组的观察的大型数据集。现在,我想使用一种称为分割样本设计的方法来分析这些数据。让我详细解释一下我想做什么。我的数据具有以下结构:

GroupID  Performance   Commitment   Affect   Size
1234     5             4            2        2
1234     6             8            9        2
2235     4             3            2        5
2235     4             3            2        5
2235     2             1            7        5
2235     2             1            7        5
2235     2             6            10       5
3678     3             5            5        4
3678     7             3            5        4
3678     5             2            6        4
3678     1             4            6        4

现在,我想以下列方式汇总这些数据:对于每个组,我想使用组的前半部分的平均绩效分数和平均承诺并影响下半年的分数。组创建一个新的观察组(对于不均匀的组大小,我想在组内放下一个随机观察 - 例如组中的最后一次观察 - 以创建偶数组大小)。但是,我想分两步完成。首先,数据应如下所示:

GroupID  Performance   Commitment   Affect   Size
1234     5             8            9        2
2235     4             1            7        5
2235     4             1            7        5
3678     3             2            6        4
3678     7             4            6        4

在下一步中,我想汇总数据。新数据集每组有一个观察结果,如下所示:

GroupID  Performance   Commitment   Affect   Size
1234     5             8            9        2
2235     4             1            7        5
3678     5             3            6        4

请再次注意,第2235组的最后一次观察被删除,因为该组的数量不均匀。

是否有任何包以这种方式拆分和汇总我的数据?如果没有,您将如何进行编码?我会非常感谢任何建议,因为我目前不知道如何优雅地处理这个问题,除了写一堆for循环。

以下是上述示例的代码:

groupid <- c(1234, 1234, 2235, 2235, 2235, 2235, 2235, 3678, 3678, 3678, 3678)
performance <- c(5, 6, 4, 4, 2, 2, 2, 3, 7, 5, 1)
commitment <- c(4, 8, 3, 3, 1, 1, 6, 5, 3, 2, 4)
affect <- c(2, 9, 2, 2, 7, 7, 10, 5, 5, 6, 6)
size <- c(2, 2, 5, 5, 5, 5, 5, 4, 4, 4, 4)
mydata <- data.frame(groupid, performance, commitment, affect, size)

非常感谢!!

2 个答案:

答案 0 :(得分:2)

以下是解决方案:

library(plyr)
mydata1<-ddply(mydata,.(GroupID),summarize,aveper=mean(head((Performance),length(GroupID)/2)),
avecom=mean(tail((Commitment),length(GroupID)/2)),
aveaff=mean(tail((Affect),length(GroupID)/2)),avesiz=mean(Size))

> mydata1
  GroupID aveper avecom aveaff avesiz
1    1234      5  8.000      9      2
2    2235      4  2.667      8      5
3    3678      5  3.000      6      4

更新:

    mydata2<-ddply(mydata,.(GroupID),transform,aveper=mean(head((Performance),length(GroupID)/2)),
avecom=mean(tail((Commitment),length(GroupID)/2)),
aveaff=mean(tail((Affect),length(GroupID)/2)),avesiz=mean(Size),lengr=length(GroupID))

    > mydata2
   GroupID Performance Commitment Affect Size aveper avecom aveaff avesiz lengr
1     1234           5          4      2    2      5  8.000      9      2     2
2     1234           6          8      9    2      5  8.000      9      2     2
3     2235           4          3      2    5      4  2.667      8      5     5
4     2235           4          3      2    5      4  2.667      8      5     5
5     2235           2          1      7    5      4  2.667      8      5     5
6     2235           2          1      7    5      4  2.667      8      5     5
8     3678           3          5      5    4      5  3.000      6      4     4
9     3678           7          3      5    4      5  3.000      6      4     4
10    3678           5          2      6    4      5  3.000      6      4     4
11    3678           1          4      6    4      5  3.000      6      4     4

mydata2<-mydata2[-7,] # this assumes that you have already taken care of uneven groups
mydata3<-Map(function(x)head(mydata2[mydata2$GroupID==x,],head(mydata2$lengr[which(mydata2$GroupID==x)],1)/2),unique(mydata2$GroupID))

library(plyr)
mydata4<-ldply(mydata3)

mydata5<-mydata4[,c(1,6:9)]
> mydata5
  GroupID aveper avecom aveaff avesiz
1    1234      5  8.000      9      2
2    2235      4  2.667      8      5
3    2235      4  2.667      8      5
4    3678      5  3.000      6      4
5    3678      5  3.000      6      4

答案 1 :(得分:1)

我现在用以下方式编码(相当强力)。如果你知道更好的方法来完成这个诀窍,请告诉我。最后,我使用了Metrics提供的代码来汇总我的数据(再次感谢!):

ids <- unique(groupid)
pos <- 1
for (i in 1:length(ids)) {
    total <- mydata[pos,5]
    num <- floor(total/2)

    for (m in pos:(pos+num-1)) {
        mydata[m,-c(1,2)] <- mydata[m+num,-c(1,2)]
    }

    for (l in (pos+num):(pos+total-1)) {
        mydata[l,] <- NA
        print(l)
    }

    pos <- pos+total

}

mydata <- mydata[!is.na(mydata$groupid),]

mydata2<-ddply(mydata,.(groupid),summarize,aveper=mean(performance),avecomm=mean(commitment), aveaff=mean(affect), avesiz=mean(size))