为什么runif()不能预测区间最大值?

use*_*737 11 r

回答了在Reddit AskScience上提出的问题,我发现了一些关于功能的奇怪的东西runif().我试图统一采样从1到52的集合.我的第一个想法是使用runif():

as.integer(runif(n, min = 1, max = 52))
Run Code Online (Sandbox Code Playgroud)

但是,我发现该操作从未产生52的值.例如:

length(unique(as.integer(runif(1000000, 1, 52))))
[1] 51
Run Code Online (Sandbox Code Playgroud)

为了我的目的,我转而sample()改为:

sample(52, n, replace = TRUE)
Run Code Online (Sandbox Code Playgroud)

在runif()文档中,它指出:

runif不会生成任何一个极值,除非max = min或max-min与min相比较小,特别是对于默认参数.

我想知道为什么runif()这样做.如果它试图统一生成样本,它似乎应该能够从集合中产生"极值".这是一个功能,为什么?

Ben*_*ker 13

这确实是一个特色.的C源代码runif包含以下的C代码:

/* This is true of all builtin generators, but protect against
       user-supplied ones */
    do {u = unif_rand();} while (u <= 0 || u >= 1);
return a + (b - a) * u;
Run Code Online (Sandbox Code Playgroud)

这意味着unif_rand() 可以返回0或1,但runif()设计为跳过那些(不太可能)的情况.

我的猜测是,这样做是为了保护在边缘情况下失败的用户代码(值恰好在范围的边界上).

这个功能是由Brian Ripley于2006年9月19日实现的(从评论来看,它似乎0<u<1是内置统一生成器的自动生成,但对于用户提供的生成器可能不是这样).

sample(1:52,size=n,replace=TRUE) 是实现目标的惯用方法(虽然不一定是最有效的).