Rstudioのbrowserとdebugモードについて
はじめに
Rstudioのbrowserとdebugモードなでデバッグについて少し共有する機会があったので、そのメモ。関数を定義した際に、エラーが出力されたり、期待通りの動作をしないことがよくある。そのような場合に、どこに誤りがあるのかを探して見つけて修正する作業がデバッグ。デバッグの方法はいろいろあるが、RStudioにはデバッグのための関数がいくつか用意されているので、その紹介。
catデバック
1番ベタで手軽な方法かもしれない。関数の途中でcat()
やprint()
を使って,バグの原因となる変数の値を関数の途中で評価して、途中で表示させる方法。myfunc0()
を実行して、x
とy
が表示されるようにする。
myfunc0 <- function(x, y) { cat(x, y, sep = "\n") if (x < 0){ s <- -1 * x } else { s <- 10 * x } return(s * y) } myfunc0(x = 10, y = 3) 10 3 [1] 300
browser
評価が進んだ時点で調べたいときはbrowser()
を使う。browser()
は関数中に何個入れても問題ない。関数を実行するとBrowse[1]>
と表示され、入力待ちになる。
myfunc1 <- function(x, y) { if (x < 0){ s <- -1 * x } else { s <- 10 * x } browser() # Here return(s * y) } myfunc1(x = -3, y = 3) Called from: myfunc1(x = -3, y = 3) Browse[1]>
コマンド | 内容 |
---|---|
c ,cont | 関数の実行を継続 |
n ,next | デバッグ付のステップ実行。一行ずつステップ実行する。 |
ls() | 現在までに生成された変数を全て表示。Environmentパネルに表示されている。 |
関数中の変数 | この例ではxやyやsなどのローカル変数の現時点の値を表示。Environmentパネルに表示されている。 |
関数中の式 | 式を評価し値を表示 |
where | 現在のスタックの記録を表示 |
return() | 関数評価に戻る |
Q | 終了 |
myfunc1(x = -3, y = 3) Called from: myfunc1(x = -3, y = 3) Browse[1]> x [1] -3 Browse[1]> y [1] 3 Browse[1]> ls() [1] "s" "x" "y" Browse[1]> n #9 の debug: return(s * y) Browse[2]> n [1] 9
debugモード
関数をステップ実行するには関数debug()
を利用する。コマンドはさきほどと同じ。
myfunc2 <- function(x, y) { if (x < 0){ s <- -1 * x } else { s <- 10 * x } return(s * y) } debug(myfunc2) myfunc2(x = -3, y = 3) debugging in: myfunc2(x = -3, y = 3) #1 の debug: { if (x < 0) { s <- -1 * x } else { s <- 10 * x } return(s * y) } Browse[2]> n #3 の debug: if (x < 0) { s <- -1 * x } else { s <- 10 * x } Browse[2]> n #4 の debug: s <- -1 * x Browse[2]> n #8 の debug: return(s * y) Browse[2]> n exiting from: myfunc2(x = -3, y = 3) [1] 9
デバッグモードを抜ける場合はundebug()
を使う。
undebug(myfunc2)
おまけのmissing()
引数が省略されたかどうかを調べる関数としてmissing()
がある。missing()
は、関数内でのみ使える特殊な関数。指定された引数が省略されていれば TRUE
を返す。
myfunc <- function(x, y) { if (missing(y)) { return(x) } else{ res <- x * y } return(res) } myfunc(x = 10, y = 3) [1] 30 myfunc(x = 10) [1] 10
missing()
を使ってワーニングを出すこともできる。
myfunc <- function(x, y) { if (missing(y)) { warning("`y` isn’t inputted.") return(x) } else{ res <- x * y } return(res) } myfunc(x = 10) [1] 10 警告メッセージ: myfunc(x = 10) で: `y` isn’t inputted.