[英]Generate random numbers in R satisfying constraints
I need help with a code to generate random numbers according to constraints.我需要代码帮助来根据约束生成随机数。 Specifically, I am trying to simulate random numbers ALFA and BETA from, respectively, a Normal and a Gamma distribution such that ALFA - BETA < 1.
具体来说,我试图分别从正态分布和 Gamma 分布模拟随机数 ALFA 和 BETA,使得 ALFA - BETA < 1。
Here is what I have written but it does not work at all.这是我写的,但它根本不起作用。
set.seed(42)
n <- 0
repeat {
n <- n + 1
a <- rnorm(1, 10, 2)
b <- rgamma(1, 8, 1)
d <- a - b
if (d < 1)
alfa[n] <- a
beta[n] <- b
l = length(alfa)
if (l == 10000) break
}
Due to vectorization, it will be faster to generate the numbers "all at once" rather than in a loop:由于矢量化,“一次”而不是循环生成数字会更快:
set.seed(42)
N = 1e5
a = rnorm(N, 10, 2)
b = rgamma(N, 8, 1)
d = a - b
alfa = a[d < 1]
beta = b[d < 1]
length(alfa)
# [1] 36436
This generated 100,000 candidates, 36,436 of which met your criteria.这产生了 100,000 名候选人,其中 36,436 名符合您的标准。 If you want to generate
n
samples, try setting N = 4 * n
and you'll probably generate more than enough, keep the first n
.如果要生成
n
样本,请尝试设置N = 4 * n
,您可能会生成足够多的样本,请保留第一个n
。
Your loop has 2 problems: (a) you need curly braces to enclose multiple lines after an if
statement.您的循环有 2 个问题:(a)您需要花括号在
if
语句之后括起多行。 (b) you are using n
as an attempt counter, but it should be a success counter. (b) 您使用
n
作为尝试计数器,但它应该是成功计数器。 As written, your loop will only stop if the 10000th attempt is a success.如前所述,只有在第 10000 次尝试成功时,您的循环才会停止。 Move
n <- n + 1
inside the if
statement to fix:在
if
语句中移动n <- n + 1
以修复:
set.seed(42)
n <- 0
alfa = numeric(0)
beta = numeric(0)
repeat {
a <- rnorm(1, 10, 2)
b <- rgamma(1, 8, 1)
d <- a - b
if (d < 1) {
n <- n + 1
alfa[n] <- a
beta[n] <- b
l = length(alfa)
if (l == 500) break
}
}
But the first way is better... due to "growing" alfa
and beta
in the loop, and generating numbers one at a time, this method takes longer to generate 500 numbers than the code above takes to generate 30,000.但是第一种方法更好......由于在循环中“增长”
alfa
和beta
,并且一次生成一个数字,这种方法生成 500 个数字比上面的代码生成 30,000 个需要更长的时间。
As commented by @Gregor Thomas, the failure of your attempt is due to the missing of curly braces to enclose the if
statement.正如@Gregor Thomas 评论的那样,您的尝试失败是由于缺少花括号来括住
if
语句。 If you would like to skip {}
for if
control, maybe you can try the code below如果您想跳过
{}
进行if
控制,也许您可以尝试下面的代码
set.seed(42)
r <- list()
repeat {
a <- rnorm(1, 10, 2)
b <- rgamma(1, 8, 1)
d <- a - b
if (d < 1) r[[length(r)+1]] <- cbind(alfa = a, beta = b)
if (length(r) == 100000) break
}
r <- do.call(rbind,r)
such that这样
> head(r)
alfa beta
[1,] 9.787751 12.210648
[2,] 9.810682 14.046190
[3,] 9.874572 11.499204
[4,] 6.473674 8.812951
[5,] 8.720010 8.799160
[6,] 11.409675 10.602608
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.