0

I already read documentations and several other question about tryCatch(), however, I am not able to figure out the solution to my class of problem.

The task to solve is: 1)There is a for loop that goes from row 1 to nrow of the dataframe. 2)Execute some instruction 3)In the case of error that would stop the program, instead restart the loop cycle from the current iteration.

Example

for (i in 1:50000) { ...execute instructions... } 

What I am looking for is a solution that in the case of error at the iteration 30250, it restart the loop such that

for (i in 30250:50000) { ...execute instructions... } 

The practical example I am working on is the following:

library(RDSTK) library(jsonlite) DF <- (id = seq(1:400000), lat = rep(38.929840, 400000), long = rep( -77.062343, 400000) for (i in 1 : nrow(DF) { location <- NULL bo <- 0 while (bo != 10) { #re-try the instruction max 10 times per row location <- NULL location <- try(location <- #try to gather the data from internet coordinates2politics(DF$lat[i], DF$long[i])) if (class(location) == "try-error") { #if not able to gather the data Sys.sleep(runif(1,2,7)) #wait a random time before query again print("reconntecting...") bo <- bo+1 print(bo) } else #if there is NO error break #stop trying on this individual } location <- lapply(location, jsonlite::fromJSON) location <- data.frame(location[[1]]$politics) DF$start_country[i] <- location$name[1] DF$start_region[i] <- location$name[2] Sys.sleep(runif(1,2,7)) #sleep random seconds before starting the new row } 

N.B.: the try() is part of the "...execute instruction..."

What I am looking for is a tryCatch that when a critical error that stops the program happen, it instead restart the for loop from the current index "i".

This program would allow me to automatically iterate over 400000 rows and restart where it interrupted in the case of errors. This means that the program would be able to work totally independently by human.

I hope my question is clear, thank you very much.

2
  • For the case of downloading stuff from the internet, use RETRY() from the httr package. Commented Nov 14, 2017 at 14:12
  • this is also a nice idea for other types of problem. Here the issue is not gathering the data from internet, instead the question is how to use tryCatch() (or some other functions) to restart a loop from the previous iteration in the case of error. Commented Nov 14, 2017 at 14:27

1 Answer 1

2

This is better addressed using while rather than for:

i <- 1 while(i < 10000){ tryCatch(doStuff()) -> doStuffResults if(class(doStuffResults) != "try-catch") i <- i + 1 { 

Beware though if some cases will always fail doStuff: the loop will never terminate!

If the program will produce a fatal error and need a human restart, then the first line i <- 1 may be replaced (as long as you don't use i elsewhere in your code) with

if(!exists("i")) i <- 1 

so that the value from the loop will persist and not be reset to one.

Sign up to request clarification or add additional context in comments.

6 Comments

I posted the code of the real example so you can work on it and present a complete answer. Could you please apply your methodology to the specific problem? However, careful that the try() is a component of the doStuff. For example, if the program fail to obtain the data of row "i" from internet for 10 times, then, the program would give an error. At this point, the program would break and I should restart it manually BUT.. the tryCatch allows to restart the while loop from that individual "i".
" I posted the code of the real example so you can work on it and present a complete answer. " - Gold! How about you try and do it yourself?
Of course I am also trying to do it myself. I was just suggesting you that you could present the gold answer to this question rather than just a hint. :) Thank you anyway
@Enrico: I am trying to produce a general answer rather than one for a very specific task as you have presented. I have added a clarification point though given that your program may terminate and you want to resume with the same value of i. Also note that doStuff() need not actually be a function: you could paste the body of your for loop in place of it as a braced set of expressions and that would also work.
@JDL I am not able to make working your approach because the "Error: lexical error: invalid char in json text." still break the program. Any idea?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.