如何让R自动保存历史记录(auto save R history before crash)

也许第一眼看到这个题目,您可能并不认为这是一个问题,因为大家都知道,R会自动在当前工作目录保存名为.Rhistory或者.Rapp.history的文件。这个文件中就是R自动保存的历史记录。但是这种自动保存的历史记录有两个缺点,第一,它只在正常退出的时候保存;第二,它有行数限制。

我提出的这个问题,其实是因为我经常遇到R崩溃的情况,或者R无限耗用内存的情况。在这些情况下,R无法正常退出,也就无法保存历史记录了。有些时候,你工作了很久,突然崩溃,而你又没有保存任何数据,是多么让人崩溃的一件事情啊。

我想着如果可以让R自动保存历史记录至一个临时文件当中,即使R崩溃了,也不至于什么都没有留下,至少还可以通过历史记录,将其重现,多好?

于是我写了如下的代码:

######################################################
#by Jianhong Ou @ umassmed @ quiworld @ Oct 22, 2013
######################################################
 
Sys.setenv("tmpfile_USED_BY_autoHistorySavor" = tempfile(pattern="Rtmp.", tmpdir="~/Rtmp", fileext=".history"), "codesLines_USED_BY_autoHistorySavor" = 0) 
 
 
write(paste("Jianhong Ou @", format(Sys.Date(), format="%B %d %Y"))
	, Sys.getenv("tmpfile_USED_BY_autoHistorySavor"), sep="\n")
 
 
 
if(interactive()){
	taskCallbackManager()$add(function(expr, value, ok, visible){
			write(deparse(expr), Sys.getenv("tmpfile_USED_BY_autoHistorySavor"), append=TRUE, sep="\n")
			Sys.setenv("codesLines_USED_BY_autoHistorySavor" = as.numeric(Sys.getenv("codesLines_USED_BY_autoHistorySavor")) + 1)
			return(TRUE)
	}, name="autoHistorySavor")
}
 
 
.Last <- function(){
        if(interactive()){
			removeTaskCallback("R-taskCallbackManager")
        }
	if(as.numeric(Sys.getenv("codesLines_USED_BY_autoHistorySavor")) < 1){
		file.remove(Sys.getenv("tmpfile_USED_BY_autoHistorySavor"))
	}
}

把上述代码以Rprofile.site为名保存至当前R版本的etc目录下(比如Mac中的/Library/Frameworks/R.framework/Versions/3.0/Resources/etc,或者Windows中的C:\Program Files\R\R-n.n.n\etc)或者以.Rprofile为文件名保存至当前用户目录下。再运行R即可。

上述代码中,如果R正常退出,会自动删除临时文件。如果R不能正常退出,临时文件就会被保留下来。当然,我们还可以增加自动保存数据的功能,但那样会让运行变得很慢。

Leave a Reply

  

  

  

%d 博主赞过: