在调试和解决我的检索属性问题的过程中(我可以在不从文件中完全加载对象的情况下访问 R 数据对象的属性吗?),根据这里关于 SO 的建议,我相应地从使用save()
and切换load()
到saveRDS()
and readRDS()
。
我的调查(通过非交互式调试打印)显示如下:
在初始化之后
saveRDS()
,保存的对象立即包含有问题的属性;在脚本初始运行后执行的交互式 R 会话显示保存的对象中缺少该属性;
上面的先前发现解释了在脚本的下一次运行期间未能检索到所述属性,我最初错误地将其归因于
save/load
行为saveRDS/readRDS
。
为了在初始之后立即手动确认持久对象(保存在.rds
文件中)中属性的存在saveRDS
,我决定暂停在一个终端窗口中运行的批处理 R 脚本,使用scan
(readLine
似乎不适用于批处理R 脚本):
if (DEBUG) {
cat("Press [Enter] to continue")
key <- scan("stdin", character(), n=1)
}
并且,在另一个终端窗口中,通过交互式 R session检查保存的对象。
但是,当批处理脚本按预期停止后,在交互式会话中从文件中加载保存的对象失败并显示以下消息:.rds
> 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
以下输出描述了我在调查时的R 环境:
> 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
对我来说唯一合理的解释是批处理会话(特别是通过 暂停scan
)以某种方式锁定或修改了环境,使得无法从交互式会话中正确访问 R 对象。这种情况可能还有其他可能的原因。我将不胜感激任何帮助或建议来解决这个问题!
更新:
在杀死批处理 R 脚本的进程(之后scan
变得无响应)后,我再次尝试手动加载.rds
文件,由于批处理脚本中没有暂停,我期待成功。然而,令我惊讶的是,我收到了完全相同的错误消息。这使我认为该.rds
文件确实已损坏(可能是由于我通过反复按停止正在运行的批处理 R 脚本的做法Ctrl-C
- 我需要想出一些更“温和”的东西)。在找出停止运行脚本的更好方法后,我将尝试重现该场景并在此处报告。
更新 2:
从缓存目录中删除所有(可能损坏的).rds
文件并遵循上述场景(以交互方式加载 R 数据文件并暂停批处理 R 脚本)后,输出显示与以前完全相同的错误消息。在这一点上,我真的需要一个建议来弄清楚发生了什么。
UPADATE 3(保存对象):
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)
更新4(可重现的例子):
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)
我希望保存变量的值,dataName
但是代码保存了变量的名称。