Hat jemand Beispiele / Tutorials zur Ausnahmebehandlung in R? Die offizielle Dokumentation ist sehr knapp.
Hat jemand Beispiele / Tutorials zur Ausnahmebehandlung in R? Die offizielle Dokumentation ist sehr knapp.
Antworten:
Neben der Antwort von Shane, die Sie auf andere StackOverflow-Diskussionen verweist, können Sie auch eine Codesuchfunktion ausprobieren. Diese ursprüngliche Antwort, die auf die Codesuche von Google verweist, wurde inzwischen eingestellt, aber Sie können es versuchen
Nur für die Aufzeichnung gibt es auch try
, tryCatch
kann aber vorzuziehen sein. Ich habe versucht, bei der Google-Codesuche schnell zu zählen, aber bei dem Versuch werden zu viele Fehlalarme für das Verb selbst angezeigt - es scheint tryCatch
jedoch weit verbreitet zu sein.
Grundsätzlich möchten Sie die tryCatch()
Funktion nutzen. Weitere Informationen finden Sie in der Hilfe ("tryCatch").
Hier ist ein triviales Beispiel (denken Sie daran, dass Sie mit einem Fehler tun können, was Sie wollen):
vari <- 1
tryCatch(print("passes"), error = function(e) print(vari), finally=print("finished"))
tryCatch(stop("fails"), error = function(e) print(vari), finally=print("finished"))
Schauen Sie sich diese verwandten Fragen an:
Dieses Ergebnis einer verwandten Google-Suche hat mir geholfen: http://biocodenv.com/wordpress/?p=15 .
for(i in 1:16){
result <- try(nonlinear_modeling(i));
if(class(result) == "try-error") next;
}
Die Funktion trycatch()
ist ziemlich einfach und es gibt viele gute Tutorials dazu. Eine ausgezeichnete Erklärung für die Fehlerbehandlung in R findet sich in Hadley Wickhams Buch Advanced-R . Das Folgende ist eine sehr grundlegende Einführung in withCallingHandlers()
und withRestarts()
in so wenigen Worten wie möglich:
Nehmen wir an, ein Programmierer auf niedriger Ebene schreibt eine Funktion zur Berechnung des Absolutwerts. Er ist sich nicht sicher, wie er es berechnen soll, weiß aber, wie man einen Fehler konstruiert, und vermittelt fleißig seine Naivität:
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)
}
Ein Programmierer mittlerer Ebene schreibt auch eine Funktion zur Berechnung des Absolutwerts, wobei er die leider unvollständige low_level_ABS
Funktion verwendet. Er weiß, dass der Low-Level-Code einen negative_value
Fehler auslöst, wenn der Wert von x
negativ ist, und schlägt eine Lösung für das Problem vor, indem er einen Wert festlegt restart
, mit dem Benutzer mid_level_ABS
steuern können, wie mid_level_ABS
ein negative_value
Fehler behoben wird (oder nicht) .
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)
}
Schließlich verwendet ein übergeordneter Programmierer die mid_level_ABS
Funktion, um den Absolutwert zu berechnen, und erstellt einen Bedingungshandler, der
den Benutzer auffordert, mid_level_ABS
einen negative_value
Fehler mithilfe des Neustarthandlers zu beheben.
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)
}
Der Sinn all dessen ist, dass die Funktion
mithilfe von withRestarts()
und feststellen konnte, wie Fehler behoben werden können, die durch Fehler ausgelöst wurden, ohne die Ausführung von zu stoppen.
Dies ist etwas, mit dem Sie nichts anfangen können :withCallingHandlers()
high_level_ABS
mid_level_ABS
low_level_ABS
mid_level_ABS
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
In der Praxis low_level_ABS
stellt dies eine Funktion dar, mid_level_ABS
die häufig aufgerufen wird (möglicherweise sogar millionenfach), wobei die korrekte Methode zur Fehlerbehandlung je nach Situation variieren kann und die Wahl der Behandlung bestimmter Fehler den Funktionen höherer Ebenen überlassen bleibt ( high_level_ABS
).
Die Neustartfunktion ist in R, das von Lisp geerbt wurde, sehr wichtig. Dies ist nützlich, wenn Sie eine Funktion im Schleifenkörper aufrufen möchten und das Programm nur fortgesetzt werden soll, wenn der Funktionsaufruf zusammenbricht. Versuchen Sie diesen 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(){})