开发者

breaking out of for loop when running a function inside a for loop in R

Suppose you have the following function foo. When I'm running a for loop, I'd like it to skip the remainder of foo when foo initially returns the value of 0. However, break doesn't wor开发者_运维问答k when it's inside a function.

As it's currently written, I get an error message, no loop to break from, jumping to top level.

Any suggestions?

foo <- function(x) {
    y <- x-2
    if (y==0) {break} # how do I tell the for loop to skip this
    z <- y + 100
    z
}


for (i in 1:3) {
    print(foo(i))
}


Admittedly my R knowledge is sparse and this is drycoded, but something like the following should work:

foo <- function(x) {
    y <- x-2
    if (y==0) {return(NULL)} # return NULL then check for it
    z <- y + 100
    z
}

for (i in 1:3) {
    j <- foo(i)
    if(is.null(j)) {break}
    print(j)
}

Edit: updated null check for posterity


As a matter of coding practice, don't do this. Having a function that can only be used inside a particular loop is not a great idea. As a matter of educational interest, you can evaluate the 'break' in the parent environment.

foo <- function(x) {
    y <- x-2
    if (y==0) {eval.parent(parse(text="break"),1)} 
    z <- y + 100
    z
}



for (i in 0:3) {
    print(foo(i))
}


Are we allowed to be a little more creative? Could you recast your problem to take advantage of the following approach, where the operation is based on vectors?

x <- 1:3  
y <- x[x-2 < 0] - 2 + 100 # I'm leaving the "- 2" separate to highlight the parallel to your code  
y  

If, however, a deeper form underlies the question and we need to follow this pattern for now, perhaps tweak it just a bit...

foo <- function(x) {
  y <- x - 2
  if (y != 0) {
    z <- y + 100
    z
  } # else implicitly return value is NULL
}

for (i in 1:3) {
  if (is.numeric(result <- foo(i))) {
    print(result)
  } else {
    break 
  }
}


An alternative way is to throw an error and catch it with try, like so:

foo <- function(x) {
    y <- x-2
    if (y==0) {stop("y==0")} 
    z <- y + 100
    z
}

try(for (i in 0:5) {
       print(foo(i))
}, silent=TRUE)

## or use tryCatch:
for (i in 0:5) {
   bar <- tryCatch(foo(i),error=function(e) NA)
   if(is.na(bar)){ break } else { print(bar) }
}


I have no clue how r works but I found the question interesting because I could lookup a new language's syntax so excuse my answer if it is totally wrong :)

foo <- function(x) { 
    y <- x-2 
    if (y!=0) z <- NULL else z <- y + 100 
    z 
}


for (i in 1:3)
{ 
    a <- foo(i)
    if (a == NULL) {next}
    print(a)
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜