R 実行中に生じたエラーの原因を調べたい場合は browser
、debug
、trace
、traceback
などのデバッグ関数を利用する。
browser |
browser が書かれている行で、プログラムの実行が一時停止される。この行にまでに出現した変数の中身を確認したりすることができる。 |
debug |
関数名を与えて、その関数の処理を追跡する。 |
traceback |
直前に発生した関数のエラーをトレースバックし、エラーが発生した源を表示する。 |
trace |
関数に任意の位置にブレークポイントを挿入しデバッグを行うことができる。 |
browser
コードの中に browser
関数を書き入れることで、それが実行されたときに、browser
が書かれている行で実行が一時停止される。この時、変数の内容を確認したり、様々なテスト演算を行ったりすることができる。
func <- function(x) {
x <- x + 2
y <- x * x
z <- NULL
browser() # ここで一時停止
a <- x + y
b <- x - y
c <- a + b
return(c)
}
func
関数を実行すると、browser
の行で実行が一時停止される。一時停止された状態で、n
を入力することで 1 行後に進むことができる。
func(10)
#'
#' Called from: func(10)
#'
#'Browse[1]> ls() # 現在で使える変数
#'[1] "x" "y" "z"
#'
#'Browse[1]> x # xの内容を確認
#'[1] 12
#'
#'Browse[1]> x + y # 途中状態で計算
#'[1] 156
#'
#'Browse[1]> n # 次の行を確認(実行されない)
#'debug at #6: a <- x + y
#'
#'Browse[2]> a # まだ実行されませんので、aには何も入っていない
#'Error: object 'a' not found
#'
#'Browse[2]> n # 次の行を確認(6行目は実行されて、7行目は実行待機状態)
#'debug at #7: b <- x - y
#'
#'Browse[2]> a # 6行目が実行されたので、aに値が入った
#'[1] 156
#'
#'Browse[2]> Q # デバッグを終了
#'
browser
関数を 2 箇所以上埋めた場合、一時停止の状態で c を入力すると、現在の browser
の行から次の browser
の行にスキップすることができる。また、条件付きで browser
を設定することもできる。例えば、変数 y
が 10 以上のときに限り一時停止する場合は以下のようにする。
func <- function(x) {
x <- x + 2
y <- x * x
z <- NULL
browser(expr = y >= 10) # ここで一時停止
a <- x + y
b <- x - y
c <- a + b
return(c)
}
debug
関数のデバッグを行いたい場合に debug
関数を利用する。debug
関数にデバッグを行いたい関数名を引数として与える。また、デバッグ状態にある関数を解除したい場合は undebug
関数を利用する。
func <- function(x) {
x <- x + 2
y <- x * x
z <- NULL
a <- x + y
b <- x - y
c <- a + b
return(c)
}
debug
関数に関数名を代入し、デバッグ状態にする。次にその関数を実行することでデバッグが開始される。
debug(func) # funcを利用したらデバッグを開始
func(10)
#'debug at #1: {
#' x <- x + 2
#' y <- x * x
#' z <- NULL
#' a <- x + y
#' b <- x - y
#' c <- a + b
#' return(c)
#'}
#'Browse[2]> ls() # 一行目が実行する前の状態、変数はxしかない
#'[1] "x"
#'
#'Browse[2]> x # xの中身を確認
#'[1] 10
#'
#'Browse[2]> n # 1行進む(だたし実行されない)
#'debug at #2: x <- x + 2
#'
#'Browse[2]> Q # デバッグを終了
undebug(func) # デバッグ状態を解除
traceback
R の実行中にエラーが発生した時、traceback
関数によりエラーの源を追跡することができる。
plot(NA, 1)
## Error in plot.window(...) : need finite 'xlim' values
## In addition: Warning messages:
## 1: In min(x) : no non-missing arguments to min; returning Inf
## 2: In max(x) : no non-missing arguments to max; returning -Inf
traceback()
## 4: plot.window(...)
## 3: localWindow(xlim, ylim, log, asp, ...)
## 2: plot.default(NA, 1)
## 1: plot(NA, 1)
エラーの源は plot.window
関数であることがわかったので、更に詳しく調べたい場合は、debug
関数を用いて plot.window
関数を 1 行ずつデバッグしていく。
debug(plot.window)
plot(NA, 1)
#'debugging in: plot.window(...)
#'debug: .Internal(plot.window(xlim, ylim, log, asp, ...))
#'Browse[2]>
trace
trace
関数を利用して、デバッグを行いたい関数の任意の位置にブレークポイントを仕掛けることができる。次は、func
関数の 3 行目にブレークポイント(browser
関数)を挿入する例である。
func <- function(x) {
x <- x + 1
y <- x + 1
z <- y + 1
w <- z + 1
}
# fun関数の3行目にデバッグ関数(browser)を仕掛る
# browserの挿入により、funcの3行目は4行目になる(以降、すべての行が1行ずつずれる)
trace(func, tracer=browser, at=3)
# func関数を呼び出す
func(0)
#' Tracing fun(0) step 3
#' Called from: eval(expr, envir, enclos)
#' Browse[1]> x # 2行目の実行が完了しているためxが変わる
#' [1] 1
#' Browse[1]> y # fun本来の3行目はbrowserの挿入により、4行目へずれ込み、従ってyはまだ生成されていない
#' Error: object 'y' not found
#' Browse[1]> n # 次の行(4行目)に進む(まだ実行されない)
#' debug: y <- x + 1
#' Browse[2]> y
#' Error: object 'y' not found
#' Browse[2]> n # 次の行(5行目)に進む(4行目は実行され、5行目は実行待ち)
#' debug at #4: z <- y + 1
#' Browse[2]> y # 4行目に書かれているyが生成されている
#' [1] 2
#' Browse[2]> z # zはまだ生成されていない
#' Error: object 'z' not found
#' Browse[2]> Q # 終了
その他
Warning message はデフォルトでは間違いとみなさないために traceback
を適用できない。そこで、options
関数により、Warning message を Error に変更させてから、デバッグする。
options(warn = 2)