2015-04-08 8 views
5

Ich habe ein data.frame wie diesesR Art zusammenfassen ddply durch Gruppensumme

x <- data.frame(Category=factor(c("One", "One", "Four", "Two","Two", 
"Three", "Two", "Four","Three")), 
City=factor(c("D","A","B","B","A","D","A","C","C")), 
Frequency=c(10,1,5,2,14,8,20,3,5)) 

    Category City Frequency 
1  One D  10 
2  One A   1 
3  Four B   5 
4  Two B   2 
5  Two A  14 
6 Three D   8 
7  Two A  20 
8  Four C   3 
9 Three C   5 

ich eine Pivot-Tabelle mit sum (Frequency) machen wollen und verwendet, um die ddply Funktion wie folgt aus:

ddply(x,.(Category,City),summarize,Total=sum(Frequency)) 
    Category City Total 
1  Four B  5 
2  Four C  3 
3  One A  1 
4  One D 10 
5 Three C  5 
6 Three D  8 
7  Two A 34 
8  Two B  2 

Aber ich brauche diese Ergebnisse nach der Gesamtzahl in jeder Kategorie gruppiert. So etwas wie das:

Category City Frequency 
1  Two A  34 
2  Two B   2 
3 Three D  14 
4 Three C   5 
5  One D  10 
6  One A   1 
7  Four B   5 
8  Four C   3 

Ich habe gesucht und versucht, sortieren, ordnen, ordnen, aber nichts scheint zu tun, was ich brauche. Wie kann ich das in R machen?

Antwort

4

hier eine Basis R-Version, wo DF das Ergebnis Ihres ddply Anruf:

with(DF, DF[order(-ave(Total, Category, FUN=sum), Category, -Total), ]) 

produziert:

Category City Total 
7  Two A 34 
8  Two B  2 
6 Three D  8 
5 Three C  5 
4  One D 10 
3  One A  1 
1  Four B  5 
2  Four C  3 

Die Logik im Grunde das gleiche wie Davids ist, berechnen die Summe von Total für jede Category, verwenden Sie diese Nummer für alle Zeilen in jedem Category (wir tun dies mit ave(..., FUN=sum)) und dann Sortieren Sie danach und einige Krawattenbrecher, um sicherzustellen, dass Zeug wie erwartet herauskommt.

+0

Dies ist auch eine ausgezeichnete Option. Vielen Dank! –

5

Das ist eine nette Frage und ich kann mir keinen direkten Weg vorstellen, statt einen Index Index zu erstellen und danach zu sortieren. Hier ist ein möglicher data.table Ansatz, die setorder Funktion verwendet, die Ihre Daten durch Bezugnahme bestellen werden

library(data.table) 
Res <- setDT(x)[, .(Total = sum(Frequency)), by = .(Category, City)] 
setorder(Res[, size := sum(Total), by = Category], -size, -Total, Category)[] 
# Category City Total size 
# 1:  Two A 34 36 
# 2:  Two B  2 36 
# 3: Three D  8 13 
# 4: Three C  5 13 
# 5:  One D 10 11 
# 6:  One A  1 11 
# 7:  Four B  5 8 
# 8:  Four C  3 8 

Oder wenn Sie tief in dem Hdleyverse wir ein ähnliches Ergebnis mit dem neueren dplyr Paket erreichen können (wie durch @akrun vorgeschlagen

) ist
library(dplyr) 
x %>% 
    group_by(Category, City) %>% 
    summarise(Total = sum(Frequency)) %>% 
    mutate(size= sum(Total)) %>% 
    ungroup %>% 
    arrange(-size, -Total, Category) 
+0

Vielen Dank! Es funktioniert –