我想生成一个范围为 [1, 3] 的正态分布随机变量。
具体来说,我尝试了以下 R 代码:
x1 <- runif(1, 2)
x2 <- rnorm(0, 1)
V <- 1 + x1 + x2
然后,
V
服从正态分布(以x1
为条件)并且大致集中在[1, 3]上。
但是,我想让
V
具有范围 [1, 3]。也就是说,所有元素都应该在 [1, 3] 中,而不是粗略地在 [1, 3] 中:
min(V)
[1] 1
max(V)
[1] 3
我不知道该怎么办。 这个任务有技巧吗?
由于任何正态分布的支持都是整个实数轴,因此获得您想要的结果的唯一方法是抽取样本,然后将其归一化到您指定的范围内。正如 r2evans 指出的那样,任何此类方法都存在理论上的问题。然而,它的一个简单实现是
rnorm_limits <- function(n, min = 1, max = 3) {
x <- rnorm(n)
x <- (max - min) * x/diff(range(x))
return(x - min(x) + min)
}
测试,我们有:
set.seed(1)
hist(rnorm_limits(100))
当然,范围将与指定的完全一致:
range(rnorm_limits(100))
#> [1] 1 3
您必须将范围表示为您希望覆盖的正态分布面积的百分比。 100% 的面积始终会产生从 -无穷大到 +无穷大的范围。因此,您必须缩小要覆盖在 [1, 3] 之间的正态分布区域。假设您希望 99% 的面积在 1 到 3 之间。
您必须使用
sd
参数为 rnorm()
提供标准差,它以 99% 的面积在 1 到 3 之间的方式定义正态分布。
如何计算具体的标准差? 我们可以使用
qnorm()
来获取某个区域的极限值。该区域的范围从 -无穷大到 p
。当我们输入 p = 0.005
时,我们会说:给我 x
值,其左侧为分布的 0.05%。
由于正态分布是对称的,我们通过将剩余部分减半 100% = 1 % 的 99% 来确定 p。我们将 1% 分成两半并说:0.5% 应低于 1,0.5% 应高于 3。
剩下的就是将我们的分布平均值提供给
qnorm()
。它应该是给定范围的中心。在你的例子中,这是 2。
所以我们知道
qnorm(p = 0.005, mean = 2, sd = ???)
的期望结果:它应该是1。我们必须以结果为1的方式设置sd
。
我通过反复试验做到了这一点,接近 1 并达到了这一点:
qnorm(0.005, mean = 2, sd = 0.388223)
#> 1.000004
那么,反过来:
rnorm(mean = 2, sd = 0.388223, n = 100)
应该给你随机值,其中 ~99% 落在范围 [1, 3] 之间。