#' @title doWhile
#' @param do Expression to evaluate at least once. The "do" expression will be repeated until the "While" condition is FALSE.
#' @param While Logical expression indicating the stopping condition. The doWhile loop will end when the "While" condition is no longer TRUE. Default is FALSE (execute "do" expression once and then return).
#' @param Return Expression to evaluate and return (allows returning of variables scoped inside the doWhile function). Default is NULL.
#' @param vars List of variables to pass by value to the doWhile loop function.
#' @export
#' @examples
#'
#' doWhile(do={k=k+1; print(k)}, While={k<5},vars=list(k=0))
#' doWhile({if(!exists("k")) {k<-1} else {k<-k+1}; print(k)}, {k<5})
#'
#' k <<- 0
#' doWhile({k<<-k+1; print(k)}, {k<5})
#' rm(k)
#'
#' # Note that i remains zero here due to scoping
#' i=0
#' doWhile(do={i=i+1; print(i)}, While={i<10}, Return=i)
#' print(i)
#'
#' # But we can force an update of i using "i <<- i+1"
#' i=0
#' doWhile(do={i<<-i+1; print(i)}, While={i<10}, Return=i)
#' print(i)
#'
#' # or we can declare j (and jPI) in the scope of the doWhile:
#' jPI=doWhile(do={if(!exists("j")|!exists("jPI")){j<-0;jPI<-0}
#' else{j=j+1; jPI=jPI+pi}},
#' While={j<10},
#' Return={jPI})
#' print(jPI)
#'
#' # Using a list lets us check existence just once when we have many parameters in the loop:
#' Y = doWhile(do ={ if(!exists("E")) {E<-list(x=pi, y=exp(1))}; E$y=E$x+E$y},
#' While ={ E$y < 100},
#' Return={ E$y})
#' print(Y)
doWhile <- function(do, While=F, Return=NULL, vars=NULL) {
env = environment()
if(!is.null(vars)) { list2env(vars, envir = env) }
eval(substitute(do), env=env)
while(eval(substitute(While), env=env)) {
eval(substitute(do), env=env)
}
return(eval(substitute(Return), env=env))
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.