Powtarzanie funkcji zdefiniowanej przez Użytkownika za pomocą replicate () lub sapply()

Zdefiniowałem funkcję niestandardową, taką jak:

my.fun = function() {

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

 return(output)

}

, która zwraca macierz wyjściową output, złożoną z 1000 wierszy i 20 kolumn.

To, co muszę zrobić, to powtórzyć funkcję say 5 razy i zapisać pięć output wyników w zupełnie nowej macierzy, powiedzmy final, ale bez użycia innej pętli for (to dla uczynienia kodu jaśniejszym, a także dlatego, że w drugiej chwili chciałbym spróbować równoległe te dodatkowe 5 powtórzeń).

Stąd final powinna to być macierz z 5000 wierszami i 20 kolumnami (uzasadnieniem tych 5 powtórzeń jest to, że w ramach dwóch pętli for używam między innymi funkcji sample).

Próbowałem użyć final <- replicate(5, my.fun()), który poprawnie oblicza pięć replikacji, ale potem muszę "ręcznie" umieścić elementy w zupełnie nowej matrycy 5000 x 20.. czy istnieje bardziej elgant sposób, aby to zrobić? (może używając sapply()?). Wielkie dzięki

Author: Stezzo, 0000-00-00

4 answers

Jak stoi prawdopodobnie macie tablicę o trzech wymiarach. Jeśli chcesz mieć listę, dodałbyś simplify = FALSE. Spróbuj tego:

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

Lub możesz użyć aperm w przypadku, gdy "final" jest nadal 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

Mogą być bardziej ekonomiczne operacje macierzy. Jeszcze nie odkryłam.

 12
Author: 42-,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-23 23:27:11

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

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

Jeśli wolisz nie polegać na plyr pakiecie, zawsze możesz to zrobić:

do.call(rbind, lapply(1:5, function(i) my.fun()))
 7
Author: David Robinson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-23 22:03:38

Zależy od tego, którego pakietu używasz do obliczeń równoległych, ale oto jak to zrobię(ukryj go w pętli używając sapply, tak 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()
 7
Author: Roman Luštrik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-23 22:52:04

Spróbuj tego:

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

Otrzymasz wynik 'finalny' w postaci macierzy.

 0
Author: SHARMISTHA CHAKRABORTTY,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-10 07:30:45