Verwenden Sie die Aggregation mit einer Funktion, die Daten aus zwei Spalten verwendet (z. B. COV oder prod).

StackOverflow https://stackoverflow.com/questions/3823549

  •  26-09-2019
  •  | 
  •  

Frage

Ich habe eine lange Zeitreihe von täglichen Daten und 101 Spalten. Jeden Monat möchte ich das berechnen cov von jeder der ersten 100 Spalten mit der 101. Spalte. Dies würde eine monatliche Kovarianz mit der 101. Spalte für jede der 100 Spalten basierend auf täglichen Daten erzeugen. Es scheint, dass aggregate Macht das, was ich will, mit Funktionen, die einen einzelnen Vektor nehmen, wie z. mean, aber ich kann es nicht zum Laufen bringen cov (oder prod).

Bitte lassen Sie mich wissen, ob a dput von ein paar Monaten würde helfen.

> library("zoo")
> data <- read.zoo("100Size-BM.csv", header=TRUE, sep=",", format="%Y%m%d")
> head(data[, c("R1", "R2", "R3", "R100", "Mkt.RF")])
                 R1       R2       R3     R100  Mkt.RF
1963-07-01 -0.00212  0.00398 -0.00472 -0.00362 -0.0066
1963-07-02 -0.00242  0.00678  0.00068 -0.00012  0.0078
1963-07-03  0.00528  0.01078  0.00598  0.00338  0.0063
1963-07-05  0.01738 -0.00932 -0.00072 -0.00012  0.0040
1963-07-08  0.01048 -0.01262 -0.01332 -0.01392 -0.0062
1963-07-09 -0.01052  0.01048  0.01738  0.01388  0.0045

mean Funktioniert großartig und gibt mir die monatlichen Daten, die ich möchte.

> mean.temp <- aggregate(data[, 1:100], as.yearmon, mean)
> head(mean.temp[, 1:3])
                    R1            R2            R3
Jul 1963  0.0003845455  7.545455e-05  0.0004300000
Aug 1963 -0.0006418182  2.412727e-03  0.0022263636
Sep 1963  0.0016250000  1.025000e-03 -0.0002600000
Oct 1963 -0.0007952174  2.226522e-03  0.0004873913
Nov 1963  0.0006555556 -5.211111e-03 -0.0013888889
Dec 1963 -0.0027066667 -1.249524e-03 -0.0005828571

Ich kann jedoch keine Funktion erhalten, die zwei verschiedene Spalten/Vektoren verwendet, um zu arbeiten.

> cov.temp <- aggregate(data[, 1:100], as.yearmon, cov(x, data[, "Mkt.RF"]))
Error in inherits(x, "data.frame") : object 'x' not found

Ich kann es auch nicht funktionieren lassen, eine zu machen cov Verpackung.

> f <- function(x) cov(x, data[, "Mkt.RF"])
> cov.temp <- aggregate(data[, 1:100], as.yearmon, f)
Error in cov(x, data[, "Mkt.RF"]) : incompatible dimensions

Soll ich das mit einem tun for Schleife? Ich hoffe, es gibt mehr R Weg. Vielen Dank!

War es hilfreich?

Lösung

Du hast das vergessen function(x) Erklärung und Sie müssen sicherstellen, dass Sie die richtige monatliche Teilmenge von erhalten data (was stampft auf die data Funktion, übrigens). Versuche dies:

> aggregate(data, as.yearmon, function(x) cov(x,data[index(x),"Mkt.RF"]))
                  R1         R2        R3        R100     Mkt.RF
Jul 1963  1.3265e-05 2.0340e-05 3.464e-05  2.2575e-05  6.267e-05
Aug 1963 -7.1295e-05 2.8875e-05 1.000e-06 -9.9700e-06 -2.608e-05

*Beachten Sie, dass ich die letzten drei Beobachtungen in Ihren Beispieldaten auf den Monat August geändert habe. Daher würde es mehr als einen Monat Ausgang geben.

Andere Tipps

Sie können den Ansatz verwenden, den ich geschrieben habe hier, nämlich so etwas wie:

tapply(1:nrow(data), data$group, function(s) cov(data$x[s], data$y[s]))

Im aggregate(), wie es vielen R -Funktionen üblich ist, die weitere R -Funktionen auf Untergruppen von Daten anwenden, nennen Sie die Funktion, die Sie anwenden möchten, in diesem Fall, indem Sie hinzugefügt werden FUN = cov zu deinem aggregate() Anruf. Sie können dann Argumente für diese Funktion als Teil der liefern ... besonderes Argument.

Sie können passieren data[, "Mkt.RF"]) als Argument y der Funktion cov(), so so etwas sollte funktionieren:

cov.temp <- aggregate(data[, 1:100], as.yearmon, FUN = cov, y = data[, "Mkt.RF"])

In diesem Fall scheint dies jedoch nicht zu funktionieren, da Sie die Zoo-Natur der Daten bewältigen und in der Lage sein können, Teilmenge zu sein data[, "Mkt.RF"] genauso wie die andere data[,1:100]1 columns are broken up byAggregat () `. Eine Alternative besteht also darin, eine Funktion anzugeben in der Reihe, so was:

cov.temp <- aggregate(data[, 1:100], as.yearmon, 
                      FUN = function(x) cov(x, y = data[index(x), "Mkt.RF"]))

Hier ist ein Beispiel, das aus der Box ausgehen sollte:

library("zoo")
dat <- data.frame(matrix(rnorm(365*10*6), ncol = 6))
Dates <- seq.Date(from = as.Date("1963-07-01"), by = "days", length = 365*10)
dat2 <- zoo(dat, order.by = Dates)

Was uns gibt:

> head(dat2)
                    X1         X2         X3          X4         X5         X6
1963-07-01  0.30910867  0.5539864  0.6433690  0.20608146 -1.7706003 -0.4607610
1963-07-02 -0.02519616 -0.1856305  1.0419578  1.01319153  0.8671110  0.1196251
1963-07-03  1.56464024  0.4980238  0.2976338  0.05654036  0.4984225 -1.4626501
1963-07-04 -0.24028698 -1.4365257  0.5707873 -0.05851961 -0.7176343  0.1233137
1963-07-05 -0.87770815 -0.5217949 -2.4875626 -0.08200408 -0.6121038 -0.3881126
1963-07-06 -0.53660576 -1.1098966  2.7411511 -1.37106883 -0.5891641  1.6322411

Nehmen wir jetzt an X6 ist dein "Mkt.RF" Spalte und wir werden über Dat2 [, 1: 5] zusammengefasst:

cov.temp <- aggregate(dat2[, 1:5], as.yearmon, 
                      FUN = function(x) cov(x, y = dat2[index(x),"X6"]))
head(cov.temp)

Welche ergibt:

> head(cov.temp)
                  X1          X2           X3          X4          X5
Jul 1963 -0.30185387  0.09802210  0.019282934 -0.03621272  0.05332324
Aug 1963  0.14739044  0.04276340  0.081847499 -0.35195736 -0.14680017
Sep 1963  0.56698393 -0.08371676  0.003870935 -0.05948173  0.07550769
Oct 1963  0.00711595 -0.07939798  0.118030943 -0.22065278 -0.12474052
Nov 1963  0.06551982  0.22848268  0.231967655  0.02356194 -0.24272566
Dec 1963  0.23866775  0.29464398 -0.034313793  0.09694199 -0.10481527

HTH

Ich habe am Ende verwendet aggregate Um die Daten zu formatieren, aber es dauerte ungefähr 50 Minuten pro Berechnung von cov mit jedem Faktor. Aus einer Laune heraus habe ich das ausprobiert plyr Lösung, die enorme Gewinne hat.

cov.fn <- function(x) nrow(x) * cov(x[, 1:100], x[, 101])
temp <- zoo(daply(data, .(as.yearmon(index(data))), cov.fn), unique(as.yearmon(index(data))))

Dies dauert ungefähr fünf Sekunden (600x -mal schneller). Ich denke, es gibt große Geschwindigkeitsgewinne bei der Verbesserung der Effizienz von Unterlassvorgängen.

Danke alles für die Hilfe. Ich habe viel gelernt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top