2016-07-21 4 views
0
require(quantmod) 
require(TTR) 

iris2 <- iris[1:4] 
b=NULL 
for (i in 1:ncol(iris2)){ 
for (j in 1:ncol(iris2)){ 
a<- runCor(iris2[,i],iris2[,j],n=21) 
b<-cbind(b,a)}} 

データフレーム内の異なる列のローリング相関を計算し、そのデータを列で別々に保存したいと考えています。上のコードは変数bにデータを格納していますが、すべての結果をダンプするだけでは役に立ちません。私が望むのは、各iに対して異なるデータフレームを作成できることです。forループのデータをforループの内部に格納する方法は?

この場合、私が最終的に望むのは、4つのデータフレームです。各データフレームには、ローリング相関を示す4つの列、つまりdf1 = col1のcol1とcol1,2,3,4、df2 =コル2の対col 1,2,3,4 ...など)

私はlapplyまたはrollapplyを使用すると考えましたが、同じ問題が発生しました。

d=NULL 
for (i in 1:ncol(iris2)) 
for (j in 1:ncol(iris2)) 
{c<-rollapply(iris2, 21 ,function(x) cor(x[,i],x[,j]), by.column=FALSE) 
d<-cbind(d,c)} 

本当に入力がありますか。

+0

インデックスベクトルに 'foreach'ループまたは' mapply'を試してみてください。それはあなたにDFのリストのリストを与えるでしょう。 'i'で' j'、次に 'c&d'で入れ子にします – Adam

+0

forループでcbindを使用することは決してお勧めできません。余分にメモリにコピーされないようにするには、あらかじめ定義された長さのリストを使用する方がはるかに良い方法です。 –

答えて

2

拡張ループを維持したい場合、データフレームのリストはどうですか?

e <- list(length = length(ncol(iris2))) 

for (i in 1:ncol(iris2)) { 
    d <- matrix(0, nrow = length(iris2[,1]), ncol = length(iris2[1,])) 
    for (j in 1:ncol(iris2)) { 
     d[,j]<- runCor(iris2[,i],iris2[,j],n=21) 
    } 
e[[i]] <- d 
} 

また、あなたが、プレースホルダとしたいスペースの量を割り当て、その空間にアイテムを置くのではなくrbindcbindを使用することをお勧めします。

+0

提案していただきありがとうございます。この方法について考えなかったし、それは素晴らしいです。しかし、問題は、実行している実際のデータには100列以上があり、コードを実行するのに20分以上かかるようです...私は簡単に他のデータとのローリング相関を見たいと思っています。私の質問で述べた。より効率的にする方法はありますか?再度、感謝します。 – sh2657

+0

@ sh2657あなたのコメントは切り捨てられているようです。 –

+0

申し訳ありませんが、誤って入力して編集していました。今は良いはずです。 – sh2657

2

それは(あなたが他の回答のように、リストにそれらを置くことを好む必要があります) Rにその場でデータフレームを作成することをお勧めではありませんが、そうするための方法は、assignget機能を使用することです。

for (i in 1:ncol(iris2)) { 
    for (j in 1:ncol(iris2)){ 
     c <- runCor(iris2[,i],iris2[,j],n=21) 

     # Assign 'c' to the name df1, df2... 
     assign(paste0("df", i), c) 
     } 
} 

# to have access to the dataframe: 
get("df1") 

# or inside a loop 
get(paste0("df", i)) 
1

あなたの計算が遅いと述べたので、私はあなたに並列ソリューションを提供したいと思います。現代のコンピュータを使用している場合は、おそらく2つのコアがあります(4つ以上でない場合)。あなたは簡単に介して、これをチェックすることができます

require(parallel) # for parallelization 
detectCores() 

今コード:

require(quantmod) 
require(TTR) 

iris2 <- iris[,1:4] 

並列化は、各プロセスで作成し、破壊された特殊な環境に置かれる関数や変数が必要です。つまり、変数と関数を定義するためにラッパー関数を作成する必要があります。

wrapper <- function(data, n) { 
    # variables placed into environment 
    force(data) 
    force(n) 

    # functions placed into environment 
    # same inner loop written in earlier answer 
    runcor <- function(data, n, i) { 
    d <- matrix(0, nrow = length(data[,1]), ncol = length(data[1,])) 
    for (j in 1:ncol(data)) { 
     d[,i] <- TTR::runCor(data[,i], data[,j], n = n) 
    } 
    return(d) 
    } 

    # call function to loop over iterator i 
    worker <- function(i) { 
    runcor(data, n, i) 
    } 

    return(worker) 
} 

ローカルコンピュータにクラスタを作成します。これにより、複数のコアを別々に実行できます。

parallelcluster <- makeCluster(parallel::detectCores()) 
models <- parallel::parLapply(parallelcluster, 1:ncol(iris2), 
           wrapper(data = iris2, n = 21)) 
stopCluster(parallelcluster) 

終了したらクラスタを停止して閉じます。

+0

あなたは最高です。ありがとうございました。 – sh2657

関連する問題