R повторять до тех пор, пока не будет выполнено условие
Я пытаюсь создать случайную выборку, которая исключает определенные "плохие данные". Я не знаю, являются ли данные "плохими" до тех пор, пока я не опробовать его. Таким образом, мне нужно сделать случайную ничью у населения, а затем проверить ее. Если данные "хорошие", то сохраните их. Если данные "плохие", тогда случайным образом нарисуйте другой и проверьте его. Я хотел бы сделать это, пока размер моего образца не достигнет 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)
Ответы
Ответ 1
Вот общее использование цикла 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)
для выхода из функции напрямую.
Ответ 2
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
Ответ 3
используйте это после первого образца
while (any(bad <- (x$SCORE <= 0)))
x[bad, ] <- df[sample(nrow(df), sum(bad)), ]
Ответ 4
Вы можете просто выбрать строки для выборки непосредственно так (всего 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
.