2013-08-28 47 views
2

我目前正在研究一個大型數據集,其中包含大約9000個屬於不同組的觀察值。現在,我想使用一種名爲拆分樣本設計的方法來分析這些數據。讓我詳細解釋我想做什麼。我的數據結構如下:拆分樣本設計

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) 

非常感謝!!

+0

您是否嘗試過使用任何軟件? ''aggregate' – dayne

+0

我會開始在Matlab中使用很多'for'循環編寫代碼,但是,我認爲肯定有一個更簡單的方法來在R中完成它。我還沒有使用聚合函數,但會看起來進去。謝謝! – rp1

+0

我會先分割數據,然後在兩個子集上使用'aggregate',然後將它們放回到一起。 – dayne

回答

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)) 
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 
+0

完美,非常感謝!這幾乎就是我所需要的(我總是可以找出一種方法來放棄最後觀察到的數字不均勻的組)。但是,是否有辦法通過上述兩個步驟真正做到這一點?我需要在第一步之後和聚合之前對數據樣本進行一些測試。再次感謝! – rp1

+0

是的,我認爲它是可能的。而不是總結,使用'transform',它會返回到您的原始數據框與這些額外的列。然後你可以繼續工作。 – Metrics

+0

有沒有什麼辦法可以在第一步之後將數據集轉換成上面描述的確切格式 - 也就是說,對於組「2235」,在性能列中使用「4」進行兩次觀察,在執行列表中使用「1」,「7」和「5」承諾,影響和大小列分別? – rp1