2013-01-23 13 views
9

jakie zdefiniowano funkcję niestandardowego tak:Powtarzając funkcję zdefiniowaną przez użytkownika za pomocą replikacji() lub sapply()

my.fun = function() { 

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

return(output) 

} 

która zwraca macierzy wyjściowej, output, złożoną 1000 rzędów i 20 kolumn.

Co muszę zrobić, to powtarzać funkcja powiedzieć 5 razy i przechowywać pięć output wyniki w nowym matrycy, powiedzmy final, ale bez użycia innego dla pętli (w tym do tworzenia kodu wyraźniejsze, a także dlatego, że w drugiej chwili chciałbym spróbować zrównoważyć te dodatkowe 5 powtórzeń).

W związku z tym final powinien być macierzą z 5000 rzędami i 20 kolumnami (uzasadnieniem tych 5 powtórzeń jest to, że w obrębie dwóch pętli for używam, między innymi, funkcji sample).

Próbowałem użyć final <- replicate(5, my.fun()), która poprawnie wylicza pięć powtórzeń, ale muszę "ręcznie" umieścić elementy w zupełnie nowej matrycy 5000 x 20 .. czy jest na to bardziej elitarny sposób? (może używając sapply()?). Dziękujemy

Odpowiedz

11

Jak zwykle masz prawdopodobnie tablicę o trzech wymiarach. Jeśli chcesz mieć listę, która by została dodana, uprość = FALSE. Spróbuj tego:

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

Albo można użyć aperm w przypadku, gdy „ostateczne” jest wciąż tablicą:

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 

Nie mogą być operacje macierzowe bardziej ekonomiczne. Po prostu jeszcze tego nie odkryłem.

+0

Wielkie dzięki za pomoc. Nawiasem mówiąc, o tablicy trzech wymiarów, masz rację :) – Stezzo

7

Jeśli zastąpić replicate z rlply z pakietu plyr, można użyć do.call z rbind:

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

Jeśli nie chcesz polegać na opakowaniu plyr, zawsze można zrobić:

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

Zależy od tego, którego pakietu używasz do obliczeń równoległych, ale oto, jak to zrobić (ukryć w pętli przy użyciu sapply, podobnie jak 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

Wielkie dzięki, to jest bardzo interesujące, a przy okazji planowałem użyć 'opadów śniegu'. – Stezzo

0

Spróbuj tego:

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

Dostaniesz wynik 'ostateczny' w postaci matrycy.

Powiązane problemy