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

时间:2017-09-06 01:49:34

标签: r

respondingReddit AskScience处提出质疑,我在runif()的功能方面遇到了一些奇怪的问题。我试图统一采样从1到52的集合。我的第一个想法是使用runif():

as.integer(runif(n, min = 1, max = 52))

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

length(unique(as.integer(runif(1000000, 1, 52))))
[1] 51

就我的目的而言,我只是转向sample()

sample(52, n, replace = TRUE)

在runif()文档中说明:

  

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

我想知道为什么runif()以这种方式行事。它似乎应该能够产生极端的价值观。如果它试图统一生成样本,则从集合中。这是一个功能,为什么?

3 个答案:

答案 0 :(得分:13)

这确实是一个特色。 runif的{​​{3}}包含以下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;

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

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

此功能为C source code(从评论中可以看出0<u<1自动生成内置统一生成器,但对于用户提供的生成器可能不适用。)

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

答案 1 :(得分:3)

as.integer的作用类似于trunc。它将通过将给定值截断为0来形成整数。由于值不能超过52(see Ben's answer),它们将始终被截断为1到51之间的值。

您会在floor(或ceiling)中看到不同的结果。 请注意,您必须通过添加max来调整runif 1(如果是min,则调整ceiling)。同样请注意,在这种情况下,由于minmax都高于0,您可以将floor替换为trunc或{{1}也是。

as.integer

enter image description here

答案 2 :(得分:2)

as.integer(51.999)

  

51

这是因为as.integer如何工作。

如果要从离散分布中绘制,请使用样本。 runif不适用于离散分发。