2013-12-10 13 views
11

Ich versuche, eine Stichprobe zu erzeugen, die bestimmte ausschließt „schlechte Daten.“ Ich weiß nicht, ob die Daten "schlecht" sind, bis ich sie einmal getestet habe. Also muss ich eine zufällige Auslosung von der Bevölkerung machen und sie dann testen. Wenn die Daten "gut" sind, dann behalte sie. Wenn die Daten "schlecht" sind, dann ziehe zufällig einen anderen und teste ihn. Ich möchte dies tun, bis meine Stichprobengröße 25 erreicht. Unten ist ein vereinfachtes Beispiel für meinen Versuch, eine Funktion zu schreiben, die dies tut. Kann mir bitte jemand sagen, was ich vermisse?R Repeat-Funktion, bis die Bedingung erfüllt

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) 
+1

sind Sie vertraut mit '? While'? –

+0

Ich schaute auf "while" und "Control", hatte aber Schwierigkeiten zu verstehen, wie man es benutzt. – user1491868

+0

Also müssen Sie nach dem Zeichnen eine Berechnung durchführen? hier haben Sie bereits 'SCORE', nur Teilmengen, die gut und Probe. – Ananta

Antwort

14

Hier ist eine allgemeine Verwendung einer while Schleife:

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) 
} 

Eine Alternative ist repeat (syntaktischer Zucker für while(TRUE)) zu verwenden und 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) 
} 

, wo break Sie den repeat Block verlassen. Alternativ könnten Sie if (x$SCORE > 0) return(x) haben, um die Funktion direkt zu verlassen.

3
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 

Es scheint mir, dass dies auch funktionieren:

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

Sehr nette Hilfe. Die Recall-Funktion wird nirgendwo in meinen R-Handbüchern erwähnt. Ist es besser, wenn ich folgendes verwende: if (x $ SCORE> 0) {return (x)} else {Recall (x)}? – user1491868

+1

elegant, aber nicht so effizient wie eine "while" -Schleife IMHO, da es einen großen Call-Stack erstellen kann. – flodel

+0

Also sollte ich Ricardos Antwort als die beste akzeptieren? – user1491868

2

können Sie nur die Zeilen auswählen, um direkt zu probieren wie so (nur 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 

Dies ist ohne Ersatz, für Bootstrap in replace=T.

+1

Ich habe zwar upgevotet, aber da das OP gesagt hat * weiß ich nicht, ob die Daten "schlecht" sind, bis ich nach dem Sample * bin ich mir nicht sicher, ob es für ihn funktioniert.Sein Beispiel wäre vielleicht schlecht gewählt. – flodel

+0

@flodel fair genug, aber R ist keine Echtzeit-App, noch gut bei rekursiven Funktionsaufrufen, also wenn die Daten überprüft werden müssen, ist der Test in den Daten und sollte vektorisiert werden und zwischen die Klammern gesetzt werden .. so. –

+0

Ob ich die Beobachtung behalte, ist eine Funktion der Beobachtung selbst. Ich kann nicht bestimmen, ob ich die Beobachtung bis nach dem Zeichnen beibehalten möchte. – user1491868

3

Verwendung dieses nach dem ersten Probe

while (any(bad <- (x$SCORE <= 0))) 
    x[bad, ] <- df[sample(nrow(df), sum(bad)), ] 
Verwandte Themen