尝试以交互方式加载由暂停的批处理脚本保存的数据文件时出错

时间:2014-05-19 05:00:34

标签: r session persistence environment rdata

在调试和解决我的问题时,检索属性(Can I access R data objects' attributes without fully loading objects from file?),根据SO上的建议,我从使用save()load()切换到{{1} }和saveRDS(),相应地。

我的调查(通过非交互式调试打印)显示以下内容:

  1. 在初始readRDS()之后,保存的对象包含相关属性;

  2. 在初始运行脚本后执行的交互式R会话,从保存的对象中显示属性的缺席;

  3. 上述调查结果解释了在下一次运行脚本期间无法检索所述属性,我最初错误地将其归因于saveRDS()save/load行为。

    < / LI>

    为了在初始saveRDS/readRDS之后立即手动确认持久对象中存在属性(保存在.rds文件中),我决定使用saveRDS暂停在一个终端窗口中运行的批处理R脚本scan在批处理R脚本中似乎不适用于此:

    readLine

    并在另一个终端窗口中,通过交互式R会话检查保存的对象。

    但是,在批处理脚本按预期停止后,从交互式会话中的if (DEBUG) { cat("Press [Enter] to continue") key <- scan("stdin", character(), n=1) } 文件加载已保存对象时,失败并显示以下消息

    .rds

    以下输出描述了我在调查时的 R环境

    > load("../cache/SourceForge/ZGV2TGlua3M=.rds")
    Error: bad restore file magic number (file may be corrupted) -- no data loaded
    In addition: Warning message:
    file ‘ZGV2TGlua3M=.rds’ has magic number 'X'
      Use of save versions prior to 2 is deprecated
    

    对我来说唯一合理的解释是,批处理会话(特别是通过> sessionInfo() R version 3.0.2 (2013-09-25) Platform: x86_64-pc-linux-gnu (64-bit) locale: [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8 [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 [7] LC_PAPER=en_US.UTF-8 LC_NAME=C [9] LC_ADDRESS=C LC_TELEPHONE=C [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C attached base packages: [1] stats graphics grDevices utils datasets methods base 的暂停)以某种方式锁定或修改环境,这使得无法正确访问R对象来自交互式会话。也许这种情况存在其他可能的原因。 我非常感谢您解决此问题的任何帮助或建议!

    更新:

    在杀死批处理R脚本的进程(scan无响应后)之后,我再次尝试手动加载scan文件,由于没有暂停而期待成功在批处理脚本中。但令我惊讶的是,我收到了完全相同的错误消息。这让我认为.rds文件确实已损坏(可能是由于我通过反复按.rds来停止正在运行的批处理R脚本的做法 - 我需要提出更多内容&#34;温和&#34)。在找出停止正在运行的脚本的更好方法之后,我将尝试重现场景并在此报告。

    更新2:

    从缓存目录中删除所有(可能已损坏的)Ctrl-C文件并遵循上述方案(以批处理R脚本暂停的方式交互式加载R数据文件)后,输出显示完全相同的错误消息和以前一样在这一点上,我真的需要一个建议来弄清楚发生了什么。

    UPADATE 3(保存对象):

    .rds

    更新4(可重现的例子):

    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 RDS file
    saveRDS(data, rdataFile)
    

    我希望保存library(RCurl) info <- "Important data" request <- "SELECT info FROM topSecret" dataName <- "sf.data.devLinks" rdataFile <- "/tmp/testAttr.rds" getData <- function() { return (info) } requestDigest <- base64(request) # check if the archive file has already been processed message("\nProcessing request \"", request, "\" ...\n") # read back the object with the attribute if (file.exists(rdataFile)) { # now check if request's SQL query hasn't been modified data <- readRDS(rdataFile) message("Retrieved object '", as.name(data), "', containing:\n") message(toString(data)) requestAttrib <- attr(data, "SQL", exact = TRUE) message("\nObject '", data, "' contains attribute:\n\"", base64(requestAttrib), "\"\n") if (identical(requestDigest, requestAttrib)) { message("Processing skipped: RDS file is up-to-date.\n") stop() } rm(data) } message("Saving results of request \"", request, "\" as R data object ...\n") assign(dataName, getData()) 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 RDS file saveRDS(data, rdataFile) 变量的,但代码会保存变量的名称

1 个答案:

答案 0 :(得分:2)

如果您使用saveRDS保存某些内容,则等效的loading函数为readRDS / 如果您将save对象放入RData文件,则应使用load加载对象。

readRDS将允许您指定要加载的对象的名称。

loadobjects加载到.RData文件中,并保留用于保存这些文件的名称。

如果"../cache/SourceForge/ZGV2TGlua3M=.rds"使用saveRDS保存,则

whatever <- readRDS("../cache/SourceForge/ZGV2TGlua3M=.rds")

会将对象加载为whatever

对未以load格式保存的文件运行.RData将导致您发布的错误消息。