20

rnorm を使用してデータをシミュレートしていますが、上限と下限を設定する必要があります。これを行う方法を知っている人はいますか?

コード:

rnorm(n = 10, mean = 39.74, sd = 25.09)

上限は 340、下限は 0 にする必要があります

SASコードをRコードに書き換えているので、この質問をしています。SASは使ったことがありません。次のコードを書き直そうとしています。

sim_sample(simtot=100000,seed=10004,lbound=0,ubound=340,round_y=0.01,round_m=0.01,round_sd=0.01,n=15,m=39.74,sd=25.11,mk=4)
4

6 に答える 6

13

観測を簡単に破棄する必要のない、独自の切り捨てられた通常のサンプラーを作成できます。

rtnorm <- function(n, mean, sd, a = -Inf, b = Inf){
    qnorm(runif(n, pnorm(a, mean, sd), pnorm(b, mean, sd)), mean, sd)
}
于 2013-10-13T21:46:31.377 に答える
10

このような?

mysamp <- function(n, m, s, lwr, upr, nnorm) {
  samp <- rnorm(nnorm, m, s)
  samp <- samp[samp >= lwr & samp <= upr]
  if (length(samp) >= n) {
    return(sample(samp, n))
  }  
  stop(simpleError("Not enough values to sample from. Try increasing nnorm."))
}

set.seed(42)
mysamp(n=10, m=39.74, s=25.09, lwr=0, upr=340, nnorm=1000)
#[1] 58.90437 38.72318 19.64453 20.24153 39.41130 12.80199 59.88558 30.88578 19.66092 32.46025

ただし、結果は正規分布ではなく、通常、指定した平均値と sd はありません (特に、制限が指定した平均値に対して対称でない場合)。

編集:

あなたのコメントによると、この SAS 関数を翻訳したいようです。私はSASユーザーではありませんが、これは多かれ少なかれ同じことをするはずです:

mysamp <- function(n, m, s, lwr, upr, rounding) {
  samp <- round(rnorm(n, m, s), rounding)
  samp[samp < lwr] <- lwr
  samp[samp > upr] <- upr
  samp
}

set.seed(8)
mysamp(n=10, m=39.74, s=25.09, lwr=0, upr=340, rounding=3)
#[1] 37.618 60.826 28.111 25.920 58.207 37.033 35.467 12.434  0.000 24.857

その後、 を使用replicateしてシミュレーションを実行できます。または、より高速なコードが必要な場合:

sim <- matrix(mysamp(n=10*10, m=39.74, s=25.09, lwr=0, upr=340, rounding=3), 10)
means <- colMeans(sim)
sds <- apply(sim, 2, sd)
于 2013-10-13T08:52:19.653 に答える
0

これは、同じ目的を達成するために私が書いた関数です。関数からの結果を正規化しrnorm、範囲に合うように調整します。

注:標準偏差と平均 (指定されている場合) は、正規化プロセス中に変更されます。

#' Creates a random normal distribution within the specified bounds.
#' 
#' WARNING: This function does not preserve the standard deviation or mean.
#' @param n The number of values to be generated
#' @param mean The mean of the distribution
#' @param sd The standard deviation of the distribution
#' @param lower The lower limit of the distribution
#' @param upper The upper limit of the distribution
rtnorm <- function(n, mean=NA, sd=1, lower=-1, upper=1){
  mean = ifelse(is.na(mean)|| mean < lower || mean > upper,
                mean(c(lower, upper)), mean)
  data <- rnorm(n, mean=m, sd=sd) # data

  if (!is.na(lower) && !is.na(upper)){ # adjust data to specified range
    drange <- range(data)           # data range
    irange <- range(lower, upper)   # input range
    data <- (data - drange[1])/(drange[2] - drange[1]) # normalize data (make it 0 to 1)
    data <- (data * (irange[2] - irange[1]))+irange[1] # adjust to specified range
  }
  return(data)
}
于 2015-02-22T18:45:31.590 に答える