2013-07-24 3 views
49

У меня есть программа, которая выполняет некоторый анализ данных и составляет несколько сотен строк.break/exit script

Очень рано в программе, я хочу сделать некоторый контроль качества, и если данных недостаточно, я хочу, чтобы программа завершилась и вернулась в консоль R. В противном случае я хочу, чтобы остальная часть кода выполнялась.

Я попытался break, browser и quit и ни один из них не остановить выполнение остальной части программы (и quit останавливает выполнение, а также полностью бросить курить R, который не то, что я хочу, чтобы это произошло). Мой последний курорт создает if-else заявление, как показано ниже:

if(n < 500){} 
else{*insert rest of program here*} 

но, похоже, плохая практика кодирования. Я что-то упускаю?

+3

'quit', безусловно, останавливает выполнение остальной части программы. Укажите [воспроизводимый пример] (http://stackoverflow.com/q/5963269/271616). –

+0

@JakeBurkhead - это мой код выше (с пустым оператором if), лучший способ пойти, тогда? @Joshua Ulrich, 'quit' выходит из всех R, но я хочу вернуться в консоль R, потому что программа должна оставаться открытой для моих целей. – user2588829

+0

Что вы подразумеваете под программой? Вы имеете в виду, что вы используете функцию, которую вы написали, или вы используете источник в сценарии? –

ответ

42

Вы можете использовать функцию stopifnot(), если вы хотите, чтобы программа выдавать ошибку:

foo <- function(x) { 
    stopifnot(x > 500) 
    # rest of program 
} 
+0

+1! Я полагаю, что функция 'foo' должна быть названа началом скрипта и содержать другой контроль проверки ... – agstudy

+7

' stopifnot' удобен, но обработанный ответ с использованием 'if (x <500) {stop (" Not достаточно предположений в 'x': n <500 ")}'. Кроме того, если это что-то для пакетного задания, полезно использовать проблему * без * выброса ошибки. –

+3

Прекратите пытаться запутать ОП. То, что он хочет, это quit() или stop(), а не stopifnot(). – stackoverflowuser2010

10

реверсировать если-то еще конструкция:

if(n >= 500) { 
    # do stuff 
} 
# no need for else 
+0

достаточно просто, и я думаю, это может быть лучшим, что я могу сделать, спасибо – user2588829

6

Edit: Кажется, что OP работает длинный сценарий, в этом случае нужно только, чтобы обернуть часть сценария после контроля качества с

if (n >= 500) { 

.... long running code here 

} 

Если вспыхивают из функции, вы, вероятно, просто хочу return() явно или implici ждение.

Например, явный двойной обратного

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 
+0

Я тоже думал об этом, но неясно, что OP говорит о выходе из функции. – Thomas

+0

Да, Томас прав - я не говорю о выходе из функции. – user2588829

+1

@ user2588829 Вам будет гораздо лучше помещать это как функцию в R, а не в 100-строчный скрипт. –

-1

Здесь:

if(n < 500) 
{ 
    # quit() 
    # or 
    # stop("this is some message") 
} 
else 
{ 
    *insert rest of program here* 
} 

Оба выхода() и остановка (сообщение) прекратит ваш скрипт. Если вы используете сценарий из командной строки R, то quit() также выйдет из R.

+5

Неплохая практика публикации ответов, дублирующих уже опубликованные. – Thomas

+0

@ Томас, который отвечает, дублирует? Я вижу только этот ответ, используя как stop, так и quit, и фактически объясняя разницу между ними. – Evert

+0

@Thomas: Объясните, какой ответ ответит на мой вопрос. – stackoverflowuser2010

1

Вы можете использовать функцию pskill в пакете «tools» R, чтобы прервать текущий процесс и вернуться на консоль. Конкретно, у меня есть следующая функция, определенная в загрузочном файле, который я запускаю в начале каждого скрипта. Однако вы также можете скопировать его непосредственно в начале вашего кода. Затем вставьте 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) 
} 
+0

> pskill (processId, SIGINT) закрывает сессию и даже вытесняет пользователя из RStudio. Это довольно опасно, но функционально .... – Espanta

+0

Не знал, что это приведет к краху RStudio, но та же проблема обсуждается в: http://stackoverflow.com/questions/32820534/invoke-interrupt-from-r-code On linux, хотя, мое решение работает отлично. Его преимущество перед stopifnot заключается в том, что сообщение об ошибке stopifnot() не отображается. –

+0

Я проверил на Windows, и он ведет себя безумно. Спасибо, в любом случае. Мне нравится пскилл. – Espanta

2

Возможно, вы просто хотите прекратить выполнение длинного сценария в какой-то момент. то есть. например, вы хотите жестко закодировать exit() в C или Python.

print("this is the last message") 
stop() 
print("you should not see this") 
+0

Для этого кода я получаю сообщение об ошибке 'Ошибка в eval (expr, envir, enclos):'. – jochen

+0

Действительно. Но он останавливается, не так ли? – netskink

+2

Да, исполнение действительно прекращается. По совпадению, если вы замените 'stop()' на 'exit()' или 'please.stop.now()', скрипт также остановится (только сообщения об ошибках, конечно, разные). – jochen

4

Не очень, но вот способ реализовать 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, а затем сценарий прерывается без сообщения об ошибке.

+0

Недостатком является то, что он не разрешен для кода в пакете CRAN. Поэтому, если вы намерены использовать в пакете, который вы хотите загрузить в CRAN, он даст предупреждение в 'R CMD CHECK'. –

+0

Да, это больше похоже на системную функцию. Это может сломаться, если внутренние детали интерпретатора будут изменены, поэтому может быть лучше частью ядра R, а не отдельным пакетом? Я нашел это, следуя различным путям через исходный код R, чтобы увидеть, как я могу закончить работу в правильном месте, чтобы выйти из интерпретатора без сообщения об ошибке. Не было так много способов найти там; поэтому я использую '.invokeRestart', который, в свою очередь, кажется, нуждается в' .Internal'. – jochen

+0

О да, кроме политики CRAN, я думаю, что это приятное решение! Позвольте мне доставить вам +10 репутации;) –

Смежные вопросы