在R中缓存昂贵的操作

Rob*_*rto 8 caching r

一个非常简单的问题:

我正在使用文本编辑器编写和运行我的R脚本,以使它们可重现,正如SO的几个成员所建议的那样.

这种方法对我来说非常有效,但我有时必须执行昂贵的操作(例如,read.csv或者reshape在2M行数据库上),我最好在R环境中缓存,而不是每次运行脚本时重新运行(这是通常很多次我进步并测试新的代码行).

有没有办法缓存脚本在某一点上的作用,所以每次我只运行增量代码行(就像我通过交互运行R一样)?

谢谢.

chr*_*ler 9

## load the file from disk only if it 
## hasn't already been read into a variable
if(!(exists("mytable")){
  mytable=read.csv(...)
}
Run Code Online (Sandbox Code Playgroud)

编辑:修正错字 - 谢谢德克.

  • 如果您以非交互方式运行,请使用save.image(file ="mydata.Rdata")命令来保存工作区.然后在每次运行开始时使用load()加载工作区.由于R需要将所有数据恢复到内存中,因此仍然需要进行一些研磨,但它将为您节省昂贵的计算步骤. (3认同)
  • `mytable`必须作为字符串给出.发布后,代码不起作用. (2认同)

Dir*_*tel 8

一些简单的方法可以使用一些组合

  • exists("foo") 测试变量是否存在,否则重新加载或重新计算
  • file.info("foo.Rd")$ctime您可以比较Sys.time()并查看它是否比您可以加载的给定时间更新,否则重新计算.

CRAN上还有一些缓存包可能很有用.


JD *_*ong 5

在你做了一些你发现代价高昂的事情之后,将那个代价高昂的步骤的结果保存在 R 数据文件中。

例如,如果您将 csv 加载到名为的数据框中myVeryLargeDataFrame,然后从该数据框中创建汇总统计数据到名为 df 的 df 中,VLDFSummary那么您可以执行以下操作:

save(c(myVeryLargeDataFrame, VLDFSummary), 
  file="~/myProject/cachedData/VLDF.RData", 
  compress="bzip2")
Run Code Online (Sandbox Code Playgroud)

压缩选项是可选的,如果您想压缩正在写入磁盘的文件,则可以使用该选项。有关?save更多详细信息,请参阅。

保存 RData 文件后,您可以注释掉缓慢的数据加载和汇总步骤以及保存步骤,然后像这样简单地加载数据:

load("~/myProject/cachedData/VLDF.RData")
Run Code Online (Sandbox Code Playgroud)

这个答案不依赖于编辑器。它适用于 Emacs、TextMate 等。您可以保存到计算机上的任何位置。但是,我建议将慢速代码保留在 R 脚本文件中,这样您就可以始终知道 RData 文件的来源,并能够在需要时从源数据重新创建它。


Ite*_*tor 5

(迟来的答案,但我在发布这个问题一年后开始使用 SO。)

这是记忆化(或记忆化)背后的基本思想。在这个查询中,我有很长的建议列表,尤其是memoiseR.cache包。

您还可以利用检查点,它也作为同一列表的一部分进行处理。

我认为你的用例反映了我的第二个:“可怕计算的记忆”。:)

我使用的另一个技巧是制作大量内存映射文件,我经常使用这些文件来存储数据。这样做的好处是多个 R 实例可以访问共享数据,所以我可以让很多实例破解相同的问题。