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
これが必要な理由は、シミュレーションデータの分析を実際のデータに適用する前に調整するためです。シミュレートされたデータでは正確なプロパティ(平均値、SDなど)がわかっているので、これは素晴らしいです。推論統計を行っているので、p値のインフレーションを避けています。私のような単純なものがあるかどうかを尋ねています。
rnorm(n=20, mean=5, sd=10, fixed=TRUE)
ワンライナーを求めたので:
rnorm2 <- function(n,mean,sd) { mean+sd*scale(rnorm(n)) }
r <- rnorm2(100,4,1)
mean(r) ## 4
sd(r) ## 1
これは、前の回答で提案された関数の改善であり、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
関数によって生成された属性を削除します。