11

この質問は、値の 1 つがエラーを返したために、3 時間のジオコーディング実行全体を失ったことに触発された可能性があります。残念な(マイナス)票をキューに入れます。

基本的に、 によって呼び出された関数内でエラーが返されましたsapply。私はそうoptions(error=recover)しましたが、利用可能なすべてのレベルを閲覧したにもかかわらず、FUN への (何千もの成功した) 呼び出しの結果がメモリに保存されている場所を見つけることができませんでした。

自分自身をブラウズしているときに見つけたオブジェクトのいくつかを調べようとすると、参照が無効になったと主張してエラーが発生しました。残念ながら、特定のエラー メッセージを失いました。

これは、参照エラー (環境の消失に関連していると思われ、おそらく重要ではない) を再現していませんが、既に処理されたデータを保存する方法が見つからないことを示す簡単な例です。

そのようなテクニックはありますか?

それ以来、私は自分のエラーに気づき、 を介して以前よりもさらに堅牢なエラー処理を挿入しましたが、事前ではなく事後tryに内容を回復する方法を探しています。

テスト機能

sapply( seq(10), function(x) {
  if(x==5) stop("Error!")
  return( "important data" )
} )

インタラクティブな探索

> sapply( seq(10), function(x) {
+   if(x==5) stop("Error!")
+   return( "important data" )
+ } )
Error in FUN(1:10[[5L]], ...) : Error!

Enter a frame number, or 0 to exit   

1: sapply(seq(10), function(x) {
    if (x == 5) 
        stop("Error!")
    return("important data")
})
2: lapply(X = X, FUN = FUN, ...)
3: FUN(1:10[[5]], ...)

Selection: 3
Called from: FUN(1:10[[5L]], ...)
Browse[1]> ls()
[1] "x"
Browse[1]> x
[1] 5
Browse[1]> 
Enter a frame number, or 0 to exit   

1: sapply(seq(10), function(x) {
    if (x == 5) 
        stop("Error!")
    return("important data")
})
2: lapply(X = X, FUN = FUN, ...)
3: FUN(1:10[[5]], ...)

Selection: 2
Called from: lapply(X = X, FUN = FUN, ...)
Browse[1]> ls()
[1] "FUN" "X"  
Browse[1]> X
 [1]  1  2  3  4  5  6  7  8  9 10
Browse[1]> FUN
function(x) {
  if(x==5) stop("Error!")
  return( "important data" )
}
Browse[1]> 
Enter a frame number, or 0 to exit   

1: sapply(seq(10), function(x) {
    if (x == 5) 
        stop("Error!")
    return("important data")
})
2: lapply(X = X, FUN = FUN, ...)
3: FUN(1:10[[5]], ...)

Selection: 1
Called from: sapply(seq(10), function(x) {
    if (x == 5) 
        stop("Error!")
    return("important data")
})
Browse[1]> ls()
[1] "FUN"       "simplify"  "USE.NAMES" "X"        
Browse[1]> X
 [1]  1  2  3  4  5  6  7  8  9 10
Browse[1]> USE.NAMES
[1] TRUE
Browse[1]> simplify
[1] TRUE
Browse[1]> FUN
function(x) {
  if(x==5) stop("Error!")
  return( "important data" )
}
Browser[1]> Q

明確にするために、私が見つけたかったのはベクトルでした:

[1] "important data" "important data" "important data" "important data"

つまり、ここまで完了した内部ループの結果です。

編集:Cコードで更新

内部.Internal(lapply())次のコードです:

PROTECT(ans = allocVector(VECSXP, n));
...
for(i = 0; i < n; i++) {
   ...
   tmp = eval(R_fcall, rho);
   ...
   SET_VECTOR_ELT(ans, i, tmp);
}

ansへの呼び出しがlapply失敗したときに取得したい。

4

3 に答える 3

4

try()ここに行く方法がない理由を理解するのに苦労していますか? sapply()何らかの理由で失敗した場合は、

  1. その失敗をうまく処理したい
  2. そこから続けて

エラーのためだけにデータ分析/処理ステップ全体を停止したいのはなぜですか? これはあなたが提案しているようです。すでに行われたことを回復しようとするのではなく、コードを記述して続行し、発生したエラーを記録するだけでなく、プロセスの次のステップにスムーズに移行します。

あなたが与える例は不自然であるため、少し複雑です(エラーの原因がわかっている場合は、なしでそれを処理できますtry())が、我慢してください:

foo <- function(x) {
    res <- try({
        if(x==5) {
            stop("Error!")
        } else {
            "important data"
        }
    })
    if(inherits(res, "try-error"))
        res <- "error occurred"
    res
}

> sapply( seq(10), foo)
Error in try({ : Error!
 [1] "important data" "important data" "important data" "important data"
 [5] "error occurred" "important data" "important data" "important data"
 [9] "important data" "important data"

ワークステーションでバックグラウンドで完了するのに数週間かかるジョブを実行したことtry()で、大きなコード ブロックではなく、個々のステートメントの周りに多くの呼び出しを記述することをすぐに学びました。実行中のジョブへの影響が最も少ない。言い換えれば、特定の R 呼び出しが失敗した場合、sapply()(または任意の関数) によって返されたオブジェクトに適切に挿入される何かを返しました。

より複雑なものについては、おそらく次を使用しますlapply()

foo2 <- function(x) {
    res <- try({
        if(x==5) {
            stop("Error!")
        } else {
            lm(rnorm(10) ~ runif(10))
        }
    })
    if(inherits(res, "try-error"))
        res <- "error occurred"
    res
}

out <- lapply(seq(10), foo2)
str(out, max = 1)

より複雑なオブジェクトを単純なものに単純化しようとするのではなく、リストが必要になるためです。

>     out <- lapply(seq(10), foo2)
Error in try({ : Error!
> str(out, max = 1)
List of 10
 $ :List of 12
  ..- attr(*, "class")= chr "lm"
 $ :List of 12
  ..- attr(*, "class")= chr "lm"
 $ :List of 12
  ..- attr(*, "class")= chr "lm"
 $ :List of 12
  ..- attr(*, "class")= chr "lm"
 $ : chr "error occurred"
 $ :List of 12
  ..- attr(*, "class")= chr "lm"
 $ :List of 12
  ..- attr(*, "class")= chr "lm"
 $ :List of 12
  ..- attr(*, "class")= chr "lm"
 $ :List of 12
  ..- attr(*, "class")= chr "lm"
 $ :List of 12
  ..- attr(*, "class")= chr "lm"

そうは言っても、for()ループを介してこれを行い、繰り返しながら事前に割り当てられたリストを埋めていたでしょう。

于 2012-10-22T11:35:13.477 に答える
1

中間値を何にも割り当てたことはありません。神に内臓があるべきだとあなたが考える理由がわかりません。何らかの方法で値を記録する必要があります。

 res <- sapply( seq(10), function(x) { z <- x
                                   on.exit(res <<- x);
                                   if(x==5) stop("Error!")
 } )
Error in FUN(1:10[[5L]], ...) : Error!
 res
#[1] 5

この方法は、プロットがうまくいかなかったときに標準設定を復元する方法としてページにon.exit示されています。?par(私はそれを動作させることができませんでしたon.exit(res <- x)

于 2012-10-22T01:30:05.023 に答える
1

多分私は理解していないので、これは確かにあなたを遅くしますが、毎回グローバルな割り当てはどうですか?

safety <- vector()
sapply( seq(10), function(x) {
  if(x==5) stop("Error!")
  assign('safety', c(safety, x), envir = .GlobalEnv)
  return( "important data" )
} )

収量:

> safety <- vector()
> sapply( seq(10), function(x) {
+   if(x==5) stop("Error!")
+   assign('safety', c(safety, x), envir = .GlobalEnv)
+   return( "important data" )
+ } )
Error in FUN(1:10[[5L]], ...) : Error!
> safety
[1] 1 2 3 4
于 2012-10-22T02:26:08.603 に答える