Rのこと。

記事は引っ越し作業中。2023年中までに引っ越しを完了させてブログは削除予定

Rstudioのbrowserとdebugモードについて

はじめに

Rstudioのbrowserとdebugモードなでデバッグについて少し共有する機会があったので、そのメモ。関数を定義した際に、エラーが出力されたり、期待通りの動作をしないことがよくある。そのような場合に、どこに誤りがあるのかを探して見つけて修正する作業がデバッグデバッグの方法はいろいろあるが、RStudioにはデバッグのための関数がいくつか用意されているので、その紹介。

catデバック

1番ベタで手軽な方法かもしれない。関数の途中でcat()print()を使って,バグの原因となる変数の値を関数の途中で評価して、途中で表示させる方法。myfunc0()を実行して、xyが表示されるようにする。

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.