2013-04-23 50 views
3

我有一个相当基本的问题,但我无法围绕如何实现它: 我有一个data.frame的返回每个仪器的返回行是明智的:计算每周回报 - 应用

tmp<-as.data.frame(t(data.frame(a=rnorm(250,0,1),b=rnorm(250,0,1)))) 

现在我想计算每行的周收益率,即每个后续五个元素(= 1 + return)的乘积。这样我可以得到50个不重叠的每周回报。

我该如何做到这一点? 我希望我可以向你明确我的问题。谢谢

回答

3

嗯,这是不完全清楚,但包zoo和功能rollapply应该得到你想要的东西(我想!):

tmp2 <- rollapply(t(tmp) , width = 5 , FUN = function(x) prod(1 + x) , by = 5 , by.column = TRUE) 
head(tmp2) 
        a    b 
[1,] -6.2279765402 0.2035895290 
[2,] 0.4088722374 3.3903379722 
[3,] 0.2112797361 -0.3812740172 
[4,] 0.7713020593 -0.0559832485 
[5,] -0.4930095796 -2.175
[6,] 6.2076460590 0.0188344154 

我用t()移调数据框,和width参数设置窗口的大小,并且参数设置窗口移动时窗口移动的元素数量,所以我们的宽度为5,并且每次移动5个位置得到50个返回值。同样,当R做矢量化时,我做了function(x) prod(1 + x),如果有多于一个的话,它为x的每个元素增加一个,并且因为我们在函数中设置了宽度为5,所以有5个元素x

而且测试中,我们发现该行的前五个栏的产品“A”是:

1+ tmp[1,1:5] 
      V1  V2  V3  V4  V5 
a -0.4655032 2.02795 2.133612 1.029273 3.004145 

prod(1+ tmp[1,1:5]) 
[1] -6.227977 
0

所以据我得到了你的观点,你想计算每五个产品后续列每行。这里的代码:

# Sample data 
set.seed(3) 
tmp <- as.data.frame(t(data.frame(a=rnorm(250,0,1),b=rnorm(250,0,1)))) 

# Compute products per row in steps of five and rbind results afterwards 
tmp.agg <- do.call("rbind", lapply(seq(nrow(tmp)), function(i) { 
    sapply(seq(1, length(tmp), 5), function(j) { 
    Reduce(prod, tmp[i,j:(j+4)] + 1) 
    }) 
})) 

tmp.agg 
      [,1]   [,2]  [,3]   [,4]  [,5]  [,6]   [,7]  [,8]  [,9]  [,10]  [,11]  [,12] 
[1,] -0.01642594 -0.004438307 -0.0231848 -0.046496247 -0.08965697 -0.07132495 -0.144778621 -0.02727861 0.1148542 0.17021314 -0.3852979 -0.46081791 
[2,] 0.15293410 0.031532305 0.1023034 0.003880801 -0.01795657 -0.03010335 -0.000979364 0.48269767 0.1357064 0.04855989 0.4002406 0.06878954 
      [,13]   [,14]   [,15]  [,16]  [,17]   [,18]  [,19]  [,20]  [,21]  [,22]  [,23]  [,24] 
[1,] 0.05578327 -0.0461665415 -0.0009288497 0.054057705 -0.4094909 -0.0004848274 0.22665096 -0.003439506 -0.161383874 0.07839329 0.06254542 1.320146e-05 
[2,] 0.26472709 -0.0001023569 0.0565177862 -0.009908618 -0.3056234 -0.0798260012 -0.03187966 0.001753645 -0.003536846 -0.05118659 0.72050663 1.726878e-01 
      [,25]  [,26]  [,27]  [,28]  [,29]  [,30]  [,31]  [,32]  [,33]  [,34]   [,35]  [,36]  [,37] 
[1,] 0.09297968 -0.3897201 -0.03092538 3.4957663 0.316273690 0.25769516 -1.54040152 0.04903115 -1.72941882 -0.7814886 -6.448821e-03 -7.1289278 0.01151266 
[2,] 0.03609944 0.5364990 0.01610708 -0.0652631 0.007055414 0.02600772 -0.03116456 2.30021712 0.01136907 0.1532950 -2.141868e-05 -0.7549226 -0.13295228 
      [,38]  [,39]  [,40]  [,41]  [,42]  [,43]  [,44]  [,45]  [,46]  [,47]  [,48]  [,49] 
[1,] -0.4453617085 1.22240858 0.01303989 -0.3-6.736829848 -0.0988588 -0.2314011 0.120263690 0.05006402 0.17631687 0.03386454 -0.14113772 
[2,] 0.0005811551 -0.08559412 -6.35558415 0.01240032 0.001522634 0.1929070 -0.3015167 0.000790891 2.07795076 -0.05711388 0.17521929 0.03909323 
      [,50] 
[1,] -0.11744356 
[2,] 0.09676705 
+0

我不明白你的结果 - 你检查了他们。我接受了OP的评论,他们想要计算类似'prod(1+ tmp [1,1:5])'然后'prod(1+ tmp [1,6:10])'和相同的第二排。你的结果似乎不正确。我误解了吗? **编辑**:我看你可能有不同的数据给我!我会先用你的set.seed进行测试,对不起! – 2013-04-23 09:25:31

+1

使用你的数据我得到了不同的结果,因为你没有为你的向量的每个元素添加1作为OP请求,即'Reduce(prod,(tmp [i,j:(j + 4)] + 1))'如果我这样做,我们的结果是相同的(所以我想这取决于我是否正确理解OP)! – 2013-04-23 09:29:51

+0

相反'减少(prod,tmp [i,j:(j + 4)])+ 1',isn是吗? – fdetsch 2013-04-23 09:45:06