2013-01-09 132 views
0

我想寫一個R腳本,作爲第一步,爲輸入矩陣的每一行計算dist()和其他東西,然後,作爲腳本的第二步,使用每對輸出矩陣在第一步中得到另一個計算。 我的問題是我無法「保存」從第一步獲得的所有矩陣。有人能告訴我一個好的策略嗎?提高R腳本效率

我的代碼如下所示:

n<- nrow (aa) 
output <- matrix (0, n, n) 
for (i in 1:n) 
{ 
    for (j in i:n) 
    { 
     akl<- function (dii){ 
      ddi<- as.matrix (dii) 
      m<- rowMeans(ddi) 
      M<- mean(ddi) 
      r<- sweep (ddi, 1, m) 
      b<- sweep (r, 2, m) 
      return (b + M) 
      } 
     A<- akl(dist(aa[i,])) 
     B<- akl(dist(aa[j,])) 
      V <- sqrt ((sqrt (mean(A * A))) * (sqrt(mean(B * B)))) 
     if (V > 0) { 
      output[i,j] <- (sqrt(mean(A * B)))/V else output[i,j] <- 0 
      } 
    } 
} 

我想獲得從akl功能的所有結果矩陣,然後將它們用於計算的其餘部分。 我在這裏展示的腳本在時間上是昂貴的,因爲它每次都計算akl,對於大輸入矩陣是一個問題。

+0

在嘗試避免嵌套的for循環和可能的矢量化之前用'else else {'替換'else'。 – Roland

回答

3

你不需要在j循環內重新計算A,把它帶到外面。另外,你不需要重新定義循環內部的函數(假設它不依賴於循環內部的任何東西)。

n<- nrow (aa) 
output <- matrix (0, n, n) 
akl<- function (dii){ 
      ddi<- as.matrix (dii) 
      m<- rowMeans(ddi) 
      M<- mean(ddi) 
      r<- sweep (ddi, 1, m) 
      b<- sweep (r, 2, m) 
      return (b + M) 
      } 
for (i in 1:n) 
{ 
    A<- akl(dist(aa[i,])) 
    for (j in i:n) 
    { 
     B<- akl(dist(aa[j,])) 
      V <- sqrt ((sqrt (mean(A * A))) * (sqrt(mean(B * B)))) 
     if (V > 0) { 
      output[i,j] <- (sqrt(mean(A * B)))/V else output[i,j] <- 0 
      } 
    } 
} 

試試這個,運行你的測試(你已經寫好了測試,對吧?)然後看看。

+0

它完美的作品!!!!!!!!!!! :D很開心!非常感謝!!!!!!! :) – Gabelins

+0

我在一個相當大的測試矩陣(400x400)上試了一下。它更快地尊重我的腳本(需要一半的時間,我的腳本需要)。問題是我必須在5000x700的矩陣上使用它......反正需要很多時間!其他改進/建議?謝謝 – Gabelins

+0

對於實際速度,用C或C++重寫整個事物,並使用RCpp。有關在任何編程語言中加快速度的一般準則都適用 - 編寫測試用例,分析代碼(請參閱?Rprofile),然後優化佔用最多時間的位。 – Spacedman

0

現在您已經對代碼進行了改進,查看了編譯器包。通過使用帶有enablejit(3)的編譯器,您可以節省大量循環的腳本的時間。