2013-12-10 47 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)), ]