R在purrr::map迭代结构中使用set.seed()



当在R中生成新数据时,我可以使用set.seed()来确保每次运行代码时都得到相同的数据集:

set.seed(12345)
a <- rnorm(500, mean = 50, sd = 10)
set.seed(12345)
b <- rnorm(500, mean = 50, sd = 10)
identical(a, b)
# TRUE

如果我注释掉set.seed()行,identical(a,b)返回FALSE

现在我想使用purrr::map()结构来生成多个参数略有不同的数据集:

library(tidyverse)
means <- c(40, 50, 60)
sds <- c(9, 10, 11)
set.seed(12345)
data <- map2(
means,
sds,
~
rnorm(500, mean = .x, sd = .y)
)

map2()调用生成一个包含三个数据帧的列表。通过这个相对简单的操作,每次运行代码时都得到相同的数据帧。但是我发现,对于涉及某些包(例如bestNormalize)的更复杂、更长的功能管道,当set.seed()命令在map()的迭代循环结构之外时,我不会得到相同的输出。

我不知道如何将set.seed()纳入map()迭代结构中,以便在每次迭代开始时重新调用它。需要明确的是,更大的目标是能够迭代使用随机数生成的函数,并且每次都得到相同的结果。也许在tidyverse中有更好的方法来实现这一点,而不依赖于set.seed()。提前感谢任何帮助!

我希望这能解决你的问题,如何在地图调用中定位种子:

means <- c(40, 50, 60)
sds <- c(9, 10, 11)
myfun <- function(means, sds){
set.seed(12345) # set it before each call
ret <- rnorm(500, mean = means, sd = sds)
return(ret)
}
data <- purrr::map2(means,
sds,
~ myfun(.x, .y))

作为后续,以下是解决我最初问题的最简洁的方法:

library(tidyverse)
means <- c(40, 50, 60)
sds <- c(9, 10, 11)
data <- map2(
means,
sds,
~ {
set.seed(12345)
rnorm(500, mean = .x, sd = .y)
}
)

此代码每次运行时返回相同的结果。

最新更新