R重复功能,直到满足条件

R重复功能,直到满足条件,r,function,conditional-statements,repeat,R,Function,Conditional Statements,Repeat,我正在尝试生成一个随机样本,排除某些“坏数据”。在对数据进行采样之前,我不知道该数据是否“坏”。因此,我需要从总体中随机抽取样本,然后对其进行测试。如果数据“良好”,则保留它。如果数据“不好”,则随机抽取另一个数据并进行测试。我想这样做,直到我的样本量达到25。下面是一个简单的例子,我试图编写一个函数来实现这一点。谁能告诉我我错过了什么 df <- data.frame(NAME=c(rep('Frank',10),rep('Mary',10)), SCORE=rnorm(20)) df

我正在尝试生成一个随机样本,排除某些“坏数据”。在对数据进行采样之前,我不知道该数据是否“坏”。因此,我需要从总体中随机抽取样本,然后对其进行测试。如果数据“良好”,则保留它。如果数据“不好”,则随机抽取另一个数据并进行测试。我想这样做,直到我的样本量达到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)

df您可以像这样直接选择要采样的行(仅5行):

>df-df[样本(其中(df$SCORE>0),5),]
姓名分数
14玛丽1.0858854
10弗兰克0.7037989
16玛丽0.7688913
5弗兰克0.2067499
17玛丽0.4391216

这是不需要更换的,对于放入
replace=T

的引导,请在第一个示例之后使用此选项

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

while(any)(bad这里是
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)
}

其中,
break
使您退出
repeat
块。或者,您可以让
if(x$SCORE>0)返回(x)
直接退出函数。

你熟悉
?while
?我看了一下“while”和“Control”,但不知道如何使用它。因此,你必须在绘图后进行计算?在这里,你已经有了
分数
,只需将那些好的和样本子集。@Ananta这仍然是来自orig的随机样本吗inal population?@aseidlitz它使用的是上面提到的相同信息“SCORE”,除非示例中没有其他内容,它只是简化为一个简单的子集问题。非常好的帮助。在我所有的R手册中都没有提到回调函数。如果我使用:if(x$SCORE>0){return(x)}else{Recall(x)}?优雅但不如
while
循环IMHO有效,因为它可以创建一个大的调用堆栈。您实际上是在进行拒绝采样。它可以简单到:
df$SCORE[df$SCORE>0][sample(1:(sum(df$SCORE>0,1)]
。我不知道如何对复选标记提出建议。我的答案基本上是一次性的。弗洛德尔关于效率的观点是正确的。递归在R中不受很好的支持。关于你的
df$SCORE[df$SCORE>0][…]
,这与我对斯蒂芬的评论是一样的:OP给出了一个更复杂情况的“简化示例”,其中“我不知道数据是否“坏”,直到我采样之后。所以递归或while循环是唯一可能的解决方案。我投了赞成票,但因为OP说我不知道数据是否“坏”"在我对它进行采样之前,我不确定它是否适合他。他的例子可能选得不好。@flodel很公平,但R不是一个实时应用程序,也不擅长递归函数调用,因此如果需要检查数据,测试就在数据中,应该矢量化并放在括号之间。就像这样。我是否保留观察结果是一个问题观察值本身的函数。我无法确定是否在绘制观察值之前保留观察值。@user1491868如果obs确实在DF中,则您可以完全这样做,根据您的标准进行子集,然后采样……无论如何,它并不真的那么重要,是吗:)在仔细考虑之后,我决定在采样之前根据标准对数据进行子集划分。但是,当无法在采样之前对数据进行子集划分时,我仍然认为此线程非常有用。感谢大家提供了非常有用的意见和建议。
> 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
while (any(bad <- (x$SCORE <= 0)))
   x[bad, ] <- df[sample(nrow(df), sum(bad)), ]
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)
}
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)
}