将聚合与使用两列数据的函数一起使用(例如cov 或产品)
题
我有很长的每日数据时间序列和 101 列。每个月我想计算 cov
前 100 列中的每一列与第 101 列。这将根据每日数据为 100 列中的每一列生成与第 101 列的月度协方差。看起来 aggregate
使用采用单个向量的函数执行我想要的操作,例如 mean
, ,但我无法让它工作 cov
(或者 prod
).
请让我知道如果 dput
几个月会有帮助。
> 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
效果很好,并为我提供了我想要的每月数据。
> 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
但我无法获得使用两个不同列/向量来工作的函数。
> cov.temp <- aggregate(data[, 1:100], as.yearmon, cov(x, data[, "Mkt.RF"]))
Error in inherits(x, "data.frame") : object 'x' not found
我也无法让它工作 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
我应该这样做吗 for
环形?我希望还有更多 R
方式。谢谢!
解决方案
你忘记了 function(x)
声明,您需要确保您获得正确的每月子集 data
(它踩在 data
顺便说一下,函数)。尝试这个:
> 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
*请注意,我将示例数据中的最后三个观察值更改为八月,因此会有超过一个月的输出。
其他提示
你可以使用我写的方法 这里, ,即做类似的事情:
tapply(1:nrow(data), data$group, function(s) cov(data$x[s], data$y[s]))
在 aggregate()
, ,正如许多将另一个 R 函数应用于数据子集的 R 函数所常见的那样,您可以命名要应用的函数,在本例中通过添加 FUN = cov
给你的 aggregate()
称呼。然后,您可以作为该函数的一部分提供参数 ...
特别论证。
你可以通过 data[, "Mkt.RF"])
作为论据 y
功能的 cov()
, ,所以这样的事情应该有效:
cov.temp <- aggregate(data[, 1:100], as.yearmon, FUN = cov, y = data[, "Mkt.RF"])
但是,在这种情况下,这似乎不起作用,因为您需要处理数据的动物园性质并能够进行子集化 data[, "Mkt.RF"]
以同样的方式另一个 data[,1:100]1 columns are broken up by
聚合()`。所以另一种方法是指定一个函数 排队, , 像这样:
cov.temp <- aggregate(data[, 1:100], as.yearmon,
FUN = function(x) cov(x, y = data[index(x), "Mkt.RF"]))
这是一个开箱即用的示例:
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)
这给了我们:
> 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
现在,我们假设 X6
是你的 "Mkt.RF"
列,我们将聚合 dat2[,1:5]:
cov.temp <- aggregate(dat2[, 1:5], as.yearmon,
FUN = function(x) cov(x, y = dat2[index(x),"X6"]))
head(cov.temp)
其产量:
> 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
华泰
我最终使用了 aggregate
格式化数据,但每次计算大约需要50分钟 cov
与每个因素。一时兴起我尝试了 plyr
解决方案,收获巨大。
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))))
这大约需要五秒(快 600 倍)。我想在提高子集化操作的效率方面会有很大的速度提升。
谢谢大家的帮助。我在这方面学到了很多东西。