Повторение пользовательской функции с использованием replicate() или 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()?). Большое спасибо

4 ответа

Решение

Как есть, у вас, вероятно, есть массив с тремя измерениями. Если бы вы хотели получить список, вы бы добавили упрощение = ЛОЖЬ. Попробуй это:

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

Или вы можете использовать aperm в случае, когда "final" все еще является массивом:

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

Могут быть более экономичные матричные операции. Я просто еще не обнаружил.

Зависит от того, какой пакет вы используете для параллельных вычислений, но вот как я это сделаю (скрыть в цикле, используя 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()

Если вы замените replicate с ответом от plyr пакет, вы можете использовать do.call с rbind:

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

Если вы не хотите полагаться на plyr пакет, вы всегда можете сделать:

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

Попробуй это:

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

Вы получите результат 'final' в виде матрицы.

Другие вопросы по тегам