我有一个Rscript,它以平面文件的形式读取恒定的数据流。另一个脚本获取此平面文件,进行一些解析和处理,然后将结果保存为RDS格式的data.frame。然后它睡觉,并重复这个过程。
saveRDS(tmp.df, file="H:/Documents/tweet.df.rds") #saving the data.frame
在第二次...第n次迭代中,我让代码只处理自上一次迭代以来添加到平面文件的新行。但是,为了将增量线附加到永久数据帧,我必须将其读入,追加,然后将其保存回来,覆盖原始数据。
df2 <- readRDS("H:/Documents/tweet.df.rds") #read in permanent
tmp.df2 <- rbind(df2, tmp.df) #append new to existing
saveRDS(tmp.df2, file="H:/Documents/tweet.df.rds") #save it
rm(df2) #housecleaning
rm(tmp.df2) #housecleaning
这种方法存在风险,因为每当RDS打开读/写时,另一个想要触摸该文件的进程都必须等待。随着基础文件变大,风险也会增加。
是否有类似appendRDS
(我确实知道没有)的东西可以实现我想要的 - 迭代更新保存到文件的单个数据框 - 使用附加而不是完全替换?
答案 0 :(得分:4)
我认为您可以通过使用连接来保护您的流程,在下一个流程接管之前打开和关闭它。
con <- file("tmp.rds")
open(con)
df <- readRDS(con)
df.new <- rbind(df,df)
saveRDS(df.new, con)
close(con)
更新:
您可以测试与文件的连接是否已打开,如果您遇到并发问题,请告诉它等待一点。
while(is.Open(con)) { # untested but something of this nature should work
sys.Sleep(2)
}
答案 1 :(得分:1)
在目录中使用一系列编号的RDS文件而不是单个RDS文件有什么问题吗?我不认为可以在不重写整个文件的情况下将数据帧附加到RDS文件,因为数据帧只是列的列表,因此可能它们一次一列地序列化,因此只有最后一列结束靠近文件的末尾。
如果您想坚持使用单个文件但最大限度地降低从RDS文件中读取不一致数据的风险,您可以将其读入,执行追加操作,然后将其写入临时文件并重命名临时文件完成后的原始名称。那么至少你的风险期不依赖于文件的大小。我不熟悉将文件重命名为现有名称时各种文件系统保证的原子性,但它可能比saveRDS所花费的时间更好。