J'essaie de générer un échantillon aléatoire qui exclut certaines "mauvaises données". Je ne sais pas si les données sont "mauvaises" avant de les avoir échantillonnées. Ainsi, je dois faire un tirage au sort de la population, puis le tester. Si les données sont "bonnes", conservez-les. Si les données sont "mauvaises", dessinez-en une autre au hasard et testez-la. Je voudrais le faire jusqu'à ce que ma taille d'échantillon atteigne 25. Ci-dessous est un exemple simplifié de ma tentative d'écrire une fonction qui fait cela. Quelqu'un peut-il me dire ce qui me manque?
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)
Voici une utilisation générale d'une boucle 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)
}
Une alternative consiste à utiliser repeat
(sucre syntaxique pour while(TRUE)
) et 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)
}
où break
vous fait quitter le bloc repeat
. Vous pouvez également avoir if (x$SCORE > 0) return(x)
pour quitter directement la fonction.
utilisez-le après votre premier échantillon
while (any(bad <- (x$SCORE <= 0)))
x[bad, ] <- df[sample(nrow(df), sum(bad)), ]
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
Il me semble que cela devrait aussi fonctionner:
df$SCORE[ df$SCORE > 0 ][ sample(1:sum(df$SCORE > 0), 1) ]
#[1] 0.6579631
Vous pouvez simplement sélectionner les lignes à échantillonner directement ainsi (seulement 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
c'est sans remplacement, pour bootstrap mettre dans replace=T
.