Повторение пользовательской функции с использованием 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' в виде матрицы.