我已经找到了我会考虑的不规则行为(但我希望有一个简单的解释)R在结合使用rbinom()何时使用种子prob=0.5.一般想法:对我来说,如果我设置种子,运行rbinom()一次(即进行一个随机过程),尽管prob设置了什么值,随机种子应该改变一个增量.然后,如果我再次将种子设置为相同的值,并运行另一个随机过程(例如,rbinom()再次,但可能具有不同的值prob),则种子应该再次更改为与之前的单个随机过程相同的值.
R只要我rbinom()和任何人一起使用,我发现确实如此prob!=0.5.这是一个例子:
比较种子向量,.Random.seed对于除0.5之外的两个概率:
set.seed(234908)
x <- rbinom(n=1,size=60,prob=0.4)
temp1 <- .Random.seed
set.seed(234908)
x <- rbinom(n=1,size=60,prob=0.3)
temp2 <- .Random.seed
any(temp1!=temp2)
> [1] FALSE
Run Code Online (Sandbox Code Playgroud)
比较种子向量,.Random.seed对于prob = 0.5与prob!= 0.5:
set.seed(234908)
x <- rbinom(n=1,size=60,prob=0.5)
temp1 <- .Random.seed
set.seed(234908)
x <- rbinom(n=1,size=60,prob=0.3)
temp2 <- .Random.seed
any(temp1!=temp2)
> [1] TRUE
temp1==temp2
> [1] TRUE FALSE TRUE TRUE TRUE TRUE TRUE
> [8] TRUE TRUE TRUE TRUE TRUE TRUE TRUE
...
Run Code Online (Sandbox Code Playgroud)
我已经找到了这个prob=0.5与集合{0.1,0.2,...,0.9}中所有其他概率的所有比较.类似地,如果我比较prob除了0.5之外的{0.1,0.2,...,0.9}的任何值,则.Random.seed向量总是逐个元素相等.这些事实也适用于奇数或甚至size内部rbinom().
让它更奇怪(我道歉这有点令人费解 - 它与我的函数编写方式有关),当我使用在向量中保存为元素的概率时,如果0.5是第一个元素,我有同样的问题,但不是第二.以下是此案例的示例:
第一种情况:0.5是向量中引用的第一个概率
set.seed(234908)
MNAR <- c(0.5,0.3)
x <- rbinom(n=1,size=60,prob=MNAR[1])
y <- rbinom(n=1,size=50,prob=MNAR[2])
temp1 <- .Random.seed
set.seed(234908)
MNAR <- c(0.1,0.3)
x <- rbinom(n=1,size=60,prob=MNAR[1])
y <- rbinom(n=1,size=50,prob=MNAR[2])
temp2 <- .Random.seed
any(temp1!=temp2)
> [1] TRUE
any(temp1!=temp2)
> [1] TRUE FALSE TRUE TRUE TRUE TRUE TRUE
> [8] TRUE TRUE TRUE TRUE TRUE TRUE TRUE
Run Code Online (Sandbox Code Playgroud)
第二种情况:0.5是向量中引用的第二个概率
set.seed(234908)
MNAR <- c(0.3,0.5)
x <- rbinom(n=1,size=60,prob=MNAR[1])
y <- rbinom(n=1,size=50,prob=MNAR[2])
temp1 <- .Random.seed
set.seed(234908)
MNAR <- c(0.1,0.3)
x <- rbinom(n=1,size=60,prob=MNAR[1])
y <- rbinom(n=1,size=50,prob=MNAR[2])
temp2 <- .Random.seed
any(temp1!=temp2)
> [1] FALSE
Run Code Online (Sandbox Code Playgroud)
再次,我发现,尽管使用的数值prob和size,这种模式成立.任何人都可以向我解释这个谜吗?这引起了相当大的问题,因为应该相同的结果会有所不同,因为种子由于某种原因prob=0.5而在不同的情况下使用/计算的时间不同.
flo*_*del 40
让我们把我们的评论转化为答案.感谢Ben Bolker让我们走上正确的轨道,并附上代码链接:https://svn.r-project.org/R/trunk/src/nmath/rbinom.c以及追踪unif_rand()调用位置的建议.
快速扫描,似乎代码分为两部分,由注释分隔:
/*-------------------------- np = n*p >= 30 : ------------------- */
Run Code Online (Sandbox Code Playgroud)
和
/*---------------------- np = n*p < 30 : ------------------------- */
Run Code Online (Sandbox Code Playgroud)
在其中每个中,调用的次数unif_rand不一样(两个与一个).
因此对于给定的size(n),您的随机种子可能会根据prob(p)的值来结束处于不同的状态:是否size * prob >= 30.
考虑到这一点,您在示例中获得的所有结果现在都应该有意义:
# these end up in the same state
rbinom(n=1,size=60,prob=0.4) # => np < 30
rbinom(n=1,size=60,prob=0.3) # => np < 30
# these don't
rbinom(n=1,size=60,prob=0.5) # => np >= 30
rbinom(n=1,size=60,prob=0.3) # => np < 30
# these don't
{rbinom(n=1,size=60,prob=0.5) # np >= 30
rbinom(n=1,size=50,prob=0.3)} # np < 30
{rbinom(n=1,size=60,prob=0.1) # np < 30
rbinom(n=1,size=50,prob=0.3)} # np < 30
# these do
{rbinom(n=1,size=60,prob=0.3) # np < 30
rbinom(n=1,size=50,prob=0.5)} # np < 30
{rbinom(n=1,size=60,prob=0.1) # np < 30
rbinom(n=1,size=50,prob=0.3)} # np < 30
Run Code Online (Sandbox Code Playgroud)
Bri*_*ggs 15
我将在这个问题上采取逆向立场,并声称期望不合适,文档也不支持.该文件没有声明.Random.seed通过调用可以预期哪些副作用(特别是)rbinom,或者在各种情况下这些副作用可能会或可能不同.
rbinom有三个参数:n,size和prob.你的期望是,调用之前设置一个随机种子rbinom,.Random.seed将调用后同rbinom一个给定n和任何的价值size和prob(或可能的任何有限值size和prob).你当然意识到不同的价值会有所不同n.rbinom并不保证或暗示.
在不知道函数内部的情况下,这是不可知的; 因为对方的回答表明,基于对产品的算法是不同的size和prob.并且内部可能会发生变化,因此这些具体细节可能会发生变化.
至少,在这种情况下,.Random.seed在每次调用之后,rbinom结果都是相同的 n,size 并且 prob.我可以构建一个甚至不是这样的病理函数:
seedtweak <- function() {
if(floor(as.POSIXlt(Sys.time())$sec * 10) %% 2) {
runif(1)
}
invisible(NULL)
}
Run Code Online (Sandbox Code Playgroud)
基本上,该函数查看第二个时间的十分之一是奇数还是甚至决定是否绘制随机数.运行此功能.Random.seed可能会也可能不会更改:
rs <- replicate(10, {
set.seed(123)
seedtweak()
.Random.seed
})
all(apply(rs, 1, function(x) Reduce(`==`, x)))
Run Code Online (Sandbox Code Playgroud)
您可以(应该?)希望的最好的是,一组给定的所有输入/参数相同的代码(包括种子)将始终给出相同的结果.当只有大多数(或仅一些)参数相同时,期望相同的结果是不切合实际的,除非所有被调用的函数都做出这些保证.