Équivalent de «lancer» dans R

141

Comment «lancer» une erreur dans R? J'ai une fonction qui prend un bloc de données et quelques noms de colonnes et fait des trucs avec eux. Si les colonnes n'existent pas, je veux que la fonction s'arrête et arrête toutes les fonctions qui en dépendent.

J'ai regardé recoveret browseet tracebackmais, eh bien, ils semblaient proches mais pas ce que je cherchais.

fourchette et attendre
la source
2
À droite, récupérer, navigateur et traceback sont destinés au débogage, tandis que les systèmes try / catch servent à gérer les erreurs dans le code de production.
Harlan
20
J'adore quand les poseurs de questions utilisent le nom de la fonction qu'ils recherchent plusieurs fois dans une question;)
hadley
Je pense qu'il y a une raison pour laquelle cette question a plus de votes positifs que la réponse principale. Même si cette autre question est techniquement hors sujet, c'est ce genre de résumé extrêmement serré d'un sujet inconnu pour lequel Stack Overflow est célèbre.
Josiah Yoder le

Réponses:

113

Voir help(tryCatch):

Les conditions sont signalées par ' signalCondition'. De plus, les fonctions
« stop» et « warning» ont été modifiées pour accepter également les
arguments de condition.

et plus tard sous 'Voir aussi':

" stop" et " warning" conditions de signal, et " try" est essentiellement une version simplifiée de " tryCatch".

donc vous voulez probablement stop.

Dirk Eddelbuettel
la source
24
Cela fonctionne parfaitement. R est tellement étrange, sans aucune faute de leur part - il a été conçu bien avant que nous ayons mis au point une bonne conception de langage interprété.
forkandwait
5
Selon les auteurs, il a été fortement influencé par Scheme, qui est à la fois ancien et bon. R est «lispy» mais avec des structures de données géniales. Les parties "intéressantes" de R sont probablement liées au fait que de nombreuses conventions diffèrent des autres langages, notamment la famille des langages C qui est également proche syntaxiquement. Je suppose que le langage a été développé par un groupe de statisticiens qui avaient besoin d'un bon outil, plutôt que par des développeurs ayant besoin d'un bon outil. Juste le fait que le «point» est juste un personnage a mis beaucoup de temps à prendre en compte.
KarlP
5
Quelques exemples de base ici seraient excellents, pas seulement des citations. Ici stackoverflow.com/a/23917007/54964
Léo Léopold Hertz 준영
Je suis arrivé à cette question en cherchant comment renvoyer une erreur dans R avec un message d'erreur plus sain, mais en gardant la trace intacte (comme dans, vous exécutez traceback()après l'erreur pour voir ce qui ne va pas). Utiliser stopen errorargument de tryCatchva gâcher la trace. Cependant, l' finallyargument permettra de lancer un message supplémentaire et de garder la trace utile. Pas exactement sur le sujet, mais, je pense, assez important pour justifier quelques inconvénients et une menace de modération expulsant ce commentaire de la fenêtre. :-)
Mali Remorker
50

Exemple simple:

f <- function(a, b){ 

    if (a == 0){ 
            stop("error message")
    }
 }
Christian Herrera Jiménez
la source
Ici stackoverflow.com/a/23917007/54964 pour les variables dans les messages d'erreur.
Léo Léopold Hertz 준영
8

Au-delà des fonctions de base que Dirk mentionne:

Le paquet R.oo a des fonctionnalités supplémentaires de gestion des exceptions, y compris une fonction throw () qui est très utile. Vous pouvez intercepter des exceptions avec les fonctions try ou trycatch habituelles:

> try(throw("Division by zero.")); print("It's ok!");
Error: [2009-10-22 10:24:07] Exception: Division by zero.
[1] "It's ok!"

Vous pouvez en savoir plus ici: http://www1.maths.lth.se/help/R/R.oo/

Shane
la source
8
Hehe. R n'est pas assez funky sans OO? Désolé d'être flip, et certainement merci pour la réponse intéressante, mais j'irai avec le vieil arrêt () ci-dessus.
forkandwait
1
Il y a encore plus d'OO maintenant. :)
Iterator
3
@ws. Qu'y a-t-il de si funky à propos de R? plottrace une fonction, try stop warntout fonctionne comme prévu, et presque tout ce que je veux faire est une ligne unique.
isomorphismes
4
Souvent, «la puissance des one-liners» n'est pas une bonne métrique pour une langue. Pour beaucoup d'entre nous, le code lisible et compréhensible l'emporte sur moins de lignes. En effet, beaucoup de choses sont incompréhensibles pour moi car je suis débutant, et j'essaye de calibrer les attentes en conséquence. Mais d'autres langages rendent assez intuitif le passage de 0 à l'exécution des tâches. R semble également avoir développé une culture des one-liners intelligents et difficiles à lire. Je plaiderais en faveur d'une culture de code de type anglais au maximum, qui pourrait souvent aussi être des one-liners, comme Ruby.
Philip
6

En fait, la fonction stopifnotest très pratique pour implémenter des vérifications de cohérence dans votre code. Il prend plusieurs expressions logiques et renvoie une erreur si l'une d'elles est évaluée à false.

Exemple: pour vérifier si la colonne 'c' existe dans le dataframe 'df':

df <- data.frame(a = numeric(), b = numeric())
stopifnot(!is.null(df$c))

Cela lancera l'erreur suivante:

Error: !is.null(df$c) is not TRUE
Chris
la source
Sonne comme Python's assert(...)...
Josiah Yoder
1

Vous pouvez vérifier si la colonne existe et faire ce que vous voulez.
Supposons une colonne data.framenommée df1et vérifiant si une colonne col1existe:

if(! any(grepl('^col1$',colnames(df1)))) stop("nonexistent column")

ou

if(! any(grepl('^col1$',colnames(df1)))) return(-1)

Par exemple

xm1
la source