У меня есть программа, которая выполняет некоторый анализ данных и состоит из нескольких сотен строк.
В самом начале программы я хочу провести некоторый контроль качества и, если данных недостаточно, я хочу, чтобы программа завершилась и вернулась в консоль R. В противном случае я хочу, чтобы остальная часть кода выполнялась.
Я попробовал break
, browser
и quit
ни один из них не остановить выполнение остальной части программы (и quit
останавливает выполнение, а также полностью бросить курить R, который не то , что я хочу , чтобы это произошло). Мое последнее средство - создать if-else
заявление, как показано ниже:
if(n < 500){}
else{*insert rest of program here*}
но это похоже на плохую практику программирования. Я что-то упускаю?
quit
наверняка останавливает выполнение остальной части программы. Приведите воспроизводимый пример .quit
выходит из R, но я хочу вернуться к консоли R, потому что программа должна оставаться открытой для моих целей.Ответы:
Вы можете использовать эту
stopifnot()
функцию, если хотите, чтобы программа выдавала ошибку:foo <- function(x) { stopifnot(x > 500) # rest of program }
источник
foo
должна вызываться в начале скрипта и содержать другой контроль валидации ...stopifnot
удобен, ноif(x < 500) { stop("Not enough observations in 'x': n < 500")}
может быть предпочтительнее использовать подготовленный ответ . Кроме того, если это что-то для пакетного задания, полезно решить проблему без выдачи ошибки.quit
(см вопрос!) Я даже не думаю , чтоstop
вstopifnot
это лучший способ справиться с этим;stop
выдает ошибку, весь скрипт просто прерывается. В то время какstopifnot
(илиstop
) кажется наиболее предпочтительным OP для ответа, написание функции для выхода без ошибок более полезно в более широком диапазоне ситуаций. После написания множества долго выполняющихся сценариев для больших заданий анализа данных нет ничего более раздражающего, чем функции, которые выдают ошибки вместо того, чтобы обрабатывать проблему и возвращать ее чисто. Но ясно, что я не знаю, о чем говорю ...stop("my message")
меня распечатывают в терминалеError: "my message" Execution halted
. Итак, это показывает вывод сообщения об ошибке, но вы говорите, что он не "выдает" ошибку? (т.е. он не остановит пакетное задание, которое было настроено на прерывание, если какой-либо из вызываемых им скриптов выдает ошибку). Благодаря! (Прямо сейчас я вызываю сценарий с помощью Rscript)Не очень красиво, но вот способ реализовать
exit()
команду в R, которая мне подходит .exit <- function() { .Internal(.invokeRestart(list(NULL, NULL), NULL)) } print("this is the last message") exit() print("you should not see this")
Только слегка протестировано, но когда я запускаю это, я вижу,
this is the last message
а затем сценарий прерывается без каких-либо сообщений об ошибке.источник
R CMD CHECK
..invokeRestart
который, в свою очередь, мне нужен.Internal
.exit <- function() { invokeRestart("abort") }
Измените конструкцию if-else:
if(n >= 500) { # do stuff } # no need for else
источник
Изменить: похоже, что OP запускает длинный скрипт, в этом случае нужно только обернуть часть скрипта после контроля качества с помощью
if (n >= 500) { .... long running code here }
Если вы выходите из функции , вы, вероятно, просто захотите
return()
, явно или неявно.Например, явный двойной возврат
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
Под
return()
подразумеваемым я подразумеваю, что последняя строка выглядит так, как будто вы это сделалиreturn(xx)
, но немного эффективнее прекратить вызовreturn()
.Некоторые считают использование нескольких возвратов плохим стилем; в длинных функциях отслеживание места выхода из функции может стать трудным или привести к ошибкам. Следовательно, альтернативой является наличие одной точки возврата, но изменение объекта возврата с помощью
if () else ()
предложения. Такая модификацияfoo()
будетfoo <- 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
источник
myFun(arg1, arg2, arg3)
и т. Д. Это просто гораздо лучший способ организации вещей.Возможно, вы просто захотите в какой-то момент прекратить выполнение длинного скрипта. т.е. например, вы хотите жестко закодировать exit () на C или Python.
print("this is the last message") stop() print("you should not see this")
источник
Error in eval(expr, envir, enclos) :
.stop()
наexit()
илиplease.stop.now()
, скрипт также остановится (разумеется, отличаются только сообщения об ошибках).stop()
команды может помочь отличить эту «ошибку» от других сообщений. Например:stop("Manual break inserted here")
может быть более информативным, чем вstop()
одиночку.Это старый вопрос, но чистого решения пока нет. Вероятно, это не ответ на этот конкретный вопрос, но те, кто ищет ответы о том, «как изящно выйти из сценария R», вероятно, попадут сюда. Похоже, что разработчики R забыли реализовать функцию exit (). Во всяком случае, трюк, который я нашел:
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")
По сути, вы используете флаг, чтобы указать продолжение или нет определенного блока кода. Затем вы используете
stop()
функцию для передачи настроенного сообщения обработчику ошибокtryCatch()
функции. Если обработчик ошибок получает ваше сообщение для корректного завершения, то он просто игнорирует ошибку и устанавливает флаг продолженияFALSE
.источник
Вы можете использовать
pskill
функцию изR
пакета "tools", чтобы прервать текущий процесс и вернуться в консоль. В частности, у меня есть следующая функция, определенная в файле запуска, который я использую в начале каждого скрипта. Однако вы также можете скопировать его прямо в начало вашего кода. Затем вставьтеhalt()
в любой момент своего кода, чтобы остановить выполнение скрипта на лету. Эта функция хорошо работает в GNU / Linux и, судя поR
документации, должна работать и в Windows (но я не проверял).# 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) }
источник
Вот:
if(n < 500) { # quit() # or # stop("this is some message") } else { *insert rest of program here* }
Оба
quit()
иstop(message)
выйдут из вашего скрипта. Если вы загружаете свой скрипт из командной строки R, тоquit()
вы также выйдете из R.источник
stop()
, и OP уже указал в комментариях, что они не хотятquit()
...