如何多次 运行 一个函数并将结果写入列表?
How to run a function multiple times and write the results to a list?
我有一个创建矩阵的函数,我想调用这个函数一千次,这样最后我就有了一个包含 1000 个矩阵的列表。这是一个例子:
set.seed(1)
gen_mat <- function(x) matrix(c(1, 1, 1, x + rnorm(1)), nrow = 2)
现在,我尝试了 replicate(10, gen_mat(1))
,但是这个 returns 是一个数组而不是列表。怎么做?
base
R
n <- 10
lapply(seq_len(n), gen_mat(1))
purrr
包裹
library(purrr)
map(seq_len(n), ~gen_mat(1))
以上答案、评论和我自己的答案的组合。自然,我更喜欢我的。另外,我认为上面 base
R 的答案有误。
n <- 10
# give 1 to gen_mat n-times
lapply(rep(1, n), gen_mat)
# replicate n-times
replicate(n, gen_mat(1), simplify=FALSE)
# lapply returns error if FUN is not function or
# the function is not taking an argument. Hence a dummy function.
lapply(seq_len(n), function(x) gen_mat(1))
对三种方法进行微基准测试
我为 n
使用了较大的值,但在我的桌面上使用较小的 n
结果也很相似。为此,replicate
比其他两种方法花费的时间更长。
set.seed(1)
gen_mat <- function(x) matrix(c(1, 1, 1, x + rnorm(1)), nrow = 2)
n <- 1000
library(microbenchmark)
library(ggplot2)
mb <- microbenchmark(
lap1 = {lapply(rep(1, n), gen_mat)},
repl = {replicate(n, gen_mat(1), simplify=FALSE)},
lap2 = {lapply(seq_len(n), function(x) gen_mat(1))},
times = 10000L
)
mb
# Unit: milliseconds
# expr min lq mean median uq max neval cld
# lap1 2.839435 3.494157 4.806954 3.854269 5.611413 103.0111 10000 a
# repl 3.091829 3.777199 5.140789 4.165856 6.013591 101.4318 10000 b
# lap2 3.131491 3.761274 5.089170 4.140316 5.939075 101.1983 10000 b
autoplot(mb)
只需添加 purrr::rerun
就可以 shorthand for replicate(..., simplify = FALSE)
library(purrr)
rerun(10, gen_mat(1))
# [[1]]
# [,1] [,2]
# [1,] 1 1.000000
# [2,] 1 1.918977
# [[2]]
# [,1] [,2]
# [1,] 1 1.000000
# [2,] 1 1.782136
# [[3]]
# [,1] [,2]
# [1,] 1 1.000000
# [2,] 1 1.074565
# [[4]]
# [,1] [,2]
# [1,] 1 1.0000000
# [2,] 1 -0.9893517
# [[5]]
# [,1] [,2]
# [1,] 1 1.000000
# [2,] 1 1.619826
# [[6]]
# [,1] [,2]
# [1,] 1 1.0000000
# [2,] 1 0.9438713
# [[7]]
# [,1] [,2]
# [1,] 1 1.0000000
# [2,] 1 0.8442045
# [[8]]
# [,1] [,2]
# [1,] 1 1.0000000
# [2,] 1 -0.4707524
# [[9]]
# [,1] [,2]
# [1,] 1 1.0000000
# [2,] 1 0.5218499
# [[10]]
# [,1] [,2]
# [1,] 1 1.000000
# [2,] 1 1.417942
我有一个创建矩阵的函数,我想调用这个函数一千次,这样最后我就有了一个包含 1000 个矩阵的列表。这是一个例子:
set.seed(1)
gen_mat <- function(x) matrix(c(1, 1, 1, x + rnorm(1)), nrow = 2)
现在,我尝试了 replicate(10, gen_mat(1))
,但是这个 returns 是一个数组而不是列表。怎么做?
base
R
n <- 10
lapply(seq_len(n), gen_mat(1))
purrr
包裹
library(purrr)
map(seq_len(n), ~gen_mat(1))
以上答案、评论和我自己的答案的组合。自然,我更喜欢我的。另外,我认为上面 base
R 的答案有误。
n <- 10
# give 1 to gen_mat n-times
lapply(rep(1, n), gen_mat)
# replicate n-times
replicate(n, gen_mat(1), simplify=FALSE)
# lapply returns error if FUN is not function or
# the function is not taking an argument. Hence a dummy function.
lapply(seq_len(n), function(x) gen_mat(1))
对三种方法进行微基准测试
我为 n
使用了较大的值,但在我的桌面上使用较小的 n
结果也很相似。为此,replicate
比其他两种方法花费的时间更长。
set.seed(1)
gen_mat <- function(x) matrix(c(1, 1, 1, x + rnorm(1)), nrow = 2)
n <- 1000
library(microbenchmark)
library(ggplot2)
mb <- microbenchmark(
lap1 = {lapply(rep(1, n), gen_mat)},
repl = {replicate(n, gen_mat(1), simplify=FALSE)},
lap2 = {lapply(seq_len(n), function(x) gen_mat(1))},
times = 10000L
)
mb
# Unit: milliseconds
# expr min lq mean median uq max neval cld
# lap1 2.839435 3.494157 4.806954 3.854269 5.611413 103.0111 10000 a
# repl 3.091829 3.777199 5.140789 4.165856 6.013591 101.4318 10000 b
# lap2 3.131491 3.761274 5.089170 4.140316 5.939075 101.1983 10000 b
autoplot(mb)
只需添加 purrr::rerun
就可以 shorthand for replicate(..., simplify = FALSE)
library(purrr)
rerun(10, gen_mat(1))
# [[1]]
# [,1] [,2]
# [1,] 1 1.000000
# [2,] 1 1.918977
# [[2]]
# [,1] [,2]
# [1,] 1 1.000000
# [2,] 1 1.782136
# [[3]]
# [,1] [,2]
# [1,] 1 1.000000
# [2,] 1 1.074565
# [[4]]
# [,1] [,2]
# [1,] 1 1.0000000
# [2,] 1 -0.9893517
# [[5]]
# [,1] [,2]
# [1,] 1 1.000000
# [2,] 1 1.619826
# [[6]]
# [,1] [,2]
# [1,] 1 1.0000000
# [2,] 1 0.9438713
# [[7]]
# [,1] [,2]
# [1,] 1 1.0000000
# [2,] 1 0.8442045
# [[8]]
# [,1] [,2]
# [1,] 1 1.0000000
# [2,] 1 -0.4707524
# [[9]]
# [,1] [,2]
# [1,] 1 1.0000000
# [2,] 1 0.5218499
# [[10]]
# [,1] [,2]
# [1,] 1 1.000000
# [2,] 1 1.417942