2013-02-21 13 views
12

Ich brauche Gruppe von Ebenen mit ddply oder Aggregat, wenn das einfacher ist. Ich bin nicht wirklich sicher, wie man das macht, da ich Cumsum als meine Aggregatfunktion verwenden muss. Dies ist, was meine Daten wie folgt aussehen:Cumsum mit ddply

level1  level2 hour  product 
A   tea  0   7 
A   tea  1   2 
A   tea  2   9 
A   coffee 17   7 
A   coffee 18   2 
A   coffee 20   4 
B   coffee 0   2 
B   coffee 1   3 
B   coffee 2   4 
B   tea  21   3 
B   tea  22   1 

erwartete Ausgabe:

A  tea  0 7 
A  tea  1 9 
A  tea  2 18 
A  coffee 17 7 
A  coffee 18 9 
A  coffee 20 13 
B  coffee 0 2 
B  coffee 1 5 
B  coffee 2 9 
B  tea  21 3 
B  tea  22 4 

I

ddply(dd,c("level1","level2","hour"),summarise,cumsum(product)) 

mit versucht, aber das bedeutet nicht zusammenzufassen, die ich denke, da die Stunden wird für die Gruppe verwendet und dadurch wird es gespalten..ich denke .. Ich bin mir nicht sicher, ob ich vollständig verstehe, wie das Aggregat hier funktioniert. Gibt es eine Möglichkeit, die benötigte Ausgabe mit Aggregat oder ddply zu erhalten?

+0

Das glaube ich nicht, dass Sie von ebenen1 + Level2 + Stunde, zusammenfassen soll, weil dann Ihre Aggregation anders sein würde als das, was Sie gezeigt haben. – A5C1D2H2I1M1N2O1R2T1

Antwort

16

Hier ist eine Lösung in R Basis ave und within mit:

within(mydf, { 
    cumsumProduct <- ave(product, level1, level2, FUN = cumsum) 
}) 
# level1 level2 hour product cumsumProduct 
# 1  A tea 0  7    7 
# 2  A tea 1  2    9 
# 3  A tea 2  9   18 
# 4  A coffee 17  7    7 
# 5  A coffee 18  2    9 
# 6  A coffee 20  4   13 
# 7  B coffee 0  2    2 
# 8  B coffee 1  3    5 
# 9  B coffee 2  4    9 
# 10  B tea 21  3    3 
# 11  B tea 22  1    4 

Natürlich, wenn Sie wollten die bestehende Produktsäule fallen zu lassen, Sie können den Befehl folgendermaßen ändern, um die aktuelle Spalte "Produkt" zu überschreiben:

within(mydf, { 
    product <- ave(product, level1, level2, FUN = cumsum) 
}) 

Ihr derzeitiger Ansatz funktioniert teilweise nicht, weil Sie "Stunde" als eine Ihrer Gruppierungsvariablen eingefügt haben. Mit anderen Worten, es sieht die Kombination von "A + Tee + 0" anders als "A + Tee + 1" aus, aber von Ihrem gewünschten Output, scheinen Sie einfach die Kombination von "A + Tee" zu haben Gruppe.

aggregate wird nicht funktionieren, wie Sie erwarten, denn es wird alles in eine data.frame mit der gleichen Anzahl von Zeilen wie die Anzahl der einzigartigen Kombinationen von "level1" und "level2", in diesem Fall 4 Zeilen zu verdichten. Die aggregierte Spalte wäre eine list. Die Werte wären korrekt, aber es wäre weniger nützlich.

Hier aggregate und seine Ausgabe:

> aggregate(product ~ level1 + level2, mydf, cumsum) 
    level1 level2 product 
1  A coffee 7, 9, 13 
2  B coffee 2, 5, 9 
3  A tea 7, 9, 18 
4  B tea  3, 4 
+0

danke! das funktioniert :) Also wenn du Produkt, level1 und level2 als die drei Spalten gibst, sagst du es, diese 3 auszuwählen und zu gruppieren, was anders ist? – Roshini

+1

'ave' wendet die Funktion nur auf eine Variable (die erste) an, die von so vielen anderen Variablen wie nötig gruppiert wird. Aus diesem Grund muss 'FUN' verwendet werden, um die Funktion aufzurufen, die Sie auf die Variable * first * anwenden möchten. – A5C1D2H2I1M1N2O1R2T1

+0

@AnandaMahto Der Nachteil des Unterrichtens von Leuten ist, dass es sich nicht auf neue Situationen verallgemeinert, und es ist auch _really_ ineffizient, wenn die Kombination von Gruppierungsvariablen spärlich ist (leider ist es ein einfacher Fehler, den R-core nicht behoben hat). – hadley

7

sollten Sie transform anstelle von summarise:

# you should probably order your `level2` first 
dd$level2 <- factor(dd$level2, levels=c("tea", "coffee")) 
# and transform using level1 and level2 alone, not hour 
# if you use hour, the groups will be for each row 
ddply(dd, .(level1, level2), transform, product=cumsum(product)) 

# level1 level2 hour product 
# 1  A tea 0  7 
# 2  A tea 1  9 
# 3  A tea 2  18 
# 4  A coffee 17  7 
# 5  A coffee 18  9 
# 6  A coffee 20  13 
# 7  B tea 21  3 
# 8  B tea 22  4 
# 9  B coffee 0  2 
# 10  B coffee 1  5 
# 11  B coffee 2  9 
+0

Vielen Dank für deine Antwort ... aber was, wenn ich mehr als 2 Level in Level2 habe. Es kann leicht ein Szenario geben, das ich um 10 oder mehr Ebenen haben könnte, muss ich sie jedes Mal in einen Vektor setzen? – Roshini

+1

'dd $ level2 <- Faktor (dd $ level2, levels = dd $ levels2 [! Dupliziert (dd $ levels2)], geordnet = T)' – Arun