首页 > 解决方案 > 如何在 R 中生成具有条件的随机数?

问题描述

我想生成满足以下条件的 500 个不同的 a、b 和 c 组合

  1. a+ b+ c = 1 和
  2. a < b < c

这是生成随机数的基本示例,但是,我需要根据上述条件生成它。

Coeff = data.frame(a=runif(500, min = 0, max = 1),
b=runif(500, min = 0, max = 1),
c=runif(500, min = 0, max = 1))

标签: rdataframeif-statementrandomconditional-statements

解决方案


myrandom <- function(n) {
  m <- matrix(runif(3*n), ncol=3)
  m <- cbind(m, rowSums(m)) # rowSums is efficient
  t(apply(m, 1, function(a) sort(a[1:3] / a[4])))
}

示范:

set.seed(2)
(m <- myrandom(5))
#           [,1]      [,2]      [,3]
# [1,] 0.1099815 0.3287708 0.5612477
# [2,] 0.1206611 0.2231769 0.6561620
# [3,] 0.2645362 0.3509054 0.3845583
# [4,] 0.2057215 0.2213517 0.5729268
# [5,] 0.2134069 0.2896015 0.4969916
all(abs(rowSums(m) - 1) < 1e-8) # CONSTRAINT 1: a+b+c = 1
# [1] TRUE
all(apply(m, 1, diff) > 0)      # CONSTRAINT 2: a < b < c
# [1] TRUE

笔记:

  • 我对“总和为 1”的测试不仅仅是==1因为 IEEE-754 和R FAQ 7.31,这表明任何浮点测试都应该是不等式而不是相等性测试;如果您测试==1,您最终会发现似乎不满意的情况:

    set.seed(2)
    m <- myrandom(1e5)
    head(which(rowSums(m) != 1))
    # [1]  73 109 199 266 367 488
    m[73,]
    # [1] 0.05290744 0.24824770 0.69884486
    sum(m[73,])
    # [1] 1
    sum(m[73,]) == 1
    # [1] FALSE
    abs(sum(m[73,]) - 1) < 1e-15
    # [1] TRUE
    max(abs(rowSums(m) - 1))
    # [1] 1.110223e-16
    

推荐阅读