4

私は R にまったく慣れていないため、 の正しい使用法に混乱していますtryCatch。私の目標は、大規模なデータ セットの予測を行うことです。予測がメモリに収まらない場合は、データを分割して問題を回避したいと考えています。

現在、私のコードはおおよそ次のようになっています。

tryCatch({
  large_vector = predict(model, large_data_frame)
}, error = function(e) { # I ran out of memory
  for (i in seq(from = 1, to = dim(large_data_frame)[1], by = 1000)) {
    small_vector = predict(model, large_data_frame[i:(i+step-1), ])
    save(small_vector, tmpfile)
  }
  rm(large_data_frame) # free memory
  large_vector = NULL
  for (i in seq(from = 1, to = dim(large_data_frame)[1], by = 1000)) {
    load(tmpfile)
    unlink(tmpfile)
    large_vector = c(large_vector, small_vector)
  }
})

ポイントは、エラーが発生しない場合、large_vector期待どおりに私の予測で満たされているということです。エラーが発生した場合、large_vectorエラー コードの名前空間にのみ存在するように見えます。関数として宣言したため、これは理にかなっています。large_data_frame同じ理由で、削除できないという警告が表示されます。

残念ながら、この動作は私が望んでいるものではありません。large_vectorエラー関数内から変数を割り当てたいと思います。1つの可能性は、環境を指定して割り当てを使用することだと考えました。したがって、エラー コードで次のステートメントを使用します。

rm(large_data_frame, envir = parent.env(environment()))
[...]
assign('large_vector', large_vector, parent.env(environment()))

ただし、このソリューションはかなり汚いようです。「きれいな」コードで私の目標を達成する可能性があるかどうか疑問に思いますか?

[編集] 上記のコードは、主に問題を説明するためのものであり、実際の例を示すためのものではないため、混乱しているようです。名前空間の問題を示す最小限の例を次に示します。

# Example 1 : large_vector fits into memory
rm(large_vector)
tryCatch({
  large_vector = rep(5, 1000)
}, error = function(e) {
  # do stuff to build the vector
  large_vector = rep(3, 1000)
})
print(large_vector)  # all 5

# Example 2 : pretend large_vector does not fit into memory; solution using parent environment
rm(large_vector)
tryCatch({ 
  stop();  # simulate error
}, error = function(e) {
  # do stuff to build the vector
  large_vector = rep(3, 1000)
  assign('large_vector', large_vector, parent.env(environment()))
})
print(large_vector)  # all 3

# Example 3 : pretend large_vector does not fit into memory; namespace issue
rm(large_vector)
tryCatch({ 
  stop();  # simulate error
}, error = function(e) {
  # do stuff to build the vector
  large_vector = rep(3, 1000)
})
print(large_vector)  # does not exist
4

3 に答える 3

5

私はこのようなことをします:

res <- tryCatch({
  large_vector = predict(model, large_data_frame)
}, error = function(e) { # I ran out of memory
  ll <- lapply(split(data,seq(1,nrow(large_data_frame),1000)),
         function(x)
             small_vector = predict(model, x))
  return(ll)
})
rm(large_data_frame)
if(is.list(ll)) 
  res <- do.call(rbind,res)

アイデアは、メモリが不足した場合に予測結果のリストを返すことです。

注、再現可能な例がないため、ここでの結果はわかりません。

于 2013-03-08T10:45:52.477 に答える
3

編集:もう一度試してみましょう:

finallyの引数を使用できますtryCatch

step<-1000
n<-dim(large_data_frame)[1]
large_vector <- NULL
tryCatch({
  large_vector <- predict(model, large_data_frame) 
}, error = function(e) { # ran out of memory
  for (i in seq(from = 1, to = n, by = step)) {
    small_vector <- predict(model, large_data_frame[i:(i+step-1),]) #predict in pieces
    save(small_vector,file=paste0("tmpfile",i)) #same pieces
  }  
 rm(large_data_frame) #free memory

},finally={if(is.null(large_vector)){ #if we run out of memory
   large_vector<-numeric(n) #make vector
   for (i in seq(from = 1, to = n, by = step)){
     #collect pieces
     load(paste0("tmpfile",i)) 
     large_vector[i:(i+step-1)] <- small_vector
   }
}})

何が起こっているかを確認するための簡略化されたバージョンを次に示します。

large_vector<-NULL
rm(y)
tryCatch({
  large_vector <- y 
}, error = function(e) {# y is not found
  print("error")
},finally={if(is.null(large_vector)){
 large_vector<-1
}})
> large_vector
[1] 1

EDIT2:large_vectorあなたに役立つ可能性のあるスコープに関する別のヒント(ただし、事前に宣言したくなかったため、この状況ではないかもしれません): <<-R-helpのオペレーター:

演算子<<-および->>は通常、関数でのみ使用され、割り当てられている変数の既存の定義を親環境で検索します。

したがって、上記のサンプルコードを次のように使用できます。

large_vector<-NULL
rm(y)
tryCatch({
  large_vector <- y 
}, error = function(e) {# y is not found
  large_vector <<- 1
  print("error")
})
> large_vector
[1] 1
于 2013-03-08T10:35:46.647 に答える
0

以下のコードは一目瞭然です。実際、問題は、エラー関数内のすべてがデフォルトで親環境に適用されないことです。

b=0

説明したように、これは機能しません:

tryCatch(expr = {stop("error1")}, error=function(e) {b=1})
b

解決策 1: 親環境に割り当てる

tryCatch(expr = {stop("error2")}, error=function(e) {assign(x = "b", value = 2, 環境 = 親.env(env = 環境()))})
b

expr解決策 2: 最も単純です ( と の両方でb に代入している場合にのみ機能しますerror)

b = tryCatch(expr = {stop("error3")}, error=function(e) {b=3;return(b)})
b

于 2015-12-15T03:53:31.640 に答える