web-dev-qa-db-ja.com

R条件が満たされるまで機能を繰り返す

特定の「不良データ」を除外するランダムサンプルを生成しようとしています。データをサンプリングするまで、データが「不良」かどうかはわかりません。したがって、母集団からランダムな抽選を行い、それをテストする必要があります。データが「良い」場合、それを保持します。データが「不良」である場合、ランダムに別のデータを描画してテストします。サンプルサイズが25に達するまでこれを行いたいと思います。以下は、これを行う関数を記述しようとする試みの簡単な例です。誰が私に欠けているものを教えてもらえますか?

df <- data.frame(NAME=c(rep('Frank',10),rep('Mary',10)), SCORE=rnorm(20))
df

random.sample <- function(x) {
  x <- df[sample(nrow(df), 1), ]
  if (x$SCORE > 0) return(x)
 #if (x$SCORE <= 0) run the function again
}

random.sample(df)
14
user1491868

whileループの一般的な使用法は次のとおりです。

_random.sample <- function(x) {
  success <- FALSE
  while (!success) {
    # do something
    i <- sample(nrow(df), 1)
    x <- df[sample(nrow(df), 1), ]
    # check for success
    success <- x$SCORE > 0
  }
  return(x)
}
_

別の方法は、repeatwhile(TRUE)の構文シュガー)とbreakを使用することです。

_random.sample <- function(x) {
  repeat {
    # do something
    i <- sample(nrow(df), 1)
    x <- df[sample(nrow(df), 1), ]
    # exit if the condition is met
    if (x$SCORE > 0) break
  }
  return(x)
}
_

breakは、repeatブロックを終了します。または、if (x$SCORE > 0) return(x)を使用して、関数を直接終了することもできます。

18
flodel

最初のサンプルの後にこれを使用します

while (any(bad <- (x$SCORE <= 0)))
   x[bad, ] <- df[sample(nrow(df), sum(bad)), ]
3
Ricardo Saporta
 random.sample <- function(x) {
   x <- df[sample(nrow(df), 1), ]
   if (x$SCORE > 0) return(x)
   Recall(x)# run the function again
 }

 random.sample(df)
#   NAME    SCORE
#14 Mary 1.252566

これも同様に機能するはずです:

 df$SCORE[ df$SCORE > 0 ][ sample(1:sum(df$SCORE > 0), 1) ]
#[1] 0.6579631
3
42-

次のように、サンプリングする行を選択するだけです(5つだけ)。

> df <- data.frame(NAME=c(rep('Frank',10),rep('Mary',10)), SCORE=rnorm(20))
> df[sample(which(df$SCORE>0), 5),]


 NAME     SCORE
14  Mary 1.0858854
10 Frank 0.7037989
16  Mary 0.7688913
5  Frank 0.2067499
17  Mary 0.4391216

bootstrap put in replace=T

2