【问题标题】:Can I access R data objects' attributes without fully loading objects from file?我可以在不从文件中完全加载对象的情况下访问 R 数据对象的属性吗?
【发布时间】:2014-07-05 06:08:22
【问题描述】:

情况是这样的。我的R 代码应该检查应用程序缓存 中现有的RData 文件是否是最新的。我通过保存名称由特定数据元素的base64 编码名称组成的文件来做到这一点。但是,通过为每个元素提交特定的 SQL 查询来检索与这些元素中的每一个相对应的数据,所有这些都在数据集合的配置文件中指定。因此,在检索到元素的数据但之后我不得不更改特定 SQL 查询的情况下,数据不会被更新。

为了处理这种情况,我决定使用R 对象的属性。我打算把每个数据对象对应的SQL查询(request)——base64-encoded——保存为对象的属性:

# save hash of the request's SQL query as data object's attribute,
# so that we can detect when configuration contains modified query
attr(data, "SQL") <- base64(request)

然后,当我需要验证 SQL 是否已经被查询更改时,我想简单地检索对象的相应属性并将其与当前 SQL 查询的哈希进行比较。如果它们匹配 - 查询未更改,我跳过处理此数据请求,如果它们不匹配 - 查询已更改,我继续处理请求:

# check if the archive file has already been processed
if (DEBUG) {message("Processing request \"", request, "\" ...")}
if (file.exists(rdataFile)) {
  # now check if request's SQL query hasn't been modified
  data <- load(rdataFile)
  if (identical(base64(request), attr(data, "SQL"))) {
    skipped <<- skipped + 1
    if (DEBUG) {message("Processing skipped: .Rdata file found.\n")}
    return (invisible())
  }
  rm(data)
}

我的问题是是否可以在不完全加载文件的情况下读取/访问对象的属性。换句话说,我可以避免上面代码中的load()和rm()吗?

非常感谢您的建议!

更新:附加问题:我的代码有什么问题,因为即使它不应该执行处理 - 以防所有信息都是最新的(缓存和配置文件也没有更改)?

更新 2(每个 @MrFlick 的答案的附加代码):

# construct name from data source prefix and data ID (see config. file),
# so that corresponding data object (usually, data frame) will be saved
# later under that name via save()
dataName <- paste(dsPrefix, "data", indicator, sep = ".")

assign(dataName, srdaGetData())
data <- as.name(dataName)

# save hash of the request's SQL query as data object's attribute,
# so that we can detect when configuration contains modified query
attr(data, "SQL") <- base64(request)

# save current data frame to RData file
save(list = dataName, file = rdataFile)
# alternatively, use do.call() as in "getFLOSSmoleDataXML.R"

# clean up
rm(data)

【问题讨论】:

    标签: r attributes persistence data-objects rdata


    【解决方案1】:

    你不能“真的”这样做,但你可以修改我的cgwtools::lsdata函数中的代码。

    function (fnam = ".Rdata") 
    {
        x <- load(fnam, envir = environment())
        return(x)
    }
    

    这会加载,因此需要时间并短暂占用内存,然后本地环境消失。因此,为要检查属性的项目添加一个参数,在函数内添加一行 attributes(your_items) -&gt;y ; return (list(x=x,y=y))

    【讨论】:

    • 非常感谢您的回答!但是,我真的看不出与我的方法有本质区别(使用load 的方法)。如果我理解正确,您的方法的“技巧”是自动消失的环境,但只是调用rm 并完成它不是更容易。在任何情况下都会加载对象。奇怪的是,我的 load 和 rm 代码没有按预期工作。你觉得有什么不正确的地方吗?
    • 使用load 的风险之一是您将轰炸当前环境中具有相同名称的任何现有对象——更不用说rm 中的最轻微拼写错误会杀死你想保留的东西:-(——这就是为什么我使用这个函数和它自己独特的环境。
    • 我非常有信心,我为这个应用程序分配的名称将是唯一的,因为它们来自我维护的配置文件。但是,我理解您的观点并感谢您的澄清。每天都在学习新东西...顺便说一句,在发布我的问题之前,我在研究 SO 上的主题时,偶然看到了这篇相关且有趣的帖子,希望您会喜欢阅读:cybaea.net/Blogs/A-warning-on-the-R-save-format.html。
    【解决方案2】:

    您使用load() 的方式存在问题。当您使用 save/load 时,您可以将多个对象“冻结”到 .RData 文件中。他们“重新膨胀”到当前的环境中。因此,当您调用load() 时,它不会返回对象,而是返回一个字符向量,其中包含它恢复的所有对象的名称。由于您没有提供您的 save() 代码,我不确定您的加载文件中实际包含什么,但如果它是一个名为 data 的变量,那么只需调用

    load(rdataFile)
    

    不是

    data <- load(rdataFile)
    

    【讨论】:

    • 感谢您的回答!我根据您的回答更新了我的问题以澄清事情(请参阅更新 2)。如您所见,我每个数据文件只加载一个对象,所以我不希望有任何冲突。但是,请务必查看并发表评论,因为我对 R 对象操作(以及 R,一般而言,就此而言)没有太多经验。
    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-20
    • 2013-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多