2009-09-08 11 views
28

lapplyとfriendsを使用して書かれたコードは、通常、目の上ではより簡単であり、ループよりも沢山あります。私は次の人と同じくらい礼賛しがっているのが大好きですが、状況が悪くなったらデバッグするにはどうしたらいいですか?例:lapply/sapplyコールのデバッグ

> y <- rep(NA, length(x)) 
> for (i in 1:length(x)) { 
+  y[i] <- 1/x[[i]] 
+ } 
Error in 1/x[[i]] : non-numeric argument to binary operator 

しかし、エラーが起こった場所を私は知っているだろう::

> ## a list composed of numeric elements 
> x <- as.list(-2:2) 
> ## turn one of the elements into characters 
> x[[2]] <- "what?!?" 
> 
> ## using sapply 
> sapply(x, function(x) 1/x) 
Error in 1/x : non-numeric argument to binary operator 

は、ループのためにIを使用していたlapply/sapplyを使用した場合

> i 
[1] 2 

は、私が何をすべきでしょうか?

答えて

23

を、エラーが発生を正確に停止するように、標準Rのデバッグ手法を使用します。

options(error = browser) 

または

options(error = recover) 

を完了したら標準動作に戻る:

options(error = NULL) 
22

お試し()ステートメントを使用して、あなたの内側の機能をラップした場合、あなたはより多くの情報を得る:この場合

> sapply(x, function(x) try(1/x)) 
Error in 1/x : non-numeric argument to binary operator 
[1] "-0.5"              
[2] "Error in 1/x : non-numeric argument to binary operator\n" 
[3] "Inf"              
[4] "1"              
[5] "0.5" 

を、あなたは、インデックスが失敗したかを確認することができます。

0

関数をデバッグ()したり、ブラウザ内にブラウザ()を置くことができます。これは、あなたがうまく反復する反復がない場合にのみ特に便利です。

また、これは個人的には行っていませんが、エラーが発生したときにbrowser()インターフェイスを使用できるように、try()の一部としてbrowser()を入れることができると思われます。

8

.inform = TRUEで、plyrパッケージを使用します。

library(plyr) 
laply(x, function(x) 1/x, .inform = TRUE) 
0

私は同じ問題に直面しており、(l)(m)(s)(t)は私がデバッグできる機能であることを要求しています。代わりに何とかのだから

、< -sapply(X、関数(x)は、{X + 1})

Iは(言う

myfn<-function(x){x+1} 
blah<-sapply(x,function(x){myfn(x)}) 

及びオプションでデバッグ(myfn)を使用したいですエラー=回復)。

私はまた何が起こっているかを見るためにここにprint()行を貼り付けるというアドバイスが好きです。

myfn(x)が通過しなければならないテストを設計し、それをsapplyに適用する前にテストに合格したことを確認することがさらにうまくいきます。私はこれに約半分の時間しか忍耐を持っていません。geoffjentry同様

+0

または単に 'blah <-appl(x、mfn)'です。そして、あなたは 'debug'とrecover'の両方を必要とすべきではありません。 – hadley

1

は言った:

> sapply(x, function(x) { 
    res <- tryCatch(1/x, 
        error=function(e) { 
          cat("Failed on x = ", x, "\n", sep="") ## browser() 
          stop(e) 
         }) 
}) 

はまた、あなたのforループは、(おそらく少し遅い)非常にクリーンであることを書き換えることができます

ループの場合
> y <- NULL 
> for (xi in x) 
    y <- c(y, 1/xi) 

Error in 1/xi : non-numeric argument to binary operator 

はRで遅いですが、しない限り、あなたは本当に私が混乱リストの理解を超えて単純な反復的なアプローチで行くスピードが必要です。

私はその場でいくつかのコードを把握する必要がある場合は、私はいつも行くよ:

sapply(x, function(x) { 
    browser() 
    ... 
}) 

をそして私は私が得ているものを見るように、関数内のコードを記述します。

- それはそう頻繁にあなたのコードを停止しますので、デバッグやブラウザを使用してダン

+3

forループの呼び出しが不正です。それは物事を多く**遅くするでしょう。 – hadley

+1

@hadley ...すべての単一ループステップで配列全体を再割り当てする必要があるため(メモリを予約し、古いデータをコピーする必要があります)、 'y < - 数値(長さ(x))'は事前割り当ての最も速い方法です。 – AlexR

1

が、この場合にはお勧めできません。代わりにTryまたはTryCatchを使用し、発生したときの状況に対処します。