2

我目前正在处理一个包含大约 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)

非常感谢!!

4

2 回答 2

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
于 2013-08-28T14:53:09.717 回答
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))
于 2013-08-28T16:55:34.517 回答