生成具有固定均值和 sd 的随机数

Posted

技术标签:

【中文标题】生成具有固定均值和 sd 的随机数【英文标题】:Generate random numbers with fixed mean and sd 【发布时间】:2013-09-25 23:29:32 【问题描述】:

在 R 中使用 rnorm(或 runif 等)生成随机数时,它们很少具有精确的均值和 SD 作为它们的抽样分布。是否有任何简单的一两班轮可以为我做到这一点?作为初步解决方案,我创建了这个函数,但它似乎应该是 R 或某些包的原生函数。

# Draw sample from normal distribution with guaranteed fixed mean and sd
rnorm_fixed = function(n, mu=0, sigma=1) 
  x = rnorm(n)  # from standard normal distribution
  x = sigma * x / sd(x)  # scale to desired SD
  x = x - mean(x) + mu  # center around desired mean
  return(x)

举例说明:

x = rnorm(n=20, mean=5, sd=10)
mean(x)  # is e.g. 6.813...
sd(x)  # is e.g. 10.222...

x = rnorm_fixed(n=20, mean=5, sd=10)
mean(x)  # is 5
sd(x)  # is 10

我想要这个的原因是我在将模拟数据应用到真实数据之前调整了我对模拟数据的分析。这很好,因为通过模拟数据,我知道确切的属性(平均值、标准差等),并且我避免了 p 值膨胀,因为我正在做推论统计。我在问是否存在任何简单的东西,例如

rnorm(n=20, mean=5, sd=10, fixed=TRUE)

【问题讨论】:

您可以使用函数scale 来执行此操作...但这不正是说明样本统计和总体统计之间的差异吗?随着您的 n 变大,sd(x)mean(x) 将接近您提供的值,但只有 20 个样本,您不能指望完美分布... 出于好奇,您为什么需要它?我不希望样本与总体具有相同的均值和标准差。 我认为你做对了。我认为这很简单,人们只需在需要时就这样做。 MASS::mvrnorm 确实有一个类似的功能(但对于多变量情况来说它有点棘手,这可能是它内置的原因)。同意@Justin,您可以将mu+sigma*scale(rnorm(n)) 用作单行... 贾斯汀和罗兰:我在问题中添加了我的动机 :-) 这是因为我模拟数据并想知道它的属性!所以,是的,如果我想让它代表现实世界,这些约束会很奇怪。但我想要一个“完美的小世界”来玩耍,以便知道我是否做对了:-) 我通常只是创建一个样本并计算属性。 【参考方案1】:

既然你要求单线:

rnorm2 <- function(n,mean,sd)  mean+sd*scale(rnorm(n)) 
r <- rnorm2(100,4,1)
mean(r)  ## 4
sd(r)    ## 1

【讨论】:

从数学的角度来看,这是不稳定的吗?人们可以期望样本均值与从中抽取样本的总体等价,但不应期望随机数样本及其总体的标准差等价。中心极限定理:(X1+...+Xn)/n -> N(mean,StdDev.)=N(mu, sigma/sqrt(n))。因此,对我来说,为了数学的正确性,rnorm3 必须定义为 SD=sigma/sqrt(n)(sigma:std dev. of the population)和 m=mu。我想知道你对这个问题的考虑。那么,如果你也发现 rnorm3 需要按照 CLT 来定义,那么如何正确定义呢? 我想,我找到了我的问题的答案。在这里,在上面的代码中,因为我们从总体中抽取一个样本(而不是从总体中抽取许多样本)。因此,人们可能希望样本和总体的均值和 SD 均等值是正常的。【参考方案2】:

这是对先前答案中建议的函数的改进,以便它符合 OP 对“固定”参数的需求。

仍然在一行中;-)

rnorm. <- function(n=10, mean=0, sd=1, fixed=TRUE)  switch(fixed+1, rnorm(n, mean, sd), as.numeric(mean+sd*scale(rnorm(n)))) 
rnorm.() %>% c(mean(.), sd(.))
#### [1] 0 1
rnorm.(,,,F) %>% c(mean(.), sd(.))
#### [1] 0.1871827 0.8124567

我选择为每个参数输入默认值并添加一个as.numeric 步骤以摆脱scale 函数生成的属性。

【讨论】:

【参考方案3】:

MASS 包中的 mvrnorm() 函数可以做到这一点。

library(MASS)
#empirical=T forces mean and sd to be exact
x <- mvrnorm(n=20, mu=5, Sigma=10^2, empirical=T)
mean(x)
sd(x)
#empirical=F does not impose this constraint
x <- mvrnorm(n=20, mu=5, Sigma=10^2, empirical=F
mean(x)
sd(x)

【讨论】:

以上是关于生成具有固定均值和 sd 的随机数的主要内容,如果未能解决你的问题,请参考以下文章

具有给定均值和标准差的正随机数生成

如何在 R 中生成给定、均值、SD、偏斜和峰度的分布?

固定密度为 1s 的伪随机数生成器

如何使用 JavaScript 生成一个固定长度的随机数?

Java改变生成随机数的平均值(改变生成随机数的概率)

Java改变生成随机数的平均值(改变生成随机数的概率)