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)
}
}
Related
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 ...")
}
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!
I am writing an apply function in R to search a table and return all the instances that TRUE occurs, and I have written the following code but it keeps giving me errors, and I am not sure why. Any help is appreciated.
xsum = apply(genomeTable, 1, function(i) {
if (i) < q.start | if (i) > q.end{
return FALSE
} else{
return TRUE
}
})
sum(xsum)
Your if statement is duplicated. You only need one if for the condition. Parenthesis need to wrap the whole condition. Try this:
xsum = apply(genomeTable, 1, function(i) {
if (i < q.start | i > q.end) {
return(FALSE)
} else {
return(TRUE)
}
})
Try this:
xsum = apply(genomeTable, 1, function(i) ifelse ((i < q.sta | i > q.end), FALSE, TRUE))
It does not work, please provide some data.
While working on some problem i came across a situation in which i wanted to know if a function was executed when called upon. To do so i put a print statement in the function.
abc = function(x)
if(x > 0) {
return(x)
print("Go")
} else {
return(0)
print("Run")
}
y = abc(3)
y
# [1] 3
Why print statement is not executed while calling abc()?
That is because you are returning before printing. Change the sequence of those two statements and it should print
abc = function(x) {
if(x > 0) {
print("Go")
return(x)
} else {
print("Run")
return(0)
}
}
abc(3)
#[1] "Go"
#[1] 3
abc(-3)
#[1] "Run"
#[1] 0
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
}
)
}