Mam program, który analizuje dane i ma kilkaset wierszy.
Na bardzo wczesnym etapie programu chcę przeprowadzić kontrolę jakości, a jeśli nie ma wystarczającej ilości danych, chcę, aby program zakończył działanie i powrócił do konsoli R. W przeciwnym razie chcę wykonać resztę kodu.
Próbowałem break
, browser
i quit
żaden z nich nie zatrzymać wykonanie pozostałej części programu (i quit
zatrzymuje wykonanie, jak również całkowicie porzuceniem R, który nie jest coś, co chcę się zdarzyć). Moją ostatecznością jest stworzenie if-else
oświadczenia jak poniżej:
if(n < 500){}
else{*insert rest of program here*}
ale wydaje się to złą praktyką kodowania. Czy coś mi brakuje?
quit
z całą pewnością zatrzymuje wykonywanie reszty programu. Proszę podać odtwarzalny przykład .quit
całe R, ale chcę wrócić do konsoli R, ponieważ program musi pozostać otwarty do moich celów.Odpowiedzi:
Możesz użyć tej
stopifnot()
funkcji, jeśli chcesz, aby program generował błąd:foo <- function(x) { stopifnot(x > 500) # rest of program }
źródło
foo
powinna się nazywać początkiem skryptu i zawierać inne kontrolki walidacji ...stopifnot
jest przydatne, aleif(x < 500) { stop("Not enough observations in 'x': n < 500")}
preferowana może być spreparowana odpowiedź przy użyciu . Ponadto, jeśli jest to coś dla zadania wsadowego, przydatne jest rozwiązanie problemu bez zgłaszania błędu.quit
(patrz pytanie!) Nawet nie myślęstop
ostopifnot
najlepszym sposobie rozwiązania tego problemu ;stop
zgłasza błąd, cały skrypt zostanie po prostu przerwany. Chociażstopifnot
(lubstop
) wydaje się być najbardziej lubianym przez Answer OP, napisanie funkcji, która kończy się czysto, bez błędów, jest bardziej korzystne w szerszym zakresie sytuacji. Po napisaniu wielu długotrwałych skryptów do zadań analizy dużych danych, nic nie jest bardziej irytujące niż funkcje, które generują błędy zamiast obsługiwać problem i zwracać je w sposób czysty. Ale najwyraźniej nie wiem, o czym mówię ...stop("my message")
pojawia się wydruk na terminaluError: "my message" Execution halted
. Więc to pokazuje wyjście komunikatu o błędzie, ale czy twierdzisz, że nie „zgłasza” błędu? (tj. nie zatrzyma zadania wsadowego, które zostało ustawione na przerwanie, jeśli którykolwiek ze skryptów, które wywołuje, zgłasza błędy). Dzięki! (Teraz jestem wywołanie skryptu z Rscript)Niezbyt ładne, ale tutaj jest sposób na zaimplementowanie
exit()
polecenia w R, które działa dla mnie.exit <- function() { .Internal(.invokeRestart(list(NULL, NULL), NULL)) } print("this is the last message") exit() print("you should not see this")
Tylko lekko przetestowane, ale kiedy to uruchomię, widzę,
this is the last message
a następnie skrypt przerywa pracę bez żadnego komunikatu o błędzie.źródło
R CMD CHECK
..invokeRestart
który z kolei wydaje się potrzebować pliku.Internal
.exit()
nie możesz zapobiec uruchomieniu następnego polecenia (które nie zostało jeszcze wprowadzone) ...Odwróć swoją konstrukcję if-else:
if(n >= 500) { # do stuff } # no need for else
źródło
Edycja: wydaje się, że OP uruchamia długi skrypt, w takim przypadku wystarczy owinąć część skryptu po kontroli jakości
if (n >= 500) { .... long running code here }
Jeśli wyjdziesz z funkcji , prawdopodobnie będziesz po prostu chciał
return()
, jawnie lub niejawnie.Na przykład jawny podwójny powrót
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
Mówiąc
return()
wprost, mam na myśli, że ostatnia linia wygląda tak, jakbyś skończyłreturn(xx)
, ale nieco bardziej efektywne jest przerwanie wywołaniareturn()
.Niektórzy uważają, że używanie wielu zwrotów jest złym stylem; w długich funkcjach śledzenie, gdzie kończy się funkcja, może być trudne lub podatne na błędy. Stąd alternatywą jest posiadanie pojedynczego punktu powrotu, ale zmiana obiektu zwracanego za pomocą
if () else ()
klauzuli. Taka modyfikacjafoo()
byłabyfoo <- 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
źródło
myFun(arg1, arg2, arg3)
itd. Jest to po prostu znacznie lepszy sposób organizowania rzeczy.Być może w pewnym momencie chcesz po prostu przestać wykonywać długi skrypt. to znaczy. tak jak chcesz na stałe zakodować exit () w C lub Pythonie.
print("this is the last message") stop() print("you should not see this")
źródło
Error in eval(expr, envir, enclos) :
.stop()
sięexit()
lubplease.stop.now()
skrypt zatrzymuje się (tylko komunikaty o błędach są oczywiście różne).stop()
poleceniu może pomóc odróżnić ten „błąd” od innych komunikatów. Na przykład:stop("Manual break inserted here")
może być bardziej pouczający niżstop()
sam.To stare pytanie, ale nie ma jeszcze czystego rozwiązania. To prawdopodobnie nie jest odpowiedzią na to konkretne pytanie, ale ci, którzy szukają odpowiedzi na temat „jak wdzięcznie wyjść ze skryptu R”, prawdopodobnie wylądują tutaj. Wygląda na to, że programiści R zapomnieli o zaimplementowaniu funkcji exit (). W każdym razie sztuczka, którą znalazłem, to:
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")
Zasadniczo używasz flagi, aby wskazać kontynuację lub nie określonego bloku kodu. Następnie używasz
stop()
funkcji do przekazania dostosowanego komunikatu do programu obsługi błędówtryCatch()
funkcji. Jeśli program obsługi błędów otrzyma wiadomość, aby pomyślnie zakończyć pracę, po prostu zignoruje błąd i ustawia flagę kontynuacji naFALSE
.źródło
Możesz użyć
pskill
funkcji zR
pakietu "tools", aby przerwać bieżący proces i powrócić do konsoli. Konkretnie, mam następującą funkcję zdefiniowaną w pliku startowym, który pobieram na początku każdego skryptu. Możesz jednak skopiować go bezpośrednio na początku swojego kodu. Następnie wstawhalt()
w dowolnym miejscu kodu, aby zatrzymać wykonywanie skryptu w locie. Ta funkcja działa dobrze w systemie GNU / Linux i sądząc poR
dokumentacji, powinna również działać w systemie Windows (ale nie sprawdzałem).# 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) }
źródło
Tutaj:
if(n < 500) { # quit() # or # stop("this is some message") } else { *insert rest of program here* }
Obie
quit()
istop(message)
zamkną twój skrypt. Jeśli pozyskujesz skrypt z wiersza polecenia języka R,quit()
zamkniesz również program R.źródło
stop()
, a OP już wskazał w komentarzach, że nie chcąquit()
...