【问题标题】:how to generate random numbers with conditons impose in R?如何在 R 中生成具有条件的随机数?
【发布时间】:2019-11-30 21:04:25
【问题描述】:

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

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

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

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

【问题讨论】:

  • 你关心抽样分布是什么吗?可以抽取随机数,然后过滤掉不符合条件的组合
  • 不是真的——我不关心分布。我想要的只是生成的样本应该满足这两个标准。

标签: r dataframe if-statement random conditional-statements


【解决方案1】:
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

注意:

  • 由于 IEEE-754 和 R FAQ 7.31,我对“总和为 1”的测试不仅仅是 ==1,这表明任何浮点测试都应该是不等式而不是相等性测试;如果您测试==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
    

【讨论】:

  • 是的,我只是在测试代码,发现有没有满足条件==1的地方。有没有办法解决这个问题并创建只满足定义条件的样本? ` head(which(rowSums(m) != 1)) [1] 218 366 435 463 500'
  • 正如我在答案中解释的那样,使用浮点时的“条件 == 1”是一个根本有缺陷的测试。真的,我不只是在这里吹烟。 R FAQ 7.31 的存在是有原因的,坦率地说,我认为它低估了浮点比较的原则。要么执行不等式测试(有一定的容忍度,正如我演示的那样),要么解决 IEEE-754 问题(并发布它!)。我在这个样本中的最大偏差是1.110223e-16,我认为这已经足够了。
  • 如果您阅读了.Machine 特殊变量,它将其double.eps 组件定义为“最小正浮点数'x',使得'1 + x != 1 '".在我的 64 位 win10 R-3.5.3 上,这是2.220446e-16。有趣的是,max(abs(rowSums(m) - 1)) 是 1.110223e-16,但 (max(abs(rowSums(m) - 1)) + 1) == 1 是真的......所以当你得到这么小的东西时,你真的需要不同的数据结构和基本运算符。
  • 感谢@r2evans,这真的很有帮助。我正在尝试开发一个降雨径流模型,并且实际上生成了这些系数以将其传递给一个方程(参见此处:stackoverflow.com/questions/57152506/…)。我想保留给我最高 R 平方值的系数。那里的任何评论将不胜感激。
  • 在解决我的问题时,我从你那里学到了一些新的 R 函数-谢谢。
【解决方案2】:

我想指出,任何分布规律(均匀分布、高斯分布、指数分布……)都会产生符合您条件的数字 a、b 和 c,只要您对其进行标准化和排序,所以应该有一些领域知识比另一个更喜欢。

作为替代方案,我建议使用Dirichlet distribution 生成自然满足您的第一个条件的数字:a+b+c=1。我相信它也适用于降雨建模 (https://arxiv.org/pdf/1801.02962.pdf)

library(MCMCpack)
abc <- rdirichlet(n, c(1,1,1))
sum(abc) # should output n

您可以改变幂律值来塑造数据,当然,还可以对它们进行排序以满足您的第二个条件。在许多情况下,如果模型使用 Dirichlet(Dirichlet 在贝叶斯方法中的多项式是先验的,f.e.),很容易争论您的模型行为

【讨论】:

  • 感谢您提供更多见解。在我的情况下,我并不真正关心使用特定的分布(任何分布都可以)-我正在生成一些数字(在我的情况下是统一的)。我正在尝试解决这里提到的问题stackoverflow.com/questions/57152506/…,老实说,我仍在努力完成它。如果您对解决该问题有任何建议,请告诉我。再次感谢您。
  • @Hydrologist I am generating some number (which in my case is uniform)。不,它们不统一,这就是问题所在,它们的 U_i/Sum(U_i) 分布很奇怪,据我所知,它没有名称,也没有属性。另一方面,狄利克雷在每一本关于概率/统计的书中都提到过。我会看看你的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-24
  • 2015-08-18
  • 2016-09-24
  • 1970-01-01
  • 2013-06-01
  • 1970-01-01
  • 2018-12-11
相关资源
最近更新 更多