When generating random numbers in R using rnorm
(or runif
etc.), they seldom have the exact mean and SD as the distribution they are sampled from.
Since you asked for a one-liner:
rnorm2 <- function(n,mean,sd) { mean+sd*scale(rnorm(n)) }
r <- rnorm2(100,4,1)
mean(r) ## 4
sd(r) ## 1
This is an improvement of the function suggested in a previous answer so that it complies with the OP's need of having a "fixed" argument.
And still in one line ;-)
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
I chose to enter default values for every argument and add a as.numeric
step to get rid of the attributes generated by the scale
function.
The mvrnorm() function in the MASS package can do this.
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)