> traceback()
として見ましょう。エラーがどの関数から発生したのかわかります。
それでエラーの内容がわからなかったら、自作関数のなかのエラーが発生したと
思われる直前に
browser()
と書いておきましょう。
例: 関数 fact の挙動を調べたい。
まず、問題の関数に"browser()"を挿入して再定義します。
> fact <- function(x){browser();if(x<=1)x else x * fact(x-1)}
その上で、実行して見ます。
> fact(4) Called from: fact(4) b(2)> ? 1: x b(2)> x [1] 4 b(2)> fact function(x) { browser() if(x <= 1) x else x * fact(x - 1) } b(2)> 0 Called from: fact(x - 1) b(3)> x [1] 3 b(3)> 0 Called from: fact(x - 1) b(4)> x [1] 2 b(4)> 0 Called from: fact(x - 1) b(5)> x [1] 1 b(5)> 0 [1] 24このように、実行した時に、一時停止して、
b(?)>
というプロンプトを表示します。
この環境で、関数の評価フレーム中のオブジェクトの内容を調べたり、
変更したりできます。具体的には、1, "?" を入力すると、その評価フレーム中のオブジェクト名を列挙します。
2, その評価フレーム中のオブジェクト名("x", "fact" など)を入力すると その内容を表示します。
3, 普通のプロンプト環境と同様、オブジェクトの(再)定義などもできる。
4, "0" を入力すると、この環境から抜け、元の関数の評価を続行する。
5, "CTRL \" で、元の関数の評価をやめて、プロンプトレベルに戻る。
詳しくは「S言語 I」p203以降を参照のこと。
また、反復などの途中で、原因不明のエラーがでるときには、 try(調べたいコマンド)とすると、エラー終了せずに実行を進めたあとで、 エラー内容を検討することができます。
例 set.seed(1) inputs <- sapply(1:10, function(i)rpois(1,1)) f <- function(x) if (x<1) stop("x<1") else log(x) val <- lapply(inputs, function(x)try(f(x))) unlist(val[!sapply(val, is, "Error")]) # extract ones that worked