Uso aggregato con una funzione che utilizza i dati di due colonne (ad esempio COV o prod)

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

  •  26-09-2019
  •  | 
  •  

Domanda

Ho una serie temporale lunga dei dati giornalieri e 101 colonne. Ogni mese vorrei calcolare la cov di ciascuna delle prime 100 colonne con la colonna 101 °. Questo genererebbe un covarianza mensile con la colonna 101 ° per ciascuna delle 100 colonne sulla base di dati giornalieri. Sembra che aggregate fa quello che voglio con funzioni che richiedono un singolo vettore, come mean, ma non riesco a farlo funzionare con cov (o prod).

Per favore fatemi sapere se un dput di pochi mesi sarebbe di aiuto.

> 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 grandi opere, e mi dà i dati mensili che voglio.

> 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

Ma non posso avere una funzione che utilizza due diverse colonne / vettori di lavoro.

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

E non posso farlo funzionare facendo un wrapper cov.

> 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

devo fare questo con un ciclo for? Sto sperando che ci sia un modo più R. Grazie!

È stato utile?

Soluzione

Si dimenticò la dichiarazione function(x) ed è necessario essere sicuri di ottenere il corretto sottoinsieme mensile di data (che calpesta la funzione data, tra l'altro). Prova questo:

> 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

* Nota che ho cambiato le ultime tre osservazioni nei dati di esempio per il mese di agosto, così non ci sarebbe più di un mese di uscita.

Altri suggerimenti

È possibile utilizzare l'approccio che ho scritto qui , vale a dire fare qualcosa di simile:

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

In aggregate(), come è comune a molte funzioni di ricerca che si applicano altre funzioni R per sottoinsiemi di dati, è il nome della funzione che si desidera applicare, in questo caso con l'aggiunta di FUN = cov alla chiamata aggregate(). È quindi possibile fornire argomenti per questa funzione come parte dell'argomento ... speciale.

È possibile passare data[, "Mkt.RF"]) come argomento della funzione y cov(), in modo da qualcosa come questo dovrebbe funzionare:

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

Tuttavia, in questo caso, questo non sembra funzionare come si deve gestire lo zoo-natura dei dati ed essere in grado di sottoinsieme data[, "Mkt.RF"] allo stesso modo l'altro data[,1:100]1 columns are broken up byaggregate () `. Quindi, un alternativa è quella di specificare una funzione in linea , in questo modo:

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

Ecco un esempio che dovrebbe correre fuori dalla scatola:

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)

Il che ci dà:

> 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

Ora, lascia supporre X6 è la colonna "Mkt.RF" e ti aggregare oltre DAT2 [, 1: 5]:

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

Quali rendimenti:

> 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

Ho finito per usare aggregate per formattare i dati, ma ci sono voluti circa 50 minuti per il calcolo di cov con ogni fattore. Per un capriccio ho provato la soluzione plyr, che ha enormi guadagni.

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))))

Questa operazione richiede circa cinque secondi (600x volte più veloce). Credo che ci sono grandi guadagni di velocità per essere avuto nel migliorare l'efficienza delle operazioni sottoinsiemi.

Grazie, tutti, per l'aiuto. Ho imparato molto su questo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top