在一定范围内从分布中抽取随机数

时间:2015-09-29 21:48:19

标签: r random distribution

我想从一系列发行版中绘制一些随机变量。但是,返回的值必须不高于某个阈值。 假设我想使用伽马分布,阈值为10,我需要n = 100个随机数。我现在想要0到10之间的100个随机数。(比如说比例和形状是1。)

获得100个随机变量显然很容易......

rgamma(100, shape = 1, rate = 1)

但是如何实现这些值的范围从0到100?

修改 使我的问题更清楚。绘制的1​​00个值应该在0和10之间缩放。因此,最高绘制值为10,最低为0.对不起,如果不清楚...

编辑No2 为我需要的随机数添加一些上下文:我想绘制遵循某些分布的“系统修复时间”。然而,在系统模拟中,存在二维的修复概率,即“简单”(即短修复时间)和“复杂”(即长修复时间)。我现在需要一个提供“短修复时间”的功能和一个提供“长修复时间”的功能。阈值将是短修复时间和长修复时间之间的区别。再次,我希望这使我的问题更加清晰。

3 个答案:

答案 0 :(得分:2)

伽玛分布无法做到这一点。 分布的支持决定了从中提取的样本数据的范围。 由于伽玛分布的支持是(0,inf),这是不可能的。(见https://en.wikipedia.org/wiki/Gamma_distribution)。

如果你真的想要一个伽玛分布采用拒绝抽样方法,正如亚历克斯雷诺兹建议的那样。

否则寻找具有有界/有限支持的分布(见https://en.wikipedia.org/wiki/List_of_probability_distributions
例如均匀或二项式

答案 1 :(得分:1)

好吧,用拒绝,未经测试的代码填充向量

v <- rep(-1.0, 100)
k <- 1
while (TRUE) {
    q <- rgamma(1, shape=1, rate=1)
    if (q > 0.0 && q < 100) {
        v[k] <- q
        k<-k+1
        if (k>100)
            break
    }
}

答案 2 :(得分:0)

我不确定你是否可以保留原始版本的属性,强加其他条件......但是这样的事情可以完成这项工作:

Filter(function(x) x < 10, rgamma(1000,1,1))[1:100]

对于缩放 - 要小心,结果将不会遵循原始分发(但是没有办法做到,正如其他答案所指出的那样):

# rescale numeric vector into (0, 1) interval
# clip everything outside the range 
rescale <- function(vec, lims=range(vec), clip=c(0, 1)) {
  # find the coeficients of transforming linear equation
  # that maps the lims range to (0, 1)
  slope <- (1 - 0) / (lims[2] - lims[1])
  intercept <- - slope * lims[1]

  xformed <- slope * vec + intercept

  # do the clipping
  xformed[xformed < 0] <- clip[1]
  xformed[xformed > 1] <- clip[2]

  xformed
}

# this is the requested data
10  * rescale(rgamma(100,1,1))