9

Rの関数はどのような状況でreadRDS()パッケージ/名前空間を読み込もうとしますか? 新しいRセッションで次のことを見て驚いた:

> loadedNamespaces()
[1] "base"      "datasets"  "graphics"  "grDevices" "methods"   "stats"    
[7] "tools"     "utils"    
> x <- readRDS('../../../../data/models/my_model.rds')
There were 19 warnings (use warnings() to see them)
> loadedNamespaces()
 [1] "base"         "class"        "colorspace"   "data.table"  
 [5] "datasets"     "dichromat"    "e1071"        "earth"       
 [9] "evaluate"     "fields"       "formatR"      "gbm"         
[13] "ggthemes"     "graphics"     "grDevices"    "grid"        
[17] "Iso"          "knitr"        "labeling"     "lattice"     
[21] "lubridate"    "MASS"         "methods"      "munsell"     
[25] "plotmo"       "plyr"         "proto"        "quantreg"    
[29] "randomForest" "RColorBrewer" "reshape2"     "rJava"       
[33] "scales"       "spam"         "SparseM"      "splines"     
[37] "stats"        "stringr"      "survival"     "tools"       
[41] "utils"        "wra"          "wra.ops"      "xlsx"        
[45] "xlsxjars"     "xts"          "zoo"     

これらの新しいパッケージのいずれかが利用できない場合、 はreadRDS()失敗します。

言及されている19の警告は次のとおりです。

> warnings()
Warning messages:
1: replacing previous import ‘hour’ when loading ‘data.table’
2: replacing previous import ‘last’ when loading ‘data.table’
3: replacing previous import ‘mday’ when loading ‘data.table’
4: replacing previous import ‘month’ when loading ‘data.table’
5: replacing previous import ‘quarter’ when loading ‘data.table’
6: replacing previous import ‘wday’ when loading ‘data.table’
7: replacing previous import ‘week’ when loading ‘data.table’
8: replacing previous import ‘yday’ when loading ‘data.table’
9: replacing previous import ‘year’ when loading ‘data.table’
10: replacing previous import ‘here’ when loading ‘plyr’
11: replacing previous import ‘hour’ when loading ‘data.table’
12: replacing previous import ‘last’ when loading ‘data.table’
13: replacing previous import ‘mday’ when loading ‘data.table’
14: replacing previous import ‘month’ when loading ‘data.table’
15: replacing previous import ‘quarter’ when loading ‘data.table’
16: replacing previous import ‘wday’ when loading ‘data.table’
17: replacing previous import ‘week’ when loading ‘data.table’
18: replacing previous import ‘yday’ when loading ‘data.table’
19: replacing previous import ‘year’ when loading ‘data.table’

そのため、どうやら and のようなものをロードしているようlubridateで、data.table名前空間の競合が発生しています。

FWIW、unserialize()同じ結果が得られます。

私が本当に望んでいるのは、オブジェクトを保存した人がその時点でロードしたと思われるすべてのものをロードせずに、これらのオブジェクトをロードすることです。

更新: オブジェクトのクラスは次のxとおりです。

> classes <- function(x) {
    cl <- c()
    for(i in x) {
      cl <- c(cl, if(is.list(i)) c(class(i), classes(i)) else class(i))
    }
    cl
  }
> unique(classes(x))
 [1] "list"              "numeric"           "rq"               
 [4] "terms"             "formula"           "call"             
 [7] "character"         "smooth.spline"     "integer"          
[10] "smooth.spline.fit"

qrquantregパッケージからのもので、残りはすべてbaseまたはからのものstatsです。

4

2 に答える 2

5

Ok。これは有用な答えではないかもしれませんが(詳細が必要です)、少なくとも「どのような状況で..」の部分に対する答えだと思います。

まず第一に、それはに固有のものではなく、 「ed」できるオブジェクトreadRDSと同じように機能すると思います。saveload

「どのような状況で」の部分: 保存されたオブジェクトに、パッケージ/名前空間環境を親として持つ環境が含まれている場合。または、環境がパッケージ/名前空間環境である関数が含まれている場合。

require(Matrix)
foo <- list(
   a = 1,
   b = new.env(parent=environment(Matrix)),
   c = "c")
save(foo, file="foo.rda")
loadedNamespaces()   # Matrix is there!
detach("package:Matrix")
unloadNamespace("Matrix")
loadedNamespaces()   # no Matrix there!
load("foo.rda")
loadedNamespaces()   # Matrix is back again

また、以下も機能します。

require(Matrix)
bar <- list(
   a = 1,
   b = force,
   c = "c")
environment(bar$b) <- environment(Matrix)
save(bar, file="bar.rda")
loadedNamespaces()      # Matrix is there!
detach("package:Matrix")
unloadNamespace("Matrix")
loadedNamespaces()      # no Matrix there!
load("bar.rda")
loadedNamespaces()      # Matrix is back!

saveRDS私は試していませんが、 /と同じように動作しない理由はありませんreadRDS。そして解決策: 保存されたオブジェクトに害がない場合 (つまり、環境が実際には必要ないことが確実な場合)、親環境を削除することができますparent.env。したがって、foo上記を使用すると、

parent.env(foo$b) <- baseenv()
save(foo, file="foo.rda")
loadedNamespaces()        # Matrix is there ....
unloadNamespace("Matrix")
loadedNamespaces()        # no Matrix there ...
load("foo.rda")
loadedNamespaces()        # still no Matrix ...
于 2013-11-06T08:17:52.897 に答える
1

私が思いついた厄介な回避策の 1 つは、厄介な eval によって、オブジェクトにアタッチされていたすべての環境のオブジェクトをクレンジングすることです。

sanitizeEnvironments <- function(obj) {
    tc <- textConnection(NULL, 'w')
    dput(obj, tc)
    source(textConnection(textConnectionValue(tc)))$value
}

古いオブジェクトを取得し、この関数を実行してから、saveRDS()もう一度実行できます。次に、新しいオブジェクトをロードしても、名前空間全体にチャンクが吹き飛ばされません。

于 2013-10-30T18:07:16.883 に答える