[英]Exponential distribution in R
我想模拟来自exp(1)分布的一些数据,但是它们必须> 0.5。所以我使用了while循环,但是它似乎不像我想要的那样工作。在此先感谢您的回答!
x1<-c()
w<-rexp(1)
while (length(x1) < 100) {
if (w > 0.5) {
x1<- w }
else {
w<-rexp(1)
}
}
1)问题中的代码存在以下问题:
我们在每次迭代中都需要一个新的随机变量,但如果if
条件为FALSE,它只会生成新的随机变量
x1
被反复覆盖而不是扩展
尽管while
可以使用repeat
但repeat
似乎更好,因为在末尾进行测试比在开始时进行测试更合适
我们可以这样解决:
x1 <- c()
repeat {
w <- rexp(1)
if (w > 0.5) {
x1 <- c(x1, w)
if (length(x1) == 100) break
}
}
1a)以下是一个变体。 请注意, if
没有else
分支,则条件为FALSE的if评估为NULL,因此,如果在标记##的行上条件为FALSE,则没有任何内容串联到x1
。
x1 <- c()
repeat {
w <- rexp(1)
x1 <- c(x1, if (w > 0.5) w) ##
if (length(x1) == 100) break
}
2)或者,这会生成200个指数随机变量,仅保留那些大于0.5的变量。 如果生成的数量少于100,请重复。 最后,它从最后一个生成的批次中提取前100个。 我们选择了200,使其足够大,以便在大多数运行中仅需要循环的一次迭代。
repeat {
r <- rexp(200)
r <- r[r > 0.5]
if (length(r) >= 100) break
}
r <- head(r, 100)
备选方案(2)实际上比(1)或(1a)更快,因为它的矢量化程度更高。 尽管它比其他解决方案丢掉了更多的指数随机变量。
我建议不要使用while
(或任何其他接受/拒绝)循环。 而是使用truncdist
的方法:
# Sample 1000 observations from a truncated exponential
library(truncdist);
x <- rtrunc(1000, spec = "exp", a = 0.5);
# Plot
library(ggplot2);
ggplot(data.frame(x = x), aes(x)) + geom_histogram(bins = 50) + xlim(0, 10);
使用逆变换采样实现采样器也很简单,它可以从截断的指数分布中抽取采样,从而避免在循环中拒绝采样。 这将是一种比任何基于接受/拒绝的采样方法更为有效的方法,并且在您的情况下效果特别好,因为存在截断指数cdf的封闭形式。 例如,请参阅此帖子以获取更多详细信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.