2017-06-12 44 views
-2

我使用這段代碼。但它非常耗時。我怎麼能加快這一點。有任何幫助嗎?我該如何加快我的代碼(矩陣,sapply,lapply)

veri=replicate(1000, sim.VSS(ncases=3000, nvariables=20, nfactors=1, meanloading=0.5,dichot=1,cut=0)) 
#save date set 
for (i in 1:1000){ 
    write.csv(veri[,,i], paste("v_30002005d_", i, ".csv", sep="")) 
} 

#read csvs 
files<- lapply(1:1000, function(x) { read.csv(paste0("v_30002005d_", x, ".csv"))}[,2:21]) 

formula<- function(a){ 
    sapply(1:nrow(a), function(x) sapply(1:ncol(a), 
             function (y) {{ifelse((as.matrix(rowMeans(a)))[x,]+as.matrix(colMeans(a))[y]>=1 , a[x,y]+as.matrix(item.exam(a)$Item.Rel.woi)[y,],a[x,y])}}) 
)} 

new_mat=sapply(1:1000, function(z){t(formula(files[[z]]))}) 
+2

什麼部分是慢的?你有沒有嘗試分析代碼找到瓶頸?通過並行運行代碼可以改進讀/寫。 –

+1

在寫第三點之前,我想問一下:你是否需要爲rowMeans和colMeans設置矩陣對象?它們被創建爲一維矢量對象,除非將它們轉換爲矩陣,並且子集化矩陣比子集矢量效率低得多。 –

+0

@RomanLuštrik,讀/寫並行打擊I/O瓶頸的可能性有多大? –

回答

1

兩點:

  • 的rowMeans部分(a)重新計算在內部sapply每次迭代(1:NcoI位(a))和也sapply(1:nrow的(a))。對於colMeans(a)部分也是如此。對於尺寸爲n和m的O(m * n^2)時間過長的大對象(因此對於方形對象,執行時間隨着維度的立方體增加)。您可以在「公式」函數的開始處計算行和列的平均值,並將這些值分配給對象,而不是在閉合內填充everthing。一個更簡潔的方法是單獨定義最內層功能並對其進行函數調用(可能會因通話而導致一些懲罰,但會使代碼更加優雅和可跟蹤)

  • 而不是兩個sapply的行和列使用外層,它是層片的二維版本。然而爲了這個工作,裏面的函數必須是矢量化的。你可以定義一個矢量化版本的函數x y向量化(x)

+0

我不確定第二點會有多好。但第一個是絕對值得的。 –

+0

我糾正了我的觀點,因爲情況更糟糕:有兩個嵌套層,所以大O是立方體而不是方形。 –