26

在使用rnorm(或runif等)在 R 中生成随机数时,它们很少具有精确的均值和 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)
4

3 回答 3

40

既然您要求单线:

rnorm2 <- function(n,mean,sd) { mean+sd*scale(rnorm(n)) }
r <- rnorm2(100,4,1)
mean(r)  ## 4
sd(r)    ## 1
于 2013-09-20T16:10:34.523 回答
3

这是对先前答案中建议的函数的改进,因此它符合 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函数生成的属性。

于 2016-09-22T20:46:35.083 回答
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)
于 2020-07-21T13:37:09.860 回答