1

最初の列(experiment.id)で構成されるデータフレームがあり、残りの列はこの実験IDに関連付けられた値です。各行は一意の実験IDです。私のデータフレームには、10⁴-10⁵のオーダーの列があります。

data.frame(experiment.id=1:100, v1=rnorm(100,1,2),v2=rnorm(100,-1,2) )

このデータフレームは、私のサンプルスペースのソースです。私がやりたいのは、一意のexperiment.id(行)ごとに、このIDに関連付けられた値v1、v2、....、v10000の1つをランダムにサンプリングして(置換して)、サンプルs1を作成することです。各サンプルs1には、すべての実験IDが表示されます。

最終的には、10⁴のサンプル、s1、s2、....、s10⁴を実行して、統計を計算したいと思います。

このサンプリングプロセスを実行するための(計算上)最も効率的な方法は何でしょうか。forループはできるだけ避けたいと思います。

更新: サンプリングだけでなく、サンプルの保存についての私の質問。私の本当の質問は、上記以外のより速い方法があるかどうかだと思います

d<-data.frame(experiment.id=1:1000, replicate (10000,rnorm(1000,100,2)) )
results<-data.frame(d$experiment.id,replicate(n=10000,apply(d[,2:10001],1,function(x){sample(x,size=1,replace=T)})))
4

3 に答える 3

3

これは、列の1つ(最初の列を除く)を選択する式です。最初の列はコピーされません。別のステップとして指定する必要があります。

データフレームの場合d

d[matrix(c(seq(nrow(d)), sample(ncol(d)-1, nrow(d), replace=TRUE)+1), ncol=2)]

これは1つのサンプルです。サンプルを取得するにNは、(ジョンの答えのように)選択を乗算するだけです。

mm <- matrix(c(rep(seq(nrow(d)), N), sample(ncol(d)-1, nrow(d)*N, replace=TRUE)+1), ncol=2)

result <- matrix(d[mm], ncol=N)

しかし、メモリの問題が発生します。

于 2012-12-28T15:25:11.850 に答える
2

ループすることなく行うことができます。最初の列の後の列を行列に変換すると、行列を[行、列]として、または基になるベクトルとして順番にアドレス指定できるため、これは簡単になります。

mat <- as.matrix(datf[,-1])
nr <- nrow(mat); nc <- ncol(mat)
sel <- sample( 1:nc, nr, replace = TRUE )
sel <- sel + ((1:nr)-1) * nc
x <- t(mat)[sel]
seldatf <- data.frame( datf[,1], x = x )

さて、たくさんのサンプルを取得するには、同じロジックを乗算するだけで非常に簡単です。

ns <- 10 # number of samples / row
sel <- sample(1:nc, nr * ns, replace = TRUE )
sel <- sel + rep(((1:nr)-1) * nc, each = ns)
x <- t(mat)[sel]
seldatf <- cbind( datf[,1],  data.frame(matrix(x, ncol = ns, byrow = TRUE)) )

設定しようns <- 1e5としていて、行がたくさんある場合は、非常に大きなデータフレームになる可能性があります。メモリ不足を監視する必要がある場合があります。読みやすさの理由から、少し不必要なコピーをします。大量のメモリを使用すると、実行中の他のプログラムをスワップアウトするため、メモリと速度のためにそれを排除できます。それは遅いです。x、mat、さらにはselを割り当てて保存する必要はありません。そうしないと、可能な限り最速の答えが得られます。

于 2012-12-28T15:31:04.100 に答える
2

最短で最も読みやすいIMHOはまだ使用されていますが、ベクトル化されapplyた事実をうまく利用しています。sample

results <- data.frame(experiment.id = d$experiment.id,
                      t(apply(d[, -1], 1, sample, 10000, replace = TRUE)))

必要な3秒が遅すぎる場合は、マトリックスインデックスを使用することをお勧めします。

于 2012-12-28T16:33:05.293 に答える