Ich habe ein Programm, das einige Datenanalysen durchführt und einige hundert Zeilen lang ist.
Sehr früh im Programm möchte ich eine Qualitätskontrolle durchführen. Wenn nicht genügend Daten vorhanden sind, soll das Programm beendet werden und zur R-Konsole zurückkehren. Ansonsten möchte ich, dass der Rest des Codes ausgeführt wird.
Ich habe versucht break
, browser
und quit
keiner von ihnen die Ausführung der Rest des Programms stoppen (und quit
stoppt die Ausführung sowie vollständig beenden R, die nicht etwas , was ich passieren soll , ist). Mein letzter Ausweg ist die Erstellung einer if-else
Erklärung wie folgt :
if(n < 500){}
else{*insert rest of program here*}
aber das scheint eine schlechte Codierungspraxis zu sein. Vermisse ich etwas
quit
stoppt mit Sicherheit die Ausführung des restlichen Programms. Bitte geben Sie ein reproduzierbares Beispiel an .quit
alle R, aber ich möchte zur R-Konsole zurückkehren, da das Programm für meine Zwecke geöffnet bleiben muss.Antworten:
Sie können die
stopifnot()
Funktion verwenden, wenn das Programm einen Fehler erzeugen soll:foo <- function(x) { stopifnot(x > 500) # rest of program }
quelle
foo
sollte der Anfang des Skripts genannt werden und andere Validierungskontrollen enthalten ...stopifnot
ist praktisch, aber eine gestaltete Antwort mitif(x < 500) { stop("Not enough observations in 'x': n < 500")}
könnte bevorzugt werden. Wenn dies für einen Stapeljob gilt, ist es hilfreich , das Problem zu behandeln, ohne einen Fehler auszulösen.quit
(siehe Frage!) Ich glaube , nicht einmalstop
derstopifnot
ist der beste Weg , dies zu handhaben ;stop
Wenn ein Fehler ausgegeben wird, wird das gesamte Skript einfach abgebrochen. Währendstopifnot
(oderstop
) die Antwort zu sein scheint, die OP am besten gefällt, ist das Schreiben einer Funktion zum sauberen und fehlerfreien Beenden in einer größeren Anzahl von Situationen vorteilhafter. Nachdem Sie viele lang laufende Skripte für große Datenanalysejobs geschrieben haben, ist nichts ärgerlicher als Funktionen, die Fehler auslösen, anstatt das Problem zu behandeln und sauber zurückzukehren. Aber klar, ich weiß nicht, wovon ich spreche ...stop("my message")
ich in das Terminal gedrucktError: "my message" Execution halted
. Dies zeigt also eine Ausgabe einer Fehlermeldung, aber sagen Sie, dass sie keinen Fehler "auslöst"? (dh es wird kein Stapeljob gestoppt, der so eingestellt wurde, dass er abgebrochen wird, wenn eines der aufgerufenen Skripte Fehler auslöst). Vielen Dank! (Im Moment rufe ich das Skript mit Rscript auf)Nicht schön, aber hier ist eine Möglichkeit, einen
exit()
Befehl in R zu implementieren, der für mich funktioniert.exit <- function() { .Internal(.invokeRestart(list(NULL, NULL), NULL)) } print("this is the last message") exit() print("you should not see this")
Nur leicht getestet, aber wenn ich dies ausführe, sehe ich
this is the last message
und dann bricht das Skript ohne Fehlermeldung ab.quelle
R CMD CHECK
..invokeRestart
was dann wiederum das zu brauchen scheint.Internal
.exit()
kann dies natürlich nicht verhindern, dass der nächste Befehl (der noch nicht eingegeben wurde) ausgeführt wird ...Kehren Sie Ihre if-else-Konstruktion um:
if(n >= 500) { # do stuff } # no need for else
quelle
Vielleicht möchten Sie irgendwann einfach aufhören, ein langes Skript auszuführen. dh. Als ob Sie ein exit () in C oder Python hart codieren möchten.
print("this is the last message") stop() print("you should not see this")
quelle
Error in eval(expr, envir, enclos) :
.stop()
mitexit()
oderplease.stop.now()
das Skript stoppt auch (nur die Fehlermeldungen sind natürlich unterschiedlich).stop()
Befehls kann dazu beitragen, diesen "Fehler" von anderen Nachrichten zu unterscheiden. Zum Beispiel:stop("Manual break inserted here")
könnte informativer sein alsstop()
allein.Bearbeiten: Scheint, dass das OP ein langes Skript ausführt. In diesem Fall muss nur der Teil des Skripts nach der Qualitätskontrolle mit umbrochen werden
if (n >= 500) { .... long running code here }
Wenn Sie aus einer Funktion ausbrechen möchten Sie wahrscheinlich nur
return()
explizit oder implizit.Zum Beispiel eine explizite doppelte Rückgabe
foo <- function(x) { if(x < 10) { return(NA) } else { xx <- seq_len(x) xx <- cumsum(xx) } xx ## return(xx) is implied here } > foo(5) [1] 0 > foo(10) [1] 1 3 6 10 15 21 28 36 45 55
Mit
return()
impliziert meine ich, dass die letzte Zeile so ist, als ob Sie es getan hättenreturn(xx)
, aber es ist etwas effizienter, den Anruf an abzubrechenreturn()
.Einige erwägen, einen schlechten Stil für mehrere Rückgaben zu verwenden. Bei langen Funktionen kann es schwierig oder fehleranfällig werden, zu verfolgen, wo die Funktion beendet wird. Daher besteht eine Alternative darin, einen einzelnen Rückgabepunkt zu haben, das Rückgabeobjekt jedoch mithilfe der
if () else ()
Klausel zu ändern . Eine solche Änderungfoo()
wärefoo <- function(x) { ## out is NA or cumsum(xx) depending on x out <- if(x < 10) { NA } else { xx <- seq_len(x) cumsum(xx) } out ## return(out) is implied here } > foo(5) [1] NA > foo(10) [1] 1 3 6 10 15 21 28 36 45 55
quelle
myFun(arg1, arg2, arg3)
ist dies eine viel bessere Möglichkeit, Dinge zu organisieren.Dies ist eine alte Frage, aber es gibt noch keine saubere Lösung. Dies beantwortet wahrscheinlich nicht diese spezielle Frage, aber diejenigen, die nach Antworten suchen, wie man ein R-Skript ordnungsgemäß verlässt, werden wahrscheinlich hier landen. Es scheint, dass R-Entwickler vergessen haben, eine exit () -Funktion zu implementieren. Der Trick, den ich gefunden habe, ist:
continue <- TRUE tryCatch({ # You do something here that needs to exit gracefully without error. ... # We now say bye-bye stop("exit") }, error = function(e) { if (e$message != "exit") { # Your error message goes here. E.g. stop(e) } continue <<-FALSE }) if (continue) { # Your code continues here ... } cat("done.\n")
Grundsätzlich verwenden Sie ein Flag, um die Fortsetzung eines bestimmten Codeblocks anzuzeigen oder nicht. Anschließend verwenden Sie die
stop()
Funktion, um eine benutzerdefinierte Nachricht an den Fehlerbehandler einertryCatch()
Funktion zu übergeben. Wenn der Fehlerbehandler Ihre Nachricht zum ordnungsgemäßen Beenden erhält, ignoriert er den Fehler einfach und setzt das Fortsetzungsflag aufFALSE
.quelle
Mit der
pskill
Funktion imR
Paket "tools" können Sie den aktuellen Prozess unterbrechen und zur Konsole zurückkehren. Konkret habe ich die folgende Funktion in einer Startdatei definiert, die ich am Anfang jedes Skripts beziehe. Sie können es jedoch auch direkt am Anfang Ihres Codes kopieren. Fügen Sie dannhalt()
an einer beliebigen Stelle in Ihren Code ein, um die Skriptausführung im laufenden Betrieb zu stoppen. Diese Funktion funktioniert gut unter GNU / Linux und nach derR
Dokumentation sollte sie auch unter Windows funktionieren (aber ich habe es nicht überprüft).# halt: interrupts the current R process; a short iddle time prevents R from # outputting further results before the SIGINT (= Ctrl-C) signal is received halt <- function(hint = "Process stopped.\n") { writeLines(hint) require(tools, quietly = TRUE) processId <- Sys.getpid() pskill(processId, SIGINT) iddleTime <- 1.00 Sys.sleep(iddleTime) }
quelle
Hier:
if(n < 500) { # quit() # or # stop("this is some message") } else { *insert rest of program here* }
Beides
quit()
undstop(message)
wird Ihr Skript beenden. Wenn Sie Ihr Skript über die R-Eingabeaufforderung beziehen,quit()
wird R ebenfalls beendet.quelle
stop()
, und OP bereits in Kommentaren angegeben, dass sie nicht wollenquit()
...