2013-01-23 55 views
9

我已經定義的自定義功能,這樣的功能或(:重複一個用戶定義的使用複製()sapply)

my.fun = function() { 

     for (i in 1:1000) { 
     ... 
     for (j in 1:20) { 
      ... 
     } 
     } 

return(output) 

} 

它返回一個輸出矩陣,output,通過1000行和20列組成。

我需要做的就是重複功能,比如5倍,並存儲五個output結果到一個全新的矩陣,說final,但不使用其他for循環(此爲使代碼更清晰,也因爲在第二時刻,我想嘗試並行化這些額外的5次重複)。

因此final應該是一個具有5000行和20列的矩陣(這5次重複的原理是在我使用的兩個for循環中,其他函數sample)。

我試圖使用final <- replicate(5, my.fun()),它正確地計算了五個重複,但是我必須「手動」將元素放入一個全新的5000 x 20矩陣中。是否有更加優雅的方法可以這樣做? (可能使用sapply()?)。非常感謝

回答

11

正如你所看到的,你可能有一個三維數組。如果你想有一個列表,你可以添加一個簡化= FALSE。試試這個:

do.call(rbind, replicate(5, my.fun(), simplify=FALSE)) 

或者你也可以在「最後」仍是一個數組的情況下使用aperm

fun <- function() matrix(1:10, 2,5) 
final <- replicate(2, fun()) 
> final 
, , 1 

    [,1] [,2] [,3] [,4] [,5] 
[1,] 1 3 5 7 9 
[2,] 2 4 6 8 10 

, , 2 

    [,1] [,2] [,3] [,4] [,5] 
[1,] 1 3 5 7 9 
[2,] 2 4 6 8 10 

> t(matrix(aperm(final, c(2,1,3)), 5,4)) 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 1 3 5 7 9 
[2,] 2 4 6 8 10 
[3,] 1 3 5 7 9 
[4,] 2 4 6 8 10 

有可能是更經濟的矩陣運算。我還沒有發現。

+0

非常感謝您的幫助。順便說一下,關於三維陣列,你是對的:) – Stezzo

7

如果你rlplyplyr包取代replicate,您可以使用do.callrbind

library(plyr) 
do.call(rbind, rlply(5, my.fun())) 

如果你不想靠plyr包,你總是可以做:

do.call(rbind, lapply(1:5, function(i) my.fun())) 
7

取決於您使用哪個軟件包進行並行計算,但這裏是我如何做的(使用sapply,就像replicate一樣,將其隱藏起來)。

library(snowfall) 
sfInit(parallel = TRUE, cpus = 4, type = "SOCK") 
# sfExport() #export appropriate objects that will be needed inside a function, if applicable 
# sfLibrary() #call to any special library 
out <- sfSapply(1:5, fun = my.fun, simplify = FALSE) 
sfStop() 
+0

非常感謝,這是非常有趣的,順便說一下,我打算使用'降雪'。 – Stezzo

0

試試這個:

final <- replicate(5, my.fun(), simplify = "matrix") 

你會得到 '最終' 結果在矩陣的形式。