【问题标题】:Random number generator for the vector in RR中向量的随机数生成器
【发布时间】:2018-06-03 19:35:32
【问题描述】:

当我尝试复制结果时,我有一个问题,我想出了一个问题。

l <- {}
for(i in 1:3){
  set.seed(1)
  l[i] <- rnorm(n = 1, i, i)  
}

这会产生

0.3735462 0.7470924 1.1206386

但是,如果我写

set.seed(1)
rnorm(n = 3, 1:3, 1:3)
0.3735462 2.3672866 0.4931142

或者

set.seed(1)
rmvnorm(n = 1, 1:3, sqrt(diag(1:3)))
0.3735462 2.21839 1.900251

我没有得到相同的结果。有什么问题? 我的目标是矢量化 for 循环,这就是我提出问题的原因。

更新

下面的答案解释了它如何适用于 rnorm 并且应该适用于 R 中的所有随机数生成器,但是当我使用 rgig 尝试这种方法时(广义逆高斯分发)我又遇到了一个问题。

l <- {}
for(i in 1:3){
  set.seed(1)
  l[i] <- rgig(n = i, i, i, i)[i]
}
1.629091 1.500733 1.564364

如果我使用

set.seed(1)
rgig(n = 3, 1:3, 1:3, 1:3)
1.629091 1.440166 3.264135

当我使用时

sapply(1:3,function(x){set.seed(1);rgig(x,x,x,x)})

它没有显示与 rnorm 类似的模式。 我假设它 rgig 不支持矢量化,因为如果我们写:

set.seed(1)
rgig(n = 3, 1, 1, 1)
1.629091 1.440166 3.264135

与矢量化的相同之处。我说的对吗?

【问题讨论】:

  • 您的预期结果是什么?我不确定我是否完全理解您不想要的第二个 2 示例的含义。
  • 最好的方法是将行更改为rnorm(1, 1) 并再次运行。输出将解释逻辑。
  • @griffmer,我的预期结果是,如果我使用 set.seed,矢量化随机数生成器和 for 循环生成器将产生相同的结果。我有两个 R 代码,我想比较它们,但一个用于循环,另一个(我的)矢量化。

标签: r random


【解决方案1】:

使用您的循环,您可以这样做:

set.seed(1)
rnorm(n = 1, 1, 1)
set.seed(1)
rnorm(n = 1, 2, 2)
set.seed(1)
rnorm(n = 1, 3, 3)

使用您的第二行代码,您可以这样做:

set.seed(1)
rnorm(3, 1:3, 1:3)

因此结果不同。 换句话说:使用循环,您执行 set.seed(1) 并随机选择 1 个数字 3 次,首先您从平均值和 sd 为 1 的分布中抽取一个数字,然后从平均值和 sd 为 2 的分布中抽取一个数字第 2 次,最后第 3 次的平均值和 sd 为 3。

另一个是直接从均值向量和由 1、2 和 3 组成的 sd 中抽取 3 个数字。然后将种子用于生成所有三个 3 数字的一行代码。

如果您希望使用 for 循环获得相同的结果,则需要以下代码:

> set.seed(1)
> rnorm(n = 1, 1, 1) 
[1] 0.3735462
> set.seed(1)
> rnorm(n = 1, 2, 2)
[1] 0.7470924
> set.seed(1)
> rnorm(n = 1, 3, 3)
[1] 1.120639

【讨论】:

  • 感谢您的回答,但我的目标是找到矢量化版本产生与 for 循环相同结果的方式。
【解决方案2】:

第一种方法

l <- {}
for(i in 1:3){
  set.seed(1)
  l[i] <- rnorm(n = 1, i, i)  
}
0.3735462 0.7470924 1.1206386

第二种方法

set.seed(1)
rnorm(n = 3, 1:3, 1:3)
0.3735462 2.3672866 0.4931142

您的问题是为什么这两种方法产生的结果不一样?

为了回答这个问题,我首先要说的是,这两种方法确实会产生一致的结果。现在让我们看看为什么伪随机生成的值不同。 最简单的方法是运行一个 for 循环来看看会发生什么:

sapply(1:3,function(x){set.seed(1);rnorm(x,x,x)})
[[1]]
[1] 0.3735462 #One number produced from mu=1 sd=1    
[[2]]
[1] 0.7470924 2.3672866 # Two numbers produced from mu=2 sd=2    
[[3]]
[1] 1.1206386 3.5509300 0.4931142  # Three numbers produced from mu=3 sd=3    

现在,如果您查看此列表,您会注意到 for 循环仅获取第一个数字,而第二个方法仅获取最后生成的数字。这就是数字不同的原因但最后,结果是一致的,因为正如您所看到的,两个数字都是由相同的均值和 sd 产生的

因此

 set.seed(1)
 rnorm(3,1:3,1:3)

is equivalent to

l <- {}
for(i in 1:3){
  set.seed(1)
  l[i] <- rnorm(n = i, i, i)[i]  
}
l
[1] 0.3735462 2.3672866 0.4931142
rnorm(3,1:3,1:3)
[1] 0.3735462 2.3672866 0.4931142

【讨论】:

  • 谢谢!它回答了我的问题。另外一条评论,如果我不想更改 for 循环(您稍微更改了它),也许您知道如何获得可重现的结果。如果我保持初始 for 循环,我如何使用矢量化表达式获得相同的数字。 (只是为了好奇)
  • 由于 for 循环给出了生成的第一个数字,而矢量化给出了最后一个生成的数字,因此无法在不扭曲 for 循环的情况下使 for 循环的值与矢量化值匹配我在上面做的方式。由于您也在处理随机数生成,因此您使用什么方法并不重要。两者都会给你正确的结论。只是向量化的方法会更快更高效
猜你喜欢
  • 2017-10-17
  • 1970-01-01
  • 2015-03-01
  • 1970-01-01
  • 2013-06-01
  • 1970-01-01
  • 2018-08-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多