9

同じ分布から来ていると思われる一連の数値があるとします。

set.seed(20130613)
x <- rcauchy(10)

同じ未知の分布からランダムに数値を生成する関数が欲しいです。私が考えた 1 つのアプローチは、densityオブジェクトを作成し、そこから CDF を取得し、一様確率変数の逆 CDF を取得することです(ウィキペディアを参照)

den <- density(x)

#' Generate n random numbers from density() object
#' 
#' @param n The total random numbers to generate
#' @param den The density object from which to generate random numbers
rden <- function(n, den)
{
        diffs <- diff(den$x)
        # Making sure we have equal increments
        stopifnot(all(abs(diff(den$x) - mean(diff(den$x))) < 1e-9))
        total <- sum(den$y)
        den$y <- den$y / total
        ydistr <- cumsum(den$y)
        yunif <- runif(n)
        indices <- sapply(yunif, function(y) min(which(ydistr > y)))
        x <- den$x[indices]

        return(x)
}

rden(1, den)
## [1] -0.1854121

私の質問は次のとおりです。

  1. 密度オブジェクトから乱数を生成するより良い (または R に組み込まれた) 方法はありますか?
  2. 一連の数値から乱数を生成する方法に関する他のアイデアはありますか (以外にsample)?
4

3 に答える 3

12

密度推定からデータを生成するには、元のデータ ポイントの 1 つをランダムに選択し、密度推定からのカーネルに基づいてランダムな「エラー」ピースを追加します。デフォルトの「ガウス」では、これは、元のベクトルを取得し、平均 0 で sd が使用帯域幅に等しいランダムな法線を追加します。

den <- density(x)

N <- 1000
newx <- sample(x, N, replace=TRUE) + rnorm(N, 0, den$bw)

logspline別のオプションは、パッケージの関数を使用して密度を適合させlogspline(密度を推定する別の方法を使用します)、rlogsplineそのパッケージの関数を使用して、推定された密度から新しいデータを生成することです。

于 2013-06-13T16:22:14.713 に答える
2

既存の数字のプールから値を引き出すことだけが必要な場合は、それsampleが道です。
推定された基になる分布から描画する場合は、 を使用しdensity、それを推定分布に当てはめて必要な係数 (平均、標準偏差など) を取得し、適切なR分布関数を使用します。

それを超えて、任意の分布に従って「選択的に」サンプリングする方法については、C の数値レシピの Chapter7.3 (「拒否法」) を参照してください。コードは単純なので、簡単に に変換できますR 。私の賭けは、誰かがすでにそうしていて、これよりも良い答えを投稿することです.

于 2013-06-13T13:30:40.857 に答える