在调试和解决我的问题时,检索属性(Can I access R data objects' attributes without fully loading objects from file?),根据SO上的建议,我从使用save()
和load()
切换到{{1} }和saveRDS()
,相应地。
我的调查(通过非交互式调试打印)显示以下内容:
在初始readRDS()
之后,保存的对象包含相关属性;
在初始运行脚本后执行的交互式R会话,从保存的对象中显示属性的缺席;
上述调查结果解释了在下一次运行脚本期间无法检索所述属性,我最初错误地将其归因于saveRDS()
和save/load
行为。
为了在初始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)
变量的值,但代码会保存变量的名称。
答案 0 :(得分:2)
如果您使用saveRDS
保存某些内容,则等效的loading
函数为readRDS
/
如果您将save
对象放入RData
文件,则应使用load
加载对象。
readRDS
将允许您指定要加载的对象的名称。
load
将objects
加载到.RData
文件中,并保留用于保存这些文件的名称。
如果"../cache/SourceForge/ZGV2TGlua3M=.rds"
使用saveRDS
保存,则
whatever <- readRDS("../cache/SourceForge/ZGV2TGlua3M=.rds")
会将对象加载为whatever
对未以load
格式保存的文件运行.RData
将导致您发布的错误消息。