Utilisation globale avec une fonction qui utilise les données de deux colonnes (par exemple cov ou prod)

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

  •  26-09-2019
  •  | 
  •  

Question

J'ai une longue série chronologique des données quotidiennes et 101 colonnes. Chaque mois, je souhaite calculer la cov de chacune des 100 premières colonnes à la colonne 101e. Cela générerait une covariance mensuelle avec la colonne 101e pour chacune des 100 colonnes à partir des données quotidiennes. Il semble que aggregate fait ce que je veux avec des fonctions qui prennent un seul vecteur, comme mean, mais je ne peux pas le faire fonctionner avec cov (ou prod).

S'il vous plaît laissez-moi savoir si un dput de quelques mois serait utile.

> 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 fonctionne très bien, et me donne les données mensuelles que je veux.

> 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

Mais je ne peux pas obtenir une fonction qui utilise deux colonnes / vecteurs de travail différents.

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

Je ne peux pas le faire faire du travail une enveloppe de 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

dois-je faire cela avec une boucle de for? J'espère qu'il ya un moyen plus R. Merci!

Était-ce utile?

La solution

Vous avez oublié la déclaration de function(x) et vous devez vous assurer d'obtenir le sous-ensemble mensuel correct de data (qui piétine la fonction data, par la voie). Essayez ceci:

> 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

* Notez que j'ai changé les trois dernières observations dans votre exemple des données au mois d'Août, donc il y aurait plus d'un mois de la production.

Autres conseils

Vous pouvez utiliser l'approche que j'ai écrit , à savoir faire quelque chose comme:

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

Dans aggregate(), comme cela est commun à de nombreuses fonctions de R qui appliquent une autre des fonctions de R à des sous-ensembles de données, vous nommez la fonction que vous souhaitez appliquer, dans ce cas, en ajoutant FUN = cov à votre appel aggregate(). Vous pouvez ensuite fournir des arguments à cette fonction dans le cadre de l'argument spécial ....

Vous pouvez passer data[, "Mkt.RF"]) comme y argument de la fonction cov(), donc quelque chose comme cela devrait fonctionner:

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

Cependant, dans ce cas, cela ne semble pas fonctionner comme vous avez besoin pour gérer le zoo-nature des données et être en mesure de sous-ensemble data[, "Mkt.RF"] de la même manière l'autre data[,1:100]1 columns are broken up byaggregate () `. Ainsi, une alternative est de spécifier une fonction en ligne , comme ceci:

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

Voici un exemple qui devrait fonctionner hors de la boîte:

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)

Ce qui nous donne:

> 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

Maintenant, laisse supposer X6 est votre colonne "Mkt.RF" et nous allons regrouper sur DAT2 [1: 5]:

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

Ce qui donne:

> 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

Je fini par utiliser aggregate pour formater les données, mais il a fallu environ 50 minutes par calcul de cov à chaque facteur. Sur un coup de tête, j'ai essayé la solution plyr, qui a des gains énormes.

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

Cela prend environ cinq secondes (600x fois plus rapide). Je suppose qu'il ya des gains importants de vitesse à avoir dans l'amélioration de l'efficacité des opérations de sous-ensembles.

Merci, tous, pour l'aide. J'ai appris beaucoup sur celui-ci.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top