The quickest way I can think of is to take advantage of the vectorisation built-in to rnorm
. Both the mean
and sd
arguments are vectorised, however you can only supply a single integer for the number of draws. If you supply a vector to the mean
and sd
arguments, R will cycle through them until it has completed the required number of draws. Therefore, just make the argument n
to rnorm
a multiple of the length of your mean
vector. The multiplier will be the number of replicates for each row of your data.frame. In the function below this is n
.
I can't think of a factor way than using base::rnorm
on its own.
Worked example
#example data
df <- data.frame(country=c("a", "b", "c"),
mean=c(1, 10, 100),
sd=c(1, 2, 10))
#function which returns a matrix, and takes column vectors as arguments for mean and sd
normv <- function( n , mean , sd ){
out <- rnorm( n*length(mean) , mean = mean , sd = sd )
return( matrix( out , , ncol = n , byrow = FALSE ) )
}
#reproducible result (note order of magnitude of rows and input sample data)
set.seed(1)
normv( 5 , df$mean , df$sd )
# [,1] [,2] [,3] [,4] [,5]
#[1,] 0.3735462 2.595281 1.487429 0.6946116 0.3787594
#[2,] 10.3672866 10.659016 11.476649 13.0235623 5.5706002
#[3,] 91.6437139 91.795316 105.757814 103.8984324 111.2493092