readRDS()加载额外的包

Ken*_*ams 9 serialization r

在什么情况下readRDS()R 中的函数尝试加载包/命名空间?我很惊讶在新的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"     
Run Code Online (Sandbox Code Playgroud)

如果这些新软件包中的任何一个不可用,则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’
Run Code Online (Sandbox Code Playgroud)

显然,它正在加载类似的东西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"
Run Code Online (Sandbox Code Playgroud)

qr来自quantreg包装,其余全部来自basestats.

leb*_*nok 5

好。这可能不是一个有用的答案(需要更多细节),但我认为这至少是“在什么情况下..”这一部分的要求。

首先,我认为它并不特定于readRDS任何save'd对象,但可以以相同的方式工作load

“在什么情况下”部分:当保存的对象包含以包/命名空间环境为父环境的环境时。或者当它包含一个环境是包/命名空间环境的函数时。

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
Run Code Online (Sandbox Code Playgroud)

还有以下工作原理:

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!
Run Code Online (Sandbox Code Playgroud)

我没有尝试过,但是没有理由为什么它不能与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 ...
Run Code Online (Sandbox Code Playgroud)