2017-09-05 30 views
0

我有如下所示的用例。基本上我有一個三列數據框。我想分兩列(c1,c2)和總結第三個c3。然後,我只想挑選頂部1 c1最多c3(在所有c2之間),即排序將是不必要的,因爲我只對最大值感興趣。如何獲得每列有多列的頂層元素?

library(plyr) 

df <- data.frame(c1=c('a','a','a','b','b','c'),c2=c('x','y','y','x','y','x'),c3=c(1,2,3,4,5,6)) 
df 
    c1 c2 c3 
1 a x 1 
2 a y 2 
3 a y 3 
4 b x 4 
5 b y 5 
6 c x 6 

sel <- plyr::ddply(df, c('c1','c2'), plyr::summarize,c3=sum(c3)) 
sel[with(sel, order(c1,-c3)),] 
    c1 c2 c3 
2 a y 5 <<< this one highest c3 for (c1,c2) combination 
1 a x 1 
4 b y 5 <<< this one highest c3 for (c1,c2) combination 
3 b x 4 
5 c x 6 <<< this one highest c3 for (c1,c2) combination 

我可以在循環中做到這一點,但我想知道如何以矢量方式或使用高級功能。

+0

另一種選擇由C1 + C2組總結C3之後,你只有每C1的第1個一行+ C2。 –

+0

事實上,你是對的。我編輯了這個問題。我對'c1'感興趣,在'c2'上最大'c3' –

回答

4

這裏有一個基礎R方法:

df2 <- aggregate(c3~c1+c2, df, sum) 
subset(df2[order(-df2$c3),], !duplicated(c1)) 
# c1 c2 c3 
#3 c x 6 
#4 a y 5 
#5 b y 5 
+0

不錯,我喜歡它,因爲它很簡單,只使用base ...但是,我擔心'!duplicate'位,因爲存在沒有規範合同,它必須選擇第一個找到的......這是一個實施選擇,如果改變,那麼解決方案會打破或? –

+0

@GiovanniAzua,不知道我理解你的問題。此方法通過減少c3-sum來排序,然後每c1選取第一行(=最大c3行)。如果你以後想做點什麼,顯然這種方法也必須改變 –

3

dplyr的另一個解決方案。

library(dplyr) 

df2 <- df %>% 
    group_by(c1, c2) %>% 
    summarise(c3 = sum(c3)) %>% 
    filter(c3 == max(c3)) 

df2 
# A tibble: 3 x 3 
# Groups: c1 [3] 
     c1  c2 c3 
    <fctr> <fctr> <dbl> 
1  a  y  5 
2  b  y  5 
3  c  x  6 
2

使用dplyr

df %>% 
    group_by(c1, c2) %>% 
    summarise(c3 = sum(c3)) %>% 
    top_n(1, c3) 

或最後一行可以slice(which.max(c3)),這將保證一行。

3

這裏是data.table

library(data.table) 
setDT(df)[, .(c3 = sum(c3)) , .(c1, c2)][, .SD[which.max(c3)], .(c1)] 
# c1 c2 c3 
#1: a y 5 
#2: b y 5 
#3: c x 6