web-dev-qa-db-ja.com

ブレーク/終了スクリプト

いくつかのデータ分析を行うプログラムがあり、長さは数百行です。

プログラムの非常に早い段階で、品質管理を行い、十分なデータがない場合は、プログラムを終了してRコンソールに戻ります。そうでない場合は、残りのコードを実行する必要があります。

breakbrowser、およびquitを試しましたが、いずれもプログラムの残りの実行を停止しません(そしてquitが実行を停止し、完全に終了しますR、これは私がやりたいことではありません)。私の最後の手段は、次のようにif-elseステートメントを作成することです。

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

しかし、それは悪いコーディング慣行のようです。何か不足していますか?

69
user2588829

プログラムでエラーを生成する場合は、stopifnot()関数を使用できます。

foo <- function(x) {
    stopifnot(x > 500)
    # rest of program
}
52
Michael Malick

If-else構造を逆にします。

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

きれいではありませんが、ここで私に役立つRでexit()コマンドを実装する方法があります。

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が表示され、エラーメッセージなしでスクリプトが中断します。

10
jochen

編集: OPは長いスクリプトを実行しているようです。その場合、スクリプトの一部をラップするだけで済みますafter品質管理

if (n >= 500) {

.... long running code here

}

functionから抜け出す場合は、おそらく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
7
Gavin Simpson

おそらく、ある時点で長いスクリプトの実行を停止したいだけです。すなわち。 CやPythonでexit()をハードコーディングしたいように。

print("this is the last message")
stop()
print("you should not see this")
5
netskink

これは古い質問ですが、まだ明確な解決策はありません。これはおそらくこの特定の質問に答えているわけではありませんが、「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に設定します。

1
user2641103

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)
}
1

ここに:

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

quit()stop(message)の両方がスクリプトを終了します。 Rコマンドプロンプトからスクリプトを調達している場合、quit()もRを終了します。