107 votes

Erreur de saut dans le for-loop

Je fais une boucle pour générer 180 graphiques pour ma matrice 6000 X 180 (1 graphique par colonne), certaines des données ne correspondent pas à mes critères et j'obtiens l'erreur :

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

L'erreur ne me dérange pas, mais je veux que le programme continue à exécuter la boucle for et me donne une liste des colonnes qui ont produit cette erreur (sous forme de variable contenant les noms des colonnes, par exemple).

Voici ma commande :

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 : J'ai trouvé de nombreux articles sur tryCatch et aucun d'entre eux n'a fonctionné pour moi (ou du moins je n'ai pas pu appliquer la fonction correctement). Le fichier d'aide n'était pas très utile non plus.

Une aide serait appréciée. Merci.

180voto

juba Points 15701

Une manière (sale) de le faire est d'utiliser tryCatch avec une fonction vide pour la gestion des erreurs. Par exemple, le code suivant lève une erreur et interrompt la boucle :

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 !

Mais vous pouvez envelopper vos instructions dans un tryCatch avec une fonction de gestion des erreurs qui ne fait rien, par exemple :

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

Mais je pense que vous devriez au moins imprimer le message d'erreur pour savoir si quelque chose de mal s'est produit tout en laissant votre code continuer à s'exécuter :

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 : Ainsi, pour appliquer tryCatch dans votre cas, serait quelque chose comme :

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")})
}

14voto

user5783745 Points 1214

Voici un moyen simple

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 }     
}

Notez que la boucle achève les 10 itérations, malgré les erreurs. Vous pouvez évidemment remplacer print(b) avec le code que vous voulez. Vous pouvez également envelopper de nombreuses lignes de code dans des fichiers { y } si vous avez plus d'une ligne de code à l'intérieur de la balise tryCatch

3voto

Daniel Fischer Points 923

Au lieu d'attraper l'erreur, ne serait-il pas possible de tester dans ou avant le myplotfunction() fonction d'abord si l'erreur se produira (c'est-à-dire si les ruptures sont uniques) et ne la tracer que pour les cas où elle n'apparaîtra pas !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X