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.

96
demandé sur gappy 2010-04-12 18:26:28

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

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é.

30
répondu Dirk Eddelbuettel 2014-09-22 14:22:44

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:

59
répondu Shane 2017-05-23 12:02:56

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;
}
21
répondu isomorphismes 2011-09-13 06:38:03

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(){})
7
répondu Xin Guo 2012-08-19 07:13:37

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 ).

6
répondu Jthorpe 2016-03-10 00:46:43