Äquivalent von "werfen" in R.

138

Wie "wirft" man einen Fehler in R? Ich habe eine Funktion, die einen Datenrahmen und einige Spaltennamen nimmt und Sachen damit macht. Wenn die Spalten nicht vorhanden sind, soll die Funktion gestoppt werden und alle Funktionen abhängig davon gestoppt werden.

Ich habe angeschaut recoverund browseund tracebackdoch, nun, sie schienen nahe zu sein, aber nicht das, wonach ich suche.

Gabel und warten
quelle
2
Richtig, Wiederherstellen, Browser und Traceback dienen zum Debuggen, während Try / Catch-Systeme zur Behandlung von Fehlern im Produktionscode dienen.
Harlan
20
Ich liebe es, wenn Fragesteller den Namen der Funktion, nach der sie suchen, mehrmals in einer Frage verwenden;)
hadley

Antworten:

112

Siehe help(tryCatch):

Bedingungen werden durch ' signalCondition' signalisiert . Darüber hinaus wurden die Funktionen
' stop' und ' warning' geändert, um auch
Bedingungsargumente zu akzeptieren .

und später unter "Siehe auch":

' stop' und ' warning' Signalbedingungen, und ' try' ist im Wesentlichen eine vereinfachte Version von ' tryCatch'.

also willst du wahrscheinlich stop.

Dirk Eddelbuettel
quelle
24
Das funktioniert perfekt. R ist so seltsam, ohne eigenes Verschulden - es wurde entworfen, lange bevor wir gut interpretiertes Sprachdesign ausgebügelt haben.
Forkandwait
5
Laut den Autoren wurde es stark von Scheme beeinflusst, das sowohl alt als auch gut ist. R ist "lispy", aber mit funky Datenstrukturen. Die "interessanten" Teile in R hängen wahrscheinlich damit zusammen, dass sich viele Konventionen von anderen Sprachen unterscheiden, insbesondere die C-Sprachfamilie, die auch syntaktisch eng ist. Ich würde raten, weil die Sprache von einer Reihe von Statistikern entwickelt wurde, die ein gutes Werkzeug brauchten, anstatt von Entwicklern, die ein gutes Werkzeug brauchten. Allein die Tatsache, dass der 'Punkt' nur ein Charakter ist, hat lange
gedauert
4
Einige grundlegende Beispiele hier wären großartig, nicht nur Zitate. Hier stackoverflow.com/a/23917007/54964
Léo Léopold Hertz 30
48

Einfaches Beispiel:

f <- function(a, b){ 

    if (a == 0){ 
            stop("error message")
    }
 }
Christian Herrera Jiménez
quelle
Hier stackoverflow.com/a/23917007/54964 für Variablen in den Fehlermeldungen.
Léo Léopold Hertz 준영
8

Über die von Dirk erwähnten Basisfunktionen hinaus:

Das R.oo-Paket verfügt über zusätzliche Funktionen zur Ausnahmebehandlung, einschließlich einer throw () -Funktion, die sehr nützlich ist. Sie können Ausnahmen mit den üblichen try- oder trycatch-Funktionen abfangen:

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

Sie können hier mehr darüber lesen: http://www1.maths.lth.se/help/R/R.oo/

Shane
quelle
8
Hehe. R ist ohne OO nicht funky genug? Tut mir leid, dass ich umgedreht habe, und auf jeden Fall danke für die interessante Antwort, aber ich werde mit einfachem altem stop () oben gehen.
Forkandwait
1
Es gibt jetzt noch mehr OO. :)
Iterator
3
@ws. Was ist so funky an R? plotZeichnet eine Funktion, try stop warnalle funktionieren wie erwartet, und fast alles, was ich tun möchte, ist ein Einzeiler.
Isomorphismen
4
Oft ist "Power of One-Liner" keine gute Metrik für eine Sprache. Für viele von uns übertrifft lesbarer, verständlicher Code weniger Zeilen. In der Tat ist vieles für mich unverständlich, weil ich ein Anfänger bin und ich versuche, die Erwartungen entsprechend zu kalibrieren. Aber andere Sprachen machen es ziemlich intuitiv, von 0 zu wechseln, um Dinge zu erledigen. R scheint auch eine Kultur kluger, schwer lesbarer Einzeiler entwickelt zu haben. Ich würde für eine Kultur von maximal englischsprachigem Code eintreten, der oft auch Einzeiler sein kann, wie Ruby.
Philip
5

Tatsächlich ist die Funktion stopifnotsehr praktisch, um Sanity Checks in Ihrem Code zu implementieren. Es nimmt mehrere logische Ausdrücke auf und gibt einen Fehler zurück, wenn einer von ihnen als falsch ausgewertet wird.

Beispiel: So überprüfen Sie, ob die Spalte 'c' im Datenrahmen 'df' vorhanden ist:

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

Dies löst den folgenden Fehler aus:

Error: !is.null(df$c) is not TRUE
Chris
quelle
1

Sie können überprüfen, ob die Spalte vorhanden ist, und tun, was Sie wollen.
Angenommen, eine data.framebenannte df1und prüfende Spalte col1:

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

oder

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

Zum Beispiel

xm1
quelle