2010-07-29 16 views
11

Ich versuche Asset-gewichtete Renditen nach Asset-Klasse zu berechnen. Für das Leben von mir kann ich nicht herausfinden, wie man es mit dem Aggregatbefehl macht.Aggregierte und gewichtete Mittelwerte in R

Mein Datenrahmen sieht aus wie diese

dat <- data.frame(company, fundname, assetclass, return, assets) 

Ich versuche, so etwas wie zu tun (das ist nicht kopieren kann, es ist falsch):

aggregate(dat, list(dat$assetclass), weighted.mean, w=(dat$return, dat$assets)) 

Antwort

13

Für den Anfang w=(dat$return, dat$assets)) ist eine Syntax Error.

Und plyr macht dies ein wenig leichter:

> set.seed(42) # fix seed so that you get the same results 
> dat <- data.frame(assetclass=sample(LETTERS[1:5], 20, replace=TRUE), 
+     return=rnorm(20), assets=1e7+1e7*runif(20)) 
> library(plyr) 
> ddply(dat, .(assetclass), # so by asset class invoke following function 
+  function(x) data.frame(wret=weighted.mean(x$return, x$assets))) 
    assetclass  wret 
1   A -2.27292 
2   B -0.19969 
3   C 0.46448 
4   D -0.71354 
5   E 0.55354 
> 
+0

Es funktioniert wie ein Charme. Das erste Mal, als ich es ausprobierte, ersetzte ich x in der Funktion durch dat (die gleiche Zahl für jede Asset-Klasse). Irgendeine Idee, warum das mit dem Aggregatbefehl nicht funktioniert? –

+1

Es scheint, Aggregat aggregiert jede Spalte, in der Sie die Berechnung über zwei Spalten wünschen. Ich denke, vor einer Weile benutze ich 'doBy' oder so ähnlich - aber hey,' plyr' macht es einfacher und hat andere Schnickschnack. –

+3

Du musst noch etwas über 'summarise' lernen;) – hadley

8

A data.table Lösung, wird schneller sein als plyr

library(data.table) 
DT <- data.table(dat) 
DT[,list(wret = weighted.mean(return,assets)),by=assetclass] 
## assetclass  wret 
## 1:   A -0.05445455 
## 2:   E -0.56614312 
## 3:   D -0.43007547 
## 4:   B 0.69799701 
## 5:   C 0.08850954 
+0

Ich wollte schon seit einiger Zeit data.table betrachten. Mit wachsenden Datenbanken denke ich, es ist Zeit. Schätzen Sie den Zeiger! –

5

Dies auch leicht mit Aggregat erfolgt. Es hilft, sich alternative Gleichungen für einen gewichteten Mittelwert zu merken.

rw <- dat$return * dat$assets 
dat1 <- aggregate(rw ~ assetclass, data = dat, sum) 
datw <- aggregate(assets ~ assetclass, data = dat, sum) 
dat1$weighted.return <- dat1$rw/datw$assets 
+1

warte eine Sekunde, das macht keinen Sinn. Sie teilen im Wesentlichen den Mittelwert durch die durchschnittliche Anzahl der Proben. Der gewichtete Mittelwert ist die * Summe * der gewichteten Werte dividiert durch die * Summe * der Gewichte – theforestecologist

+0

Es gibt eine Vielzahl von Möglichkeiten, Gewichtungen zu tun, und in diesem Fall ist es die Anzahl der Stichproben, also ist es richtig. Es gibt mehr als eine Gleichung für die Gewichtung. Führen Sie es auf Dirks Daten aus. – John

+0

Die Verwendung von 'mean()' verwirrte mich hier. Es könnte 'sum()' sein; Die Verwendung von 'mean()' impliziert, dass wir den Zähler und den Nenner durch 'nlevels (assetclass)' teilen (bei sehr großen Datenmengen könnte der Mittelwert jedoch numerisch stabiler sein) –