如何在R中不使用for循环为零矩阵每行分配随机向量?
解决方案
问题原因
你当前代码仅调用了一次fun(5)$A,得到长度为2的向量,R在赋值时会自动循环该向量以匹配矩阵维度,因此出现两行重复的结果。要实现每行调用一次fun生成独立随机值,需让fun被执行10次并将结果整理为矩阵。
方法1:Base R的replicate函数
replicate可重复执行表达式并自动整理结果,是最简洁的Base R实现方式:
set.seed(200) fun <- function(mu) { a <- rnorm(2, mu, 1) b <- rexp(2, mu) list("A" = a, "B" = b) } # 重复调用10次fun(5)$A,转置后得到10行2列矩阵 M <- t(replicate(10, fun(5)$A))
replicate(10, fun(5)$A)会生成2行10列的矩阵(每次返回的长度2向量按列排列),通过t()转置后得到目标格式的矩阵,每行都是独立生成的随机值。
方法2:lapply + do.call(rbind, ...)
这也是Base R的经典写法,通过lapply生成列表后合并为矩阵:
set.seed(200) M <- do.call(rbind, lapply(1:10, function(x) fun(5)$A))
方法3:向量化改造函数(最高效)
由于rnorm和rexp本身支持向量化生成随机数,直接改造fun一次性生成所有所需值,效率远高于多次函数调用:
set.seed(200) # 改造后的函数,支持生成n行结果 fun_vec <- function(mu, n) { # 一次性生成2*n个随机数,整理为n行2列矩阵 a <- matrix(rnorm(2*n, mu, 1), nrow = n, ncol = 2) b <- matrix(rexp(2*n, mu), nrow = n, ncol = 2) list("A" = a, "B" = b) } # 直接生成10行的结果 M <- fun_vec(5, 10)$A
验证结果
运行上述任意方法后,矩阵M的每行均为独立随机值,示例输出(以方法1为例):
[,1] [,2] [1,] 5.084756 5.226460 [2,] 4.727650 5.242540 [3,] 5.359035 4.774626 [4,] 4.880907 5.472666 [5,] 3.872272 5.137663 [6,] 5.676256 4.888611 [7,] 4.496857 5.038764 [8,] 5.178080 4.337789 [9,] 5.182021 4.872760 [10,] 4.787672 5.497815
内容的提问来源于stack exchange,提问作者DevD
相关产品推荐
相关产品推荐

