How to jump to next top level loop - r

If condition occurs in the inner for loop I want to break the inner and next the outer.
I could create a flag in the inner before the break statement and then evaluate in the outer, this is a silly example:
for (i in 1:3) {
NEXT <- FALSE
for (j in 1:3) {
if (j==2 && i==2) {
NEXT <- TRUE
break
}
}
if (NEXT) next
cat("\n", i, " ... some i stuff ...")
}
Is there an elegant way to do it? Something like:
for (i in 1:3) {
for (j in 1:3) {
if (j==2 && i==2) {
break
# next (outer)
}
}
cat("\n", i, " ... some i stuff ...")
}
There a similar/duplicate question but I think it doesn't answer's mine, because in the question's outer loop it does nothing after the inner loop.
How to jump to next top level loop?

A quick fix could be something like:
for(i in 1:3){
for(j in 1:3){
if(i == 2 && j == 2){
i <- 3 # can be ignored if you don't want i value changed
j <- 3 # this will kick it out of the j for loop
} else {
...code...
}
cat ....
}
Obviously, it's not robust but seems to solve your problem.
EDIT:
Per your comment, perhaps you're looking for:
for(i in 1:3){
cat.ready <- TRUE
for(j in 1:3){
if(i == 2 && j == 2){
j <- 3 # this will kick it out of the j for loop
cat.ready <- FALSE
} else {
...code...
}
if(cat.ready == TRUE){
cat(...)
} else {
cat.ready <- TRUE
}
This then will remove you from executing code and also from producing a cat() if i and j are both 2 and will reset the condition after that exception has been handled.
I'm sure there is a more elegant solution, however.

Why not invert the problem and only execute the inner loop if j!=2 && i!=2?
for (i in 1:3) {
for (j in 1:3) {
cat("\n\ni=",i, " and j=",j )
if (j!=2 | i!=2 )
# will be executed unless j is 2 and i is 2
{
cat("\n", j, " ... some j stuff ...")
}
}
cat("\n", i, " ... some i stuff ...")
}
If I am misunderstanding and you want to not execute the combination of j=2/i=2 and j=3/i=2 adjust accordingly:
for (i in 1:3) {
for (j in 1:3) {
cat("\n\ni=",i, " and j=",j )
if (j!=2 | i!=2 & i!=3)
# will be executed unless j is 2 and i is 2 or j is 3 and i is 2
{
cat("\n", j, " ... some j stuff ...")
}
}
cat("\n", i, " ... some i stuff ...")
}

Related

While Loop Inside For Loop in r

I expect the given code to output the answer : 1. However the loop runs forever. I am trying to see if while loop works for such a case. The use of while loop is necessary for the solution.
a = list(1,2,3,4)
for(i in a){
while(i != 2){
print(i)
}
}
Here are two solutions that work with while. The first one with a 'flag' set as TRUE, and the index as 1, based on the condition, set the 'flag' to FALSE
flag <- TRUE
i <- 1
while(flag) {
print(a[[i]])
i <- i + 1
if(a[[i]] == 2) {
flag <- FALSE
}
}
#[1] 1
Or we add a break
i <- 1
while(TRUE) {
print(a[[i]])
i <- i + 1
if(a[[i]] == 2) {
break
}
}
#[1] 1
The value of i does not change inside the while loop, so you never advance to the next item in list. You need if instead of while:
a = list(1,2,3,4)
for(i in a){
if(i != 2){
print(i)
}
}

Couldn't calculate prime numbers within a range

for (i in 2:100 )
{
count <- 0
for (j in i )
if( (i %% j ) == 0 )
count <- count + 1
if(count == 2 )
print(i)
}
I am trying to print print prime numbers in R. Could any one help me to resolve
Let us look at your code and show what went wrong. It's the inner loop that did not loop at all:
for (i in 2:100 )
{
count <- 0
for (j in 1:i ) # you forgot to provide a vector here
if( i %% j == 0 )
count <- count + 1
if(count == 2)
print(i)
}
The answer above tries to optimise the code some more and is a more efficient solution. For example does it only test odd numbers because even ones clearly aren't prime numbers.
The below code creates the function prime_numbers which returns prime numbers up to an inputted number.
prime_numbers <- function(n) {
if (n >= 2) {
x = seq(2, n)
prime_nums = c()
for (i in seq(2, n)) {
if (any(x == i)) {
prime_nums = c(prime_nums, i)
x = c(x[(x %% i) != 0], i)
}
}
return(prime_nums)
}
else {
stop("Input number should be at least 2.")
}
}
## return the answer to your question
prime_numbers(100)
If you wanted the range 3:100, after running the above code you could run something like this:
a<-prime_numbers(100)
a[a>3]
I hope this helps!

For statement nested in while statement not working

I am learning how to use while and for loops, and am having difficulty executing a for loop within a while loop. I am trying to recurse a simple procedure over a vector, and have the while loop set the conditionals for which parts of the vector are operated upon. This is really just meant as an exercise to understand how to use for and while loops in conjunction.
data <- c(1:200)
n=0
while(n < 100){
for(x in data){
n=x+1
if(x >= 10 & x < 100){
print("double digit")
} else {
print("single digit")
}}}
I want to stop the while loop when the procedure hits x=100 of the vector that runs from 1:200. But instead, the for loop runs through every element within the vector, from 1:200, failing to stop executing when n hits 100.
Would appreciate any advice to help out a new coder, thanks.
I have also tried
for(x in data){
n=x+1
while(n < 100){
if(x >= 10 & x < 100){
print("double digit")
} else {
print("single digit")
}}}
But the code does not stop executing.
First let's try a for loop. Each time through it n will be set to the loop counter plus 1. If this result is between 10 and 100, print a message, if not print something else. Note that no loop depends on n .
data <- c(1:200)
n = 0
for (x in data) {
n = x + 1
if (n < 100) {
if (x >= 10 && x < 100) {
print("double digit")
} else {
print("single digit")
}
}
}
x
#[1] 200
n
#[1] 201
Now for a while loop. I believe it is much simpler, it only envolves one variable, n.
n <- 0
while (n < 100) {
n = n + 1
if (n < 100) {
if (n >= 10) {
print("double digit")
} else {
print("single digit")
}
}
}
n
#[1] 100

How to restart a loop with eval with timeout in R?

while (!exists("j")) {
i <- 1
repeat {
tryCatch(expr = {
print(i)
raw.result <- evalWithTimeout(Sys.sleep(i), timeout = 3)
if (i == 1) {
j <- i
} else {
j <- c(j, i)
}
i <- i + 1
}, TimeoutException = function(ex) {
rm("j")
})
}
}
The above code is getting stuck at i=4 and keeps executing the function for i=4, however I want it to restart from i=1, whenever there is an error.
Can someone please guide on where am I doing it wrong?
In your codeTimeoutException is unable to find j as it is evaluated in a different environment. Even if it was able to find it, nothing would change. As tryCatch is stopping an error from breaking a repeat loop, thus repeat will continue with the current i. You could explicitly break out from the repeat, but in that case you have deleted j, thus your while will stop.
I am not quite sure why you need while loop here.
Here is a modification of your code that will work as you want.
Fist explicitly set i <- 1, and rest it again to i <<-1 (Note <<- as i is one environment above tryCatch).
i <- 1
repeat {
tryCatch(
expr = {
print(i)
raw.result <- R.utils:evalWithTimeout(Sys.sleep(i), timeout = 3)
if (i == 1) {
j <- i
} else {
j <- c(j, i)
}
i <- i + 1
},
TimeoutException = function(ex) {
i <<- 1
}
)
}

Why is break() not working in this loop? (but stop is)

I am trying to build a matrix model which ends if certain conditions are invoked - however for some reason the break() command isn't working, although stop() does. Unfortunately stop() is not what I need as I need to run the model a number of times.
The first break command in the model works, but I have left it in with dth>100 so that you can see for yourselves
n.steps <- 200
ns <- array(0,c(14,n.steps))
ns[13,1]<-rpois(1,3)
ns[14,1] <- 1
k<-0
for (i in 1:n.steps){
k<-k+1
ns[13,1]<-rpois(1,2)
death<-sample(c(replicate(1000,
sample(c(1,0), prob=c(surv.age.a, 1-surv.age.a), size = 1))),1)
ns[14,k] <- death
if (death == 0) {
dth <- sample(1:100, 1)
if (dth > 100) {
ns[14,k]<-0
print("stop.1")
break()
} else {
while (death == 0) {
if (ns[13, k] > 0) {
rep.vec[i]<-ns[13,k]
ns[13, k] <- ns[13, k] - 1
ns[14,k+1]<-1
print("replace")
} else {
if (ns[13, k] == 0) {
print("stop.2")
ns[14,k+1]<-0
break()
}
}
}
}
}
}
Try this (only showing the relevant portions):
for (i in 1:n.steps){
# ...
break.out.of.for <- FALSE
while (death == 0) {
if (ns[13, k-1] > 0) {
# ...
} else {
if (ns[13, k] == 0) {
# ...
break.out.of.for = TRUE
break
}
}
if (break.out.of.for) {
break
}
}

Resources