2017-12-05 7 views
1

ための計算3月のリターン私は毎月の株式リターンのデータフレームを持っている:月次リターンのデータフレーム

d<-data.frame(replicate(5,sample(rnorm(1),6,rep=TRUE))) 

今、私は次のようにn個ヶ月のリターンにこれらのリターンを変換したいと思います(例えばnの= 3):

d[1,1]=(1+d[1,1])*(1+d[2,1])*(1+d[3,1]) 
d[2,1]=(1+d[2,1])*(1+d[3,1])*(1+d[4,1]) 
d[3,1]=(1+d[3,1])*(1+d[4,1])*(1+d[5,1]) 

そして、次の列に同じ

d[1,2]=(1+d[1,2])*(1+d[2,2])*(1+d[3,2]) 
d[2,2]=(1+d[2,2])*(1+d[3,2])*(1+d[4,2]) 
d[3,2]=(1+d[3,2])*(1+d[4,2])*(1+d[5,2]) 

は、私はあなたのアイデアを得ると思います。次のように

は今、私が進むことを考えていた方法は、次のとおりです。

apply(d, 2, fun) 

楽しみは次のように定義されている場所:

fun<-function(df_column) 
{ 
    # Loop over df_column rows 
for (row in 1:nrow(df_column)) { 
    d[row]=(1+d[row])*(1+d[row+1])*(1+d[row+2]) 
} 
} 

このアプローチでは意味をなさないか、よりエレガントな方法はありますか?

答えて

2

rollapplyを好きな方法で試してみてください。最初の行は、最後の2行にNAsを配置します。 2つ目は部分積で塗りつぶし、3つ目は最後の2つの行を削除します。 3引数はローリングプロダクトの幅を指定し、他の幅を試したい場合は変更できます。詳細は、?rollapplyを参照してください。

library(zoo) 

rollapplyr(d + 1, 3, prod, align = "left", fill = NA) 

rollapplyr(d + 1, 3, prod, align = "left", partial = TRUE) 

rollapplyr(d + 1, 3, prod, align = "left") 
+0

私は 'zoo'からその関数を使用しているのを見たことがありません。私が気付いた好奇心の中で、それは 'map'ソリューションよりもはるかに遅く、なぜそうだったのか不思議でした。 –

+2

これは動物園のオブジェクトに合わせて作られ、オブジェクトを動物園の内部で動物園に変換してから戻って、Rで書かれています。また、非常に一般的です。あなたは 'exp(rollsum(log(1 + d)、3、align =" left "、fill = NA))'を試すことができます。また、C++で書かれたいくつかのローリング関数を持つRcppRollパッケージもあります。 –

+0

優秀、ヒントありがとう! –

1

purrr::map_dfdplyr::leadを使用して、後の処理を達成できます。

library(dplyr) 
library(purrr) 

set.seed(42) 

df <- data.frame(replicate(5, rnorm(6))) 

df %>% 
    map_df(function(x) { 

    (1 + x) * (1 + lead(x, 1)) * (1 + lead(x, 2)) 

    }) 

# # A tibble: 6 x 5 
#   X1  X2   X3   X4   X5 
#  <dbl> <dbl>  <dbl>  <dbl>  <dbl> 
# 1 1.4068610 6.863243 -0.2430606 -2.3172461 1.2246900 
# 2 0.9688954 2.561324 1.0225645 -1.2568729 -0.3228241 
# 3 3.1256224 6.520767 1.0148172 -0.4485965 -0.8276191 
# 4 2.0496361 7.100212 -1.9395879 -1.4328679 -0.4011510 
# 5  NA  NA   NA   NA   NA 
# 6  NA  NA   NA   NA   NA 

N.B. 2つのレコードを先読みしているので、最後の2行はNAしか生成しません。除外したい場合は、na.omitまたはtidyr::drop_naをパイプに追加することができます。

+0

また非常にいいです。ありがとう、ケビン! –

関連する問題