120

I am doing a for loop for generating 180 graphs for my 6000 X 180 matrix (1 graph per column), some of the data don't fit my criteria and i get the error:

"Error in cut.default(x, breaks = bigbreak, include.lowest = T) 
'breaks' are not unique". 

I am fine with the error, I want the program to continue running the for loop, and give me a list of what columns made this error (as a variable containing column names maybe?).

Here's my command:

for (v in 2:180){
    mypath=file.path("C:", "file1", (paste("graph",names(mydata[columnname]), ".pdf", sep="-")))
    pdf(file=mypath)
    mytitle = paste("anything")
    myplotfunction(mydata[,columnnumber]) ## this function is defined previously in the program
    dev.off()
}

Note: I have found numerous posts about tryCatch and none of them worked for me (or at least i couldn't apply the function correctly). The help file wasn't very helpful as well.

Help would be appreciated. Thanks.

Error404
  • 6,959
  • 16
  • 45
  • 58
  • Take a minute to think about your question. Do we need to know about the vector `mypath` or the fact you are saving pdfs? – csgillespie Feb 07 '13 at 10:20
  • 1
    OK, so you need to "practice" using tryCatch. It's really not that hard. Make up some simple loop function and feed it bad data. Then apply to your current loop, which after all contains a very simple set of commands. – Carl Witthoft Feb 07 '13 at 12:39
  • I definitley need to, now that i know how it works, I can play around with it. :) – Error404 Feb 07 '13 at 14:50

2 Answers2

194

One (dirty) way to do it is to use tryCatch with an empty function for error handling. For example, the following code raises an error and breaks the loop :

for (i in 1:10) {
    print(i)
    if (i==7) stop("Urgh, the iphone is in the blender !")
}

[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
[1] 6
[1] 7
Erreur : Urgh, the iphone is in the blender !

But you can wrap your instructions into a tryCatch with an error handling function that does nothing, for example :

for (i in 1:10) {
  tryCatch({
    print(i)
    if (i==7) stop("Urgh, the iphone is in the blender !")
  }, error=function(e){})
}

[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
[1] 6
[1] 7
[1] 8
[1] 9
[1] 10

But I think you should at least print the error message to know if something bad happened while letting your code continue to run :

for (i in 1:10) {
  tryCatch({
    print(i)
    if (i==7) stop("Urgh, the iphone is in the blender !")
  }, error=function(e){cat("ERROR :",conditionMessage(e), "\n")})
}

[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
[1] 6
[1] 7
ERROR : Urgh, the iphone is in the blender ! 
[1] 8
[1] 9
[1] 10

EDIT : So to apply tryCatch in your case would be something like :

for (v in 2:180){
    tryCatch({
        mypath=file.path("C:", "file1", (paste("graph",names(mydata[columnname]), ".pdf", sep="-")))
        pdf(file=mypath)
        mytitle = paste("anything")
        myplotfunction(mydata[,columnnumber]) ## this function is defined previously in the program
        dev.off()
    }, error=function(e){cat("ERROR :",conditionMessage(e), "\n")})
}
juba
  • 47,631
  • 14
  • 113
  • 118
  • Thanks for your answer Juba, the command you wrote is quite clear. But i still have 2 issues with that. 1-Sadly, the program is stopping at column 26 and telling me "ERROR : Urgh, the iphone is in the blender" (so your program is partially working!). 2- in your command, the error always happens at i==7, but i might have errors at 26,50,70,120,121,135.... Is there a way to say "Whenever there is an error, skip to next if". Appreciated – Error404 Feb 07 '13 at 14:32
  • 3
    The `tryCatch` instruction should "intercept" the error whenever it occurs in your code or your data... – juba Feb 07 '13 at 14:34
  • Well I trust what you say Juba, your command is pretty good. but here's what happened (take a look at the end of the post please). Can you think of anything going wrong? – Error404 Feb 07 '13 at 14:43
  • 2
    No, you didn't understand how `tryCatch` works. See my edited answer for a way you can use it in your code (not tested, obviously). But Daniel Fischer's answer is probably the best : you should really try to understand what the error is and take care of it in your function. – juba Feb 07 '13 at 14:47
  • 1
    I just implemented this in my homework assignment, my code failed 3/4 times due to sampling error, but this allowed me to keep going. – Bluebird Mar 14 '19 at 06:04
  • Wonderful way to explain the tryCatch function and its utility. Thanks a lot @juba. You saved me a lot of time. – Franky May 17 '19 at 18:05
  • Extremely useful answer. In my case I was looping over datasets (within datasets), and some datasets simply did not exist (for reasons), which threw an error, and I wanted it to keep going and to operate on all others. This worked perfectly! – DryLabRebel Jul 07 '20 at 06:54
22

Here's a simple way

for (i in 1:10) {
  
  skip_to_next <- FALSE
  
  # Note that print(b) fails since b doesn't exist
  
  tryCatch(print(b), error = function(e) { skip_to_next <<- TRUE})
  
  if(skip_to_next) { next }     
}

Note that the loop completes all 10 iterations, despite errors. You can obviously replace print(b) with any code you want. You can also wrap many lines of code in { and } if you have more than one line of code inside the tryCatch

stevec
  • 41,291
  • 27
  • 223
  • 311