R重复功能直到满足条件
Posted
技术标签:
【中文标题】R重复功能直到满足条件【英文标题】:R repeat function until condition met 【发布时间】:2013-12-28 17:22:48 【问题描述】:我正在尝试生成排除某些“不良数据”的随机样本。我不知道数据是否“坏”,直到我采样之后。因此,我需要从人群中随机抽取,然后进行测试。如果数据“好”,则保留它。如果数据“不好”,则随机抽取另一个数据并进行测试。我想这样做,直到我的样本量达到 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)
【问题讨论】:
你熟悉?while
吗?
我查看了 ?'while' 和 ?Control 但无法理解如何使用它。
那么,画完还要计算吗?在这里,您已经有了 SCORE
,只需将那些好的和样本子集即可。
@Ananta 那仍然是来自原始人群的随机样本吗?
@aseidlitz 它使用上面提到的相同信息“SCORE”,除非示例中没有其他内容,它只是简化为一个简单的子集问题
【参考方案1】:
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
【讨论】:
非常好的帮助。在我所有的 R 手册中甚至都没有提到 Recall 函数。如果我使用: if (x$SCORE > 0) return(x) else Recall(x) 会更好吗? 优雅但不如while
循环恕我直言,因为它可以创建一个大的调用堆栈。
您实际上是在进行拒绝抽样。可以很简单:df$SCORE[df$SCORE > 0][ sample(1:(sum(df$SCORE > 0, 1)]
。我不确定如何在复选标记上提供建议。我的答案基本上是一次性的。弗洛德尔关于效率是正确的。 R 中不支持递归。
关于您的df$SCORE[df$SCORE > 0][...]
,这与我对斯蒂芬的评论相同:OP 给出了一个更复杂情况的“简化示例”,其中“I直到我采样后才知道数据是否“坏””。因此,递归或 while 循环是唯一可能的解决方案。【参考方案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
这是没有替换的,用于引导放入replace=T
。
【讨论】:
我投了赞成票,但由于 OP 说 我不知道数据是否“坏”,直到我对它进行采样我不确定它是否对他有用。他的榜样可能选择不当。 @flodel 很公平,但 R 不是实时应用程序,也不擅长递归函数调用,因此如果需要检查数据,则测试在数据中,应该向量化并放在括号之间。像这样。 我是否保留观察是观察本身的函数。我无法确定是否要保留观察结果,直到绘制完成。 @user1491868 如果 obs 真的在一个 DF 中,那么你可以做到这一点,根据你的标准子集然后采样......无论如何它并不那么重要:) 经过深思熟虑后,我决定在采样前按标准对数据进行子集化。但我仍然认为,当无法在采样之前对数据进行子集化时,这个线程很有用。感谢大家非常有帮助的 cmets 和建议。【参考方案3】:在你的第一个样本之后使用它
while (any(bad <- (x$SCORE <= 0)))
x[bad, ] <- df[sample(nrow(df), sum(bad)), ]
【讨论】:
【参考方案4】:这是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)
直接退出该功能。
【讨论】:
以上是关于R重复功能直到满足条件的主要内容,如果未能解决你的问题,请参考以下文章