1

私の問題に対する有効な解決策がありますが、非常に遅いため使用できません (私の計算では、シミュレーション全体に 2 ~ 3 年かかると予測されています!)。したがって、私はより良い(より速い)解決策を探しています。これは(本質的に)私が扱っているコードです:

N=4
x <-NULL
for (i in 1:N) { #first loop
  v <-sample(0:1, 1000000, 1/2) #generate data
  v <-as.data.frame(v) #convert to dataframe
  v$t <-rep(1:2, each=250) #group
  v$p <-rep(1:2000, each=500) #p.number
  # second loop
  for (j in 1:2000) { #second loop
    #count rle for group 1 for each pnumber
    x <- rbind(x, table(rle(v$v[v$t==1&v$p==j])))
    #count rle for group 2 for each pnumber
    x <- rbind(x, table(rle(v$v[v$t==2&v$p==j])))
  } #end second loop
} #end first loop
#total rle counts for both group 1 & 2
y <-aggregate(x, list(as.numeric(rownames(x))), sum)

つまり、コードはコイントス シミュレーションを生成します ( v)。グループ係数が生成されます (1 & 2)。p.number 係数が生成されます (1:2000)。グループ 1 とグループ 2 の両方について、各 p.number (1:2000) のランの長さが記録されます (各 p.number には両方のグループのランがあります)。ループ (最初のループ) の後N、総実行長がテーブル (集計) として表示されます (つまりN、合計としてのループにわたる各グループ、各 p.number の実行長)。

作業しているデータは個々のファイルに含まれているため、最初のループが必要です (そのため、ファイルをロードし、さまざまな統計を計算してから、次のファイルをロードして同じことを行います)。私は 2 番目のループにはそれほど執着していませんが、より高速なものに置き換える方法がわかりません。

2 番目のループを (願わくば、はるかに) 高速化するにはどうすればよいでしょうか?

4

2 に答える 2

8

for()あなたはRのループ内でオブジェクトを成長させるという根本的な罪を犯しています。これをしないでください(繰り返しますが)。x最初に十分なストレージを割り当ててから、徐々に入力しxていきます。

x <- matrix(nrow = N * (2000 * 2), ncol = ??)

次に、内側のループで

x[ii, ] <- table(rle(....))

ここで、は最初のループの前にii初期化し、2番目のループ内でインクリメントするループカウンターです。1

x <- matrix(nrow = N * (2000 * 2), ncol = ??)
ii <- 1
for(i in 1:N) {
    .... # stuff here
    for(j in 1:2000) {
        .... # stuff here
        x[ii, ] <- table(rle(....))
        ## increment ii
        ii <- ii + 1
        x[ii, ] <- table(rle(....))
        ## increment ii
        ii <- ii + 1
    } ##  end inner loop
} ## end outer loop

iまた、上記のように、2番目のループでボットfor()loops which will not work.i is just a normal R object and so bothfor()loops will be overwriting it as the progress. USej`のインデックスを再利用していることにも注意してください。

最初にその単純な最適化を試して、それによって実際のシミュレーションが許容可能な時間内に完了するかどうかを確認してください。そうでない場合は、最新のコードを示す新しいQを使用して戻ってきてください。そうすれば、他の最適化について考えることができます。上記の最適化は簡単に実行でき、最適化table()するrle()ため、さらに多くの作業が必要になる場合があります。それに注意して、あなたはその特定のステップを最適化するための1つの道であるかもしれないでtabulate()重い持ち上げをする関数を見るかもしれません。table()

于 2012-10-18T11:52:57.067 に答える
2

rletableの値の組み合わせごとにv$t個別に実行する場合v$pは、2番目のループは必要ありません。この方法でははるかに高速です。

values <- v$v + v$t * 10 + v$p * 100
runlength <- rle(values)
runlength$values <- runlength$values %% 2
x <- table(runlength)


y <- aggregate(unclass(x), list(as.numeric(rownames(x))), sum)

コード全体は次のようになります。が4と低い場合N、成長するオブジェクトxは深刻な問題にはなりません。しかし、一般的に私は@GavinSimpsonに同意します。それは、優れたプログラミング手法ではないということです。

N=4
x <-NULL
for (i in 1:N) { #first loop
  v <-sample(0:1, 1000000, 1/2) #generate data
  v <-as.data.frame(v) #convert to dataframe
  v$t <-rep(1:2, each=250) #group
  v$p <-rep(1:2000, each=500) #p.number

  values <- v$v + N * 10 + v$t * 100 + v$p * 1000
  runlength <- rle(values)
  runlength$values <- runlength$values %% 2
  x <- rbind(x, table(runlength))

} #end first loop
y <-aggregate(x, list(as.numeric(rownames(x))), sum) #tota
于 2012-10-18T13:19:23.467 に答える