创建条件随机序列

时间:2017-09-14 18:22:25

标签: r

我想在特定条件下为变量a,b,c,d,e和f创建长度为6000的随机序列。

我想从每个序列的10到40之间的离散均匀分布中随机抽取,但是在以下条件下:

a = f < (a+b)/2 < e < c < b < d

有谁知道我会如何编码?

3 个答案:

答案 0 :(得分:2)

条件有点特别。在满足条件之前绘制随机向量的命中和未命中方法可以起作用(尽管可能不是最佳的)。类似的东西:

randvect <- function(){
  v <- sample(10:40,5)
  while(any(c(v[1] >= v[2],
              mean(v[1:2]) >= v[5],
              v[5] >= v[3],
              v[3] >= v[2],
              v[2] >= v[4]))){
    v <- sample(10:40,5)
  }
  v
}

例如,

> randvect()
[1] 16 26 25 36 23

(我不打算使用f,因为它与a相同。

获得6000:

vects <- replicate(6000,randvect()) 

在命中和未命中的所有失误中,在我的机器上评估大约需要30秒。

答案 1 :(得分:0)

这个问题并没有很好地定义,因为有不同的实现导致不同的分布。例如,采取条件b = d。后者是最自然的解释,但计算上最昂贵。您可以通过随机选择b和d来改进它,然后如果b> d,然后切换b和d。我认为这个逻辑可以扩展到e,c,b,d:随机选择10到40之间的四个数字,然后指定e为最小,c为第二个最小等。我认为这将产生与“抛弃”方法,但我不确定。所以要获得e,c,b和d:

numbers = sort(sample(10:40,4,replace = TRUE))
e = numbers[1]
c = numbers[2]
b = numbers[3]
d = numbers[4]

然而,我仍在考虑如何处理a。

答案 2 :(得分:0)

John Coleman的答案将会到达那里,并且可能是一种更好的随机抽样方式,但可能需要很长时间,具体取决于您的允许空间。

确定允许空间的另一个选项,以及以。

开头的示例
  • a必须介于10到34之间(为e,c,b和d留出空间)
  • a和b的平均值必须=&lt; (b-2)和&lt;这意味着b必须是5或大于a,小于39
    • a + 4 < b < min((37 * 2) - a, 39)

其余的更直接一点。这些可以包装成一个函数。

我将更多地使用data.table来查看最后的结果。此外,我正在使用resample中描述的函数help(sample)来处理只有一个值要采样的情况。

library(data.table)

resample <- function(x, ...) x[sample.int(length(x), ...)]

funky <- function() {

  a <- resample(10:34, 1)
  f <- a
  b <- resample((a + 5):min(((37 * 2) - a + 1), 39), 1)
  e <- resample(ceiling((a+b)/2 + 0.1):min(38, b - 2), 1)
  c <- resample((e + 1):(b - 1), 1)
  d <- resample((b + 1):40, 1)

  c(a, b, c, d, e, f)

}

通过反复试验发现的一些问题。在e中,添加0.1,以便如果平均值当前是整数,则增加1,但如果值为X.5,则将向上舍入为X + 1.

dat <- data.table(t(replicate(10000, funky())))
setnames(dat, c("a", "b", "c", "d", "e", "f"))

以下内容将返回原始问题中未通过测试的所有行。使用10k样本进行一些迭代并且看起来不像任何东西都失败了。

dat[!(a == f &  
        f < ((a + b) / 2) & 
        ((a + b) / 2) < e &
        e < c &
        c < b &
        b < d)]