Traitement des exceptions en R [fermé]
quelqu'un aurait-il des exemples/tutoriels de la gestion des exceptions dans R? La documentation officielle est très laconique.
5 réponses
outre la réponse de Shane vous indiquant d'autres discussions StackOverflow, vous pouvez essayer une fonction de recherche de code. Cette réponse originale pointée sur la recherche de code de Google a depuis été discontinué, mais vous pouvez essayer
- Github recherche comme par exemple dans cette requête pour tryCatch en langue=R ;
- Ohloh/Blackduck la recherche d'un Code eg cette requête pour tryCatch dans la R de fichiers
- le moteur de recherche de code Debian en haut de L'archive Debian
juste pour information, il y a aussi try
mais tryCatch
peut être préférable. J'ai essayé un comptage rapide à la recherche de code Google mais try obtient trop de faux positifs pour le verbe lui-même -- pourtant il semble tryCatch
est plus largement utilisé.
fondamentalement, vous voulez utiliser la fonction tryCatch()
. Regardez l'aide ("tryCatch") pour plus de détails.
Voici un exemple trivial (gardez à l'esprit que vous pouvez faire ce que vous voulez avec une erreur):
vari <- 1
tryCatch(print("passes"), error = function(e) print(vari), finally=print("finished"))
tryCatch(stop("fails"), error = function(e) print(vari), finally=print("finished"))
jetez un oeil à ces questions reliées:
ce résultat d'une recherche connexe de google m'a aidé: http://biocodenv.com/wordpress/?p=15 .
for(i in 1:16){
result <- try(nonlinear_modeling(i));
if(class(result) == "try-error") next;
}
la fonction de redémarrage est très importante dans R hérité de Lisp. Il est utile si vous voulez appeler une fonction dans le corps de la boucle et vous voulez juste le programme de continuer si l'appel de la fonction s'effondre. Essayez ce code:
for (i in 1:20) withRestarts(tryCatch(
if((a <- runif(1))>0.5) print(a) else stop(a),
finally = print("loop body finished!")),
abort = function(){})
La fonction trycatch()
est assez simple, et il y a beaucoup de bons tutoriels sur le sujet. Une excellente explication du traitement des erreurs en R peut être trouvée dans le livre de Hadley Wickham Advanced-R , et ce qui suit est un très introduction de base à withCallingHandlers()
et withRestarts()
en aussi peu de mots que possible:
disons qu'un programmeur de bas niveau écrit une fonction pour calculer l'absolu valeur. Il n'est pas sûr comment le calculer, mais sait comment construire un erreur et il communique avec diligence sa naïveté:
low_level_ABS <- function(x){
if(x<0){
#construct an error
negative_value_error <- structure(
# with class `negative_value`
class = c("negative_value","error", "condition"),
list(message = "Not Sure what to with a negative value",
call = sys.call(),
# and include the offending parameter in the error object
x=x))
# raise the error
stop(negative_value_error)
}
cat("Returning from low_level_ABS()\n")
return(x)
}
un programmeur de niveau moyen écrit également une fonction pour calculer la valeur absolue, faisant usage de la fonction tristement incomplète low_level_ABS
. Il sait que le code bas niveau lance un negative_value
erreur lorsque la valeur de x
est négative et suggère une solution au problème, par
établissant un restart
qui permet aux utilisateurs de mid_level_ABS
de contrôler le
la façon dont mid_level_ABS
récupère (ou ne récupère pas) d'une erreur negative_value
.
mid_level_ABS <- function(y){
abs_y <- withRestarts(low_level_ABS(y),
# establish a restart called 'negative_value'
# which returns the negative of it's argument
negative_value_restart=function(z){-z})
cat("Returning from mid_level_ABS()\n")
return(abs_y)
}
enfin, un programmeur de haut niveau utilise la fonction mid_level_ABS
pour calculer
la valeur absolue, et établit un gestionnaire de conditions qui dit
mid_level_ABS
pour récupérer d'une erreur negative_value
en utilisant le redémarrage
manipulateur.
high_level_ABS <- function(z){
abs_z <- withCallingHandlers(
# call this function
mid_level_ABS(z) ,
# and if an `error` occurres
error = function(err){
# and the `error` is a `negative_value` error
if(inherits(err,"negative_value")){
# invoke the restart called 'negative_value_restart'
invokeRestart('negative_value_restart',
# and invoke it with this parameter
err$x)
}else{
# otherwise re-raise the error
stop(err)
}
})
cat("Returning from high_level_ABS()\n")
return(abs_z)
}
le point de tout cela est qu'en utilisant withRestarts()
et withCallingHandlers()
, la fonction
high_level_ABS
a pu dire mid_level_ABS
comment récupérer des erreurs
par erreur low_level_ABS
sans arrêter l'exécution de
mid_level_ABS
, ce qui est quelque chose que vous ne pouvez pas faire avec tryCatch()
:
> high_level_ABS(3)
Returning from low_level_ABS()
Returning from mid_level_ABS()
Returning from high_level_ABS()
[1] 3
> high_level_ABS(-3)
Returning from mid_level_ABS()
Returning from high_level_ABS()
[1] 3
dans la pratique, low_level_ABS
représente une fonction que mid_level_ABS
appelle
lot (peut-être même des millions de fois), pour lequel la bonne méthode d'erreur
la manipulation peut varier par la situation et le choix de la façon de gérer les erreurs spécifiques est
à gauche vers les fonctions de niveau supérieur ( high_level_ABS
).