Reputation: 3264
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.
Upvotes: 0
Views: 1777
Reputation: 1654
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.
Upvotes: 2