gpt4 book ai didi

r - 如何使用saveRDS(...,refhook =)参数?

转载 作者:行者123 更新时间:2023-12-04 11:21:52 24 4
gpt4 key购买 nike

我有一个复杂的列表对象,即建模函数(asreml)的输出。该对象包含附加了环境的各种数据类型,包括函数和公式。我不想将环境保存到RDS,因为它们很大,并且我保存了很多模型。

我在refhook=serialize函数中遇到了参数saveRDS。该文档说:

The refhook functions can be used to customize handling of non-system reference objects (all external pointers and weak references, and all environments other than namespace and package environments and .GlobalEnv). The hook function for serialize should return a character vector for references it wants to handle; otherwise it should return NULL.



给定这个示例模型
e <- new.env()
e$a = rnorm(10)
l <- list(a = e, b = 42)

refhook函数确实显示了一些效果。当我定义一个返回字符的函数时,输出将变小,表明未保存环境:
length(serialize(l, connection = NULL))
[1] 338

s <- serialize(l,
connection = NULL,
refhook = function(x) "")
length(s)
[1] 109

但是,我无法读取结果对象:
unserialize(s)

Error in unserialize(s) :
no restore method available

我还尝试了原始向量输出,怀疑可能希望refhook提供替代的序列化输出,但这不起作用:
s2 <- serialize(l,
connection = NULL,
refhook = function(x)
serialize("env", connection = NULL)))

Error in serialize(l, con = NULL, refhook = function(x) serialize("env", :
assertion 'TYPEOF(t) == STRSXP && LENGTH(t) > 0' failed: file 'serialize.c', line 982

如何使用 refhook=?此功能预期输出什么字符?

最佳答案

啊,我自己发现的。错误“没有可用的还原方法”意味着您忘记为unserialize函数添加refhook。两者都需要refhook的serializeunserialize
serialize的refhook在返回的字符串中是完全免费的。唯一需要了解结果的人是unserialize的refhook。

示例:序列化和还原包含集中存储的环境的列表

生成环境存储库。让我们假装这些来自
外部源及其内容无需序列化。恢复
他们,外部数据源只需要重新读取。

repo <- list()
for(i in 1:10){
repo[[i]] <- new.env()
repo[[i]]$a <- rnorm(1e6)
}

一种环境是8 MB大。我们不想在序列化输出中拥有所有这些数据,因为它已经永久保存在 repo中。
object.size(repo[[1]]$a)

这是我们要序列化的列表。它包含第二个环境
从存储库中。我们只想存储数值 b。为了
环境,我们只想存储环境2中的
资料库。我们不想序列化内容,因为存储库
已经有他们了。
l <- list(a = repo[[2]], b = 42)

这是序列化的引用。它在索引中查找环境
并存储索引。
ser <- function(e){
for(i in seq_along(repo)){
if(identical(e, repo[[i]])){
message("Identified environment #",i)
return(as.character(i)) # Just save the
}
}
message("Environment not found in the repository")
return(NULL)
}

反序列化的相应refhook获取索引并加载
来自 repo的相应环境:
unser <- function(s){
i <- as.numeric(s)
return(repo[[i]])
}

这样可以节省序列化输出中的大量空间
  • 没有自定义refhook:还包含环境
    object.size(serialize(l, con = NULL))
    ## 8000040 bytes
  • 与自定义refhook:仅保存l$b和环境索引
    s <- serialize(l, con = NULL, refhook = ser)
    object.size(s)
    ## 168 bytes

  • 反序列化时从数据库加载环境
    u <- unserialize(s, refhook = unser)
    ## $a
    ## <environment: 0x000000001c91a118>
    ##
    ## $b
    ## [1] 42

    关于r - 如何使用saveRDS(...,refhook =)参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54144239/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com