Comment écrire trycatch dans R

Je veux écrire trycatch code trycatch pour traiter les erreurs de téléchargement sur le Web.

 url <- c( "http://stat.ethz.ch/R-manual/R-devel/library/base/html/connections.html", "http://en.wikipedia.org/wiki/Xz") y <- mapply(readLines, con=url) 

Ces deux instructions s’exécutent avec succès. Ci-dessous, je crée une adresse Web non existante:

 url <- c("xxxxx", "http://en.wikipedia.org/wiki/Xz") 

url[1] n’existe pas. Comment on écrit une boucle trycatch (fonction) pour que:

  1. Lorsque l’URL est incorrecte, la sortie sera la suivante: “l’URL Web est incorrecte, impossible d’obtenir”.
  2. Lorsque l’URL est incorrecte, le code ne s’arrête pas, mais continue à être téléchargé jusqu’à la fin de la liste des URL?

Eh bien: bienvenue dans le monde R 😉

Voici

Mise en place du code

 urls <- c( "http://stat.ethz.ch/R-manual/R-devel/library/base/html/connections.html", "http://en.wikipedia.org/wiki/Xz", "xxxxx" ) readUrl <- function(url) { out <- tryCatch( { # Just to highlight: if you want to use more than one # R expression in the "try" part then you'll have to # use curly brackets. # 'tryCatch()' will return the last evaluated expression # in case the "try" part was completed successfully message("This is the 'try' part") readLines(con=url, warn=FALSE) # The return value of `readLines()` is the actual value # that will be returned in case there is no condition # (eg warning or error). # You don't need to state the return value via `return()` as code # in the "try" part is not wrapped insided a function (unlike that # for the condition handlers for warnings and error below) }, error=function(cond) { message(paste("URL does not seem to exist:", url)) message("Here's the original error message:") message(cond) # Choose a return value in case of error return(NA) }, warning=function(cond) { message(paste("URL caused a warning:", url)) message("Here's the original warning message:") message(cond) # Choose a return value in case of warning return(NULL) }, finally={ # NOTE: # Here goes everything that should be executed at the end, # regardless of success or error. # If you want more than one expression to be executed, then you # need to wrap them in curly brackets ({...}); otherwise you could # just have written 'finally=' message(paste("Processed URL:", url)) message("Some other message at the end") } ) return(out) } 

Appliquer le code

 > y <- lapply(urls, readUrl) Processed URL: http://stat.ethz.ch/R-manual/R-devel/library/base/html/connections.html Some other message at the end Processed URL: http://en.wikipedia.org/wiki/Xz Some other message at the end URL does not seem to exist: xxxxx Here's the original error message: cannot open the connection Processed URL: xxxxx Some other message at the end Warning message: In file(con, "r") : cannot open file 'xxxxx': No such file or directory 

Recherche de la sortie

 > head(y[[1]]) [1] "" [2] "R: Functions to Manipulate Connections" [3] "" [4] "" [5] "" [6] "" > length(y) [1] 3 > y[[3]] [1] NA 

Remarque additionnelle

essayerCatch

tryCatch renvoie la valeur associée à l'exécution de expr sauf en cas d'erreur ou d'avertissement. Dans ce cas, des valeurs de retour spécifiques (voir return(NA) ci-dessus) peuvent être spécifiées en fournissant une fonction de gestionnaire respective (voir les arguments error et warning dans ?tryCatch ). Celles-ci peuvent être des fonctions qui existent déjà, mais vous pouvez également les définir dans tryCatch() comme je l'ai fait ci-dessus.

Les implications du choix de valeurs de retour spécifiques pour les fonctions du gestionnaire

Comme nous avons spécifié que NA devrait être renvoyé en cas d'erreur, le troisième élément de y est NA . Si nous avions choisi NULL comme valeur de retour, la longueur de y aurait simplement été 2 au lieu de 3 car lapply() ignorera simplement les valeurs de retour NULL . Notez également que si vous ne spécifiez pas de valeur de retour explicite via return() , les fonctions du gestionnaire NULL (c'est-à-dire en cas d'erreur ou de condition d'avertissement).

Message d'avertissement "indésirable"

Comme warn=FALSE ne semble pas avoir d'effet, une autre façon de supprimer l'avertissement (qui dans ce cas n'est pas vraiment intéressant) est d'utiliser

 suppressWarnings(readLines(con=url)) 

au lieu de

 readLines(con=url, warn=FALSE) 

Plusieurs expressions

Notez que vous pouvez également placer plusieurs expressions dans la "partie expressions réelles" (argument expr de tryCatch() ) si vous les placez entre des accolades (comme je l'ai illustré dans la partie tryCatch() ).

R utilise des fonctions pour implémenter le bloc try-catch:

La syntaxe ressemble à ceci:

 result = tryCatch({ expr }, warning = function(warning_condition) { warning-handler-code }, error = function(error_condition) { error-handler-code }, finally={ cleanup-code }) 

Dans tryCatch (), deux «conditions» peuvent être gérées: «avertissements» et «erreurs». L’important à comprendre lors de l’écriture de chaque bloc de code est l’état d’exécution et la scope. @la source

Voici un exemple simple :

 # Do something, or tell me why it failed my_update_function <- function(x){ tryCatch( # This is what I want to do: y = x * 2 return(y) , # ... but if an error occurs, tell me what happened: error=function(error_message) { message("My message is here!") message("And below is the error message from R:") message(error_message) return(NA) } ) } 

Si vous souhaitez également capturer un "avertissement", ajoutez simplement un warning= similaire à l' error= partie.

Comme je viens de perdre deux jours de ma vie en essayant de résoudre pour tryCatch pour une fonction irr, j’ai pensé que je devais partager ma sagesse (et ce qui manque). FYI – irr est une fonction réelle de FinCal dans ce cas où il y avait des erreurs dans quelques cas sur un grand dataset.

  1. Configurez tryCatch dans le cadre d’une fonction. Par exemple:

     irr2 <- function (x) { out <- tryCatch(irr(x), error = function(e) NULL) return(out) } 
  2. Pour que l'erreur (ou l'avertissement) fonctionne, vous devez créer une fonction. A l'origine, pour la partie d'erreur, j'ai écrit error = return(NULL) et TOUTES les valeurs sont revenues nulles.

  3. N'oubliez pas de créer une sous-sortie (comme mon "out") et de return(out) .