2017-08-23 108 views
-3

我想將一個for循環轉換爲更快的操作,如應用。轉換一個for循環在R

這是我的代碼

for(a in 1:dim(k)[1]){ 

for(b in 1:dim(k)[2]){ 

if((k[a,b,1,1]==0) & (k[a,b,1,2]==0) & (k[a,b,1,3]==0)){ 

    k[a,b,1,1]<-1 

    k[a,b,1,2]<-1 

    k[a,b,1,3]<-1 

     } 
     } 
      } 

這是一個簡單代碼,不會多維陣列k的每個元素上的檢查,如果三個元素是相同的,並且等於0,它分配值1。

有沒有辦法讓它更快?矩陣k有1,444,000個元素,運行它需要很長的時間。誰能幫忙?

感謝

+1

請提供一個*可重複*的例子。 –

+0

我的k矩陣非常大,但可以想象它可以定義如下:k <-array(c(1,1,1,0,2,2,2,0,3,3,3,0)), dim(c(2,2,3))' –

+0

只需粘貼'dput(head(k))',或者如果這仍然過大,請縮小尺寸以包含'k [c(1,2),c (1,2),1,c(1:3)]'。 – LAP

回答

2

隨着應用您可以返回所有的3組合爲一個數值向量,然後檢查你的具體情況:

# This creates an array with the same properties as yours 
    array <- array(data = sample(c(0, 1), 81, replace = TRUE, 
         prob = c(0.9, 0.1)), c(3, 3, 3, 3)) 

    # This loops over all vectors in the fourth dimension and returns a 
    # vector of ones if your condition is met 
    apply(array, MARGIN = c(1, 2, 3), FUN = function(x) { 
     if (sum(x) == 0 & length(unique(x)) == 1) 
     return(c(1, 1, 1)) 
     else 
     return(x) 
    }) 

注意,MARGIN參數指定的尺寸,在其上環。你需要第四維向量,所以你指定c(1, 2, 3)

如果您隨後將此新創建的數組分配給舊數組,則將所有滿足條件的向量替換爲舊數組。

+2

請注意,如果'x'包含負值和正值,'sum(x)== 0'可能是'TRUE', –

+0

是的,我剛剛加了'length(unique(x))== 1'。謝謝。 – Stan125

+0

發佈的解決方案是否有效?如果確實如此,請考慮通過點擊複選標記來接受答案。這向更廣泛的社區表明,您已經找到了解決方案,併爲答覆者和您自己提供了一些聲譽。沒有義務這樣做。 – Stan125

0

您應該首先使用過濾器函數兩次(合成),然後對過濾後的數組應用(lapply?)函數。也許你也可以減少數組,因爲它看起來對第三維不是很感興趣(總是訪問第一項)。你或許應該做一些閱讀有關函數式編程中的R這裏http://adv-r.had.co.nz/Functionals.html

注意我不是A R程序員,但我很熟悉函數式編程(哈斯克爾等),所以這可能給你一個想法。這可能會更快,但這取決於R是如何設計的(懶惰或渴望評估等)。