0

私はRに不慣れではありませんが、Rで関数を記述し、コマンドを設定された回数繰り返し、各反復の結果をベクトルに格納する関数を記述しようとするのは初めてです。この場合、サイズが「m」の順序付けられたベクトル(これを「デッキ」と呼んでいます)が「n」回シャッフルされています。デッキがシャッフルされるたびに、元のデッキとシャッフルされたデッキを比較し、元のデッキとシャッフルされたデッキが同じ場所にある回数を数えたいと思います。一致するものがある場合は「1」を格納し、一致するものがまったくない場合は「0」を格納します。

理論から、一致しない割合は1/eに収束する必要があることがわかっています。

これは、数時間の試行錯誤の末に私が持っているものですが、単一の要素を持つベクトルしか生成しません。比較の反復を保持できないようです。以下の私のコードでは、「w」はシャッフルされた各比較を格納するベクトルです。

shuffle = function(m,n){
    deck=1:m
    repeat {        
    x=deck - sample(deck,size=length(deck))
    w=ifelse(length(x[x==0])>0, 1,0)
    if(length(w)==n)
    break
    }
return(w)
}

何かご意見は?

4

3 に答える 3

3

編集:より効率的な機能

shuffle  <- function(m,n) {
  deck <- 1:m
  w <- numeric(n)
  for(i in 1:n){
    x <- sample(deck, m)
    w[i] <- 1*!(sum(deck==x)==0)
  }
  return(w)
}

そしてあなたが言ったように

1-sum(shuffle(20,1000))/1000
[1] 0.363
1/exp(1)
[1] 0.3678794

古いバージョン:

shuffleSlow  <- function(m,n) {
  deck <- 1:m
  w <- numeric(0)
  repeat {        
    x <- sample(deck, length(deck))
    w <- c(w, 1*!(sum(deck==x)==0))
    if(length(w) == n)
      break
  }
  return(w)
}

と有用な比較

> system.time(1-sum(shuffleSlow(30,100000))/100000)
   user  system elapsed 
  52.20    0.36   52.65 
> system.time(1-sum(shuffle(30,100000))/100000)
   user  system elapsed 
   2.95    0.00    2.94 
于 2012-06-14T20:54:03.083 に答える
3

欠落している部分は、の内部でrepeat、その反復の出力の単一の値を計算し、それを出力ベクトルの特定の位置(反復に対応する位置)に割り当てる必要があるということです。

または、replicate関数がこのほとんどを処理します。

shuffle <- function(m,n){
    deck <- 1:m
    replicate(n, {newdeck <- sample(deck)
                  anymatches <- as.numeric(any(deck==newdeck))
                  deck <- newdeck
                  anymatches})
}

といくつかの例:

> shuffle(5,35)
 [1] 0 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 0 1 1 0 1 0 1 1 1 1 1 0 1 1 1 1 1
> shuffle(20,30)
 [1] 0 0 0 0 0 0 0 1 0 0 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 0 1 0 0 0
> shuffle(52,35)
 [1] 1 1 1 0 1 0 0 1 1 1 1 1 0 0 0 1 1 1 1 0 0 1 0 1 1 1 0 0 1 1 0 1 0 1 1
于 2012-06-14T20:54:51.957 に答える
3

各反復で上書きwしているため、最終的には最後の反復での値のみになりwます。

デッキをシャッフルする回数がわかっている場合は、forループよりもループを使用する方がよいでしょうrepeat

wとの実際の比較を含めるのか、それとも一致しないものがあったかどうかを示すsとsのdeckベクトルだけを含めるのかは明確ではありません。とにかく、これらの両方を実装するいくつかの例を次に示します。01

shuffle <- function(deck, n) {
    out <- logical(length = n)
    shuf <- deck
    for(i in seq_len(n)) {
        shuf <- sample(shuf)
        out[i] <- any(shuf == deck)
    }
    out <- as.numeric(out)
    out
}

これは次のように使用され、次のように生成されます。

> set.seed(42)
> deck <- 1:100
> (out <- shuffle(deck, 20))
 [1] 0 1 1 1 1 0 1 0 0 1 1 0 1 1 1 1 0 1 0 1

deckとシャッフルされたデッキの間の一致の位置を返すバージョンは次のとおりです。

shuffle2 <- function(deck, n) {
    out <- matrix(NA, ncol = n, nrow = length(deck))
    shuf <- deck
    for(i in seq_len(n)) {
        shuf <- sample(shuf)
        out[,i] <- shuf == deck
    }
    out <- out + 0
    out
}

これは次のように使用され、

> set.seed(42)
> deck <- 1:100
> (out2 <- shuffle2(deck, 20))
       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
  [1,]    0    0    0    0    0    0    0    0    0     0     0
  [2,]    0    0    0    0    0    0    0    0    0     0     0
  [3,]    0    0    0    0    0    0    0    0    0     0     0
  [4,]    0    0    0    0    0    0    0    0    0     0     0
  [5,]    0    0    0    0    0    0    0    0    0     0     0
  [6,]    0    0    0    0    0    0    0    0    0     0     0
  [7,]    0    0    0    0    0    0    0    0    0     0     0
  [8,]    0    0    0    0    0    0    0    0    0     0     0
  [9,]    0    0    0    0    0    0    0    0    0     0     0
 [10,]    0    0    0    1    0    0    0    0    0     0     0
....

その一致の行列は簡単に処理され、一致するかどうかのベクトルが生成されます。

> as.numeric(apply(out2 > 0, 2, any))
 [1] 0 1 1 1 1 0 1 0 0 1 1 0 1 1 1 1 0 1 0 1

これは。によって与えられたものと一致しshuffle()ます。

もちろん、2つを組み合わせて、関数によって両方を返すこともできます。

shuffle3 <- function(deck, n) {
    out <- matrix(NA, ncol = n, nrow = length(deck))
    shuf <- deck
    for(i in seq_len(n)) {
        shuf <- sample(shuf)
        out[,i] <- shuf == deck
    }
    out <- list(matches = out+0,
                summary = as.numeric(apply(out > 0, 2, any)))
    out
}

これは、次のように使用され、生成されます。

> set.seed(42)
> deck <- 1:100
> out3 <- shuffle3(deck, 20)
> str(out3)
List of 2
 $ matches: num [1:100, 1:20] 0 0 0 0 0 0 0 0 0 0 ...
 $ summary: num [1:20] 0 1 1 1 1 0 1 0 0 1 ...
> out3$summary
 [1] 0 1 1 1 1 0 1 0 0 1 1 0 1 1 1 1 0 1 0 1

どちらのバージョンを使用する場合でも、最初に必要なサイズの結果を保持するオブジェクトを作成してから、ループを進めながらそのオブジェクトを入力することに注意してください。

于 2012-06-14T21:00:14.187 に答える