2013-12-10 45 views
11

我試圖生成排除某些「不良數據」的隨機樣本。我不知道數據是否「壞」,直到我對它進行採樣。因此,我需要隨機抽取人羣並進行測試。如果數據「很好」,那麼保留它。如果數據「不好」,則隨機抽取另一個數據並對其進行測試。我想這樣做,直到我的樣本大小達到25歲。下面是我嘗試編寫這樣一個函數的簡化示例。任何人都可以告訴我我失蹤了什麼?R重複函數,直到條件滿足

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

你是否熟悉'?while'? –

+0

我看了一下?'while'和?Control但很難理解如何使用它。 – user1491868

+0

那麼,繪圖後你必須做計算嗎?在這裏,你已經有了'SCORE',只是那些優秀和樣品的子集。 – Ananta

回答

14

這裏之後是一個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) 
} 

一種替代方法是使用repeat(爲while(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)直接退出該功能。

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 

在我看來,這應該工作,以及:

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

非常好的幫助。 Recall功能在我的所有R手冊中都沒有提及。如果我使用if(x $ SCORE> 0){return(x)} else {Recall(x)}? – user1491868

+1

優雅但不如'while'循環IMHO效率高,因爲它可以創建一個大的調用堆棧。 – flodel

+0

所以我應該接受裏卡多的答案爲最好的? – user1491868

2

你可以只選擇行來樣直接像這樣(只是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放在replace=T

+1

我upvoted,但自OP說*我不知道數據是否「壞」,直到我採樣後*我不知道它會爲他工作。他的榜樣可能選擇不當。 – flodel

+0

@flodel足夠公平,但R不是一個實時應用程序,也不擅長遞歸函數調用,所以如果數據需要檢查,測試在數據中,應該被矢量化並放在括號之間..就像這樣。 –

+0

我是否繼續觀察是觀察本身的一個功能。我不能確定是否保持觀察,直到繪製完成。 – user1491868

3

使用這第一個樣品

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