2012-06-11 49 views
4

我正試圖在給定列上使用max函數來減少數據幀。我想保留其他列,但保留來自選擇每個最大值的相同行的值。一個例子會使這個解釋更容易。如何減少保留其他列的訂單的數據幀

讓我們假設我們有以下的數據幀:

dframe <- data.frame(list(BENCH=sort(rep(letters[1:4], 4)), 
          CFG=rep(1:4, 4), 
          VALUE=runif(4 * 4) 
         )) 

這給了我:

 
    BENCH CFG  VALUE 
1  a 1 0.98828096 
2  a 2 0.19630597 
3  a 3 0.83539540 
4  a 4 0.90988296 
5  b 1 0.01191147 
6  b 2 0.35164194 
7  b 3 0.55094787 
8  b 4 0.20744004 
9  c 1 0.49864470 
10  c 2 0.77845408 
11  c 3 0.25278871 
12  c 4 0.23440847 
13  d 1 0.29795494 
14  d 2 0.91766057 
15  d 3 0.68044728 
16  d 4 0.18448748 

現在,我想降低成本,以選取不同的最大值的數據BENCH:

aggregate(VALUE ~ BENCH, dframe, FUN=max) 

這給了我預期的結果:

 
    BENCH  VALUE 
1  a 0.9882810 
2  b 0.5509479 
3  c 0.7784541 
4  d 0.9176606 

接着,我試圖保持其他列:

aggregate(cbind(VALUE, CFG) ~ BENCH, dframe, FUN=max) 

這種減少返回:

 
    BENCH  VALUE CFG 
1  a 0.9882810 4 
2  b 0.5509479 4 
3  c 0.7784541 4 
4  d 0.9176606 4 

價值和CFG使用max功能降低。但這不是我想要的。例如,在這個例子中,我想獲得:

 
    BENCH  VALUE CFG 
1  a 0.9882810 1 
2  b 0.5509479 3 
3  c 0.7784541 2 
4  d 0.9176606 2 

其中CFG沒有減少,但它只是讓關聯到每個不同的BENCH最大值的值。

我怎樣才能改變我的減少,以獲得最後的結果?

回答

2

這裏有一個基礎R解決方案:

do.call(rbind, by(dframe, dframe$BENCH, FUN=function(X) X[which.max(X$VALUE),])) 
# BENCH CFG  VALUE 
# a  a 1 0.9882810 
# b  b 3 0.5509479 
# c  c 2 0.7784541 
# d  d 2 0.9176606 
+1

如果'by()'有一個類似「簡化」的參數來完成split-apply-combine算法,並將結果數據幀放回到一起,那肯定會很好。它非常接近...然後讓你用這個尷尬的'do.call(rbind,...)'結構做最後一步。 –

+0

+1來解決這個問題。謝謝!其實,在我看來,這看起來並不糟糕:) – betabandido

1

你可以使用ddplyplyr包:

ddply(dframe, 
     .(BENCH), 
     function(df) return(df[df$VALUE==max(df$VALUE),])) 
+0

+1解決問題。謝謝!只是一件小事,最後還有一個缺失的括號。 – betabandido

5

如果您的問題擴展到數百萬行和羣體的大數據(單位:百萬或者10秒),那麼包data.table可能是感興趣的。以下是相關的語法:

require(data.table) 
dtable <- data.table(dframe) 
dtable[, .SD[which.max(VALUE),], by = BENCH]