Breaking out of nested loops in R
Solution 1
Using explicit flags, and breaking out of loops conditionally on those flags can give one more flexibility. Example:
stop = FALSE
for (i in c(1,2,3,4)){
for (j in c(7,8,9)){
print(i)
print(j)
if (i==3){
stop = TRUE # Fire the flag, and break the inner loop
break
}
}
if (stop){break} # Break the outer loop when the flag is fired
}
The above code will break the two nested loops when i=3
. When the last line (if (stop){break}
) is commented out, then only the inner loop gets broken at i=3
, but the outer loop keeps running, i.e. it practically skips the cases of i=3
. This structure is easy to play around with, and is as flexible as one may need.
Solution 2
I think your method of wrapping your nested loops into a function is the cleanest and probably best approach. You can actually call return()
in the global environment, but it will throw an error and looks ugly, like so:
for (i in 1:10) {
for (a in 1:10) {
for(b in 1:10) {
if (i == 5 & a == 7 & b == 2) { return() }
}
}
}
print(i)
print(a)
print(b)
Which looks like this in the command line:
> for (i in 1:10) {
+ for (a in 1:10) {
+ for(b in 1:10) {
+
+ if (i == 5 & a == 7 & b == 2) { return() }
+
+ }
+ }
+ }
Error: no function to return from, jumping to top level
>
> print(i)
[1] 5
> print(a)
[1] 7
> print(b)
[1] 2
Obviously far better and cleaner to use the function method.
EDIT:
Added an alternative solution to making the error look nicer given by Roland:
for (i in 1:10) {
for (a in 1:10) {
for(b in 1:10) {
if (i == 5 & a == 7 & b == 2) { stop("Let's break out!") }
}
}
}
print(i)
print(a)
print(b)
Robomatix
Updated on August 04, 2022Comments
-
Robomatix over 1 year
Very simple example code (only for demonstration, no use at all):
repeat { while (1 > 0) { for (i in seq(1, 100)) { break # usually tied to a condition } break } break } print("finished")
I want to break out from multiple loops without using
break
in each loop separately. According to a similar question regarding python, wrapping my loops into a function seems to be a possible solution, i.e. usingreturn()
to break out of every loop in the function:nestedLoop <- function() { repeat { while (1 > 0) { for (i in seq(1, 100)) { return() } } } } nestedLoop() print("finished")
Are there other methods available in R? Maybe something like labeling loops and then specifying which loop to break (like in Java) ?
-
Roland almost 8 yearsWell, you could just throw an error directly using
simpleError
instead. -
giraffehere almost 8 yearsReplacing
return()
withsimpleError("", call = return())
still throws the error in the console, though I haven't seensimpleError
before so I might be using it incorrectly. -
Roland almost 8 yearsTry
stop("Let's break out!")
which returns asimpleError
object. -
giraffehere almost 8 yearsAdded in an alternative version, is that what you meant?
-
Roland almost 8 yearsYes, that's better than using an expression/function that throws an error only because you want an error. Of course, it is still not a good solution because this is not appropriate use of errors. You'll see why if you wrap this code in a function. You couldn't get a return value from that function.
-
giraffehere almost 8 yearsYeah, I agree that wrapping this in a function is the right way to do what OP wants. Just doing this for the sake of trying.