2013-09-20 3 views
14

При генерации случайных чисел в R с использованием rnorm (или runif и т. Д.) Они редко имеют точное среднее значение и SD в качестве распределения, от которого они берутся. Есть ли простой один-два-лайнер, который делает это для меня? В качестве предварительного решения я создал эту функцию, но кажется, что она должна быть родной для R или некоторого пакета.Генерировать случайные числа с фиксированным средним значением и sd

# 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 

Поэтому я хочу, чтобы это то, что я поправляю анализ на смоделированных данных, прежде чем применить его к реальным данным. Это хорошо, потому что с имитированными данными я знаю точные свойства (средства, SD и т. Д.), И я избегаю инфляции p-value, потому что я делаю выводную статистику. Я спрашиваю, есть ли что-то простое, например, например.

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

Вы можете использовать функцию 'scale' для этого ... но разве это не иллюстрирует разницу между выборкой и статистикой населения? Поскольку ваш 'n' получает большие' sd (x) 'и' mean (x) 'будет приближаться к указанным вами значениям, но только в 20 образцах вы не можете ожидать идеального распространения ... – Justin

+3

Из любопытства, зачем вам это нужно? ? Я бы не ожидал, что образец будет иметь такое же среднее значение и sd, что и население. – Roland

+2

Думаю, у вас все в порядке. Я думаю, что это достаточно просто, что люди просто делают это так, когда им это нужно. 'MASS :: mvrnorm' имеет аналогичную функцию (но это несколько сложнее для многомерного случая, который, по-видимому, почему он встроен). Согласитесь с @Justin, что вы можете использовать масштаб mu + sigma * (rnorm (n)) 'как однострочный ... –

ответ

22

Поскольку вы просили однострочника:

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

Это улучшение функции, предложенной в предыдущем ответе, так что он соответствует потребности ФП о имеющих «фиксированный» аргумент ,

И еще в одной строке ;-)

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.