假设我在脚本中有一堆R代码,我想将从.GlobalEnv运行的所有R代码与错误和警告消息一起记录到平面文件或数据库中.我可以编写一个简单的logme函数,如下所示,或者通过更改来获取错误使其更复杂一些options(error = mylogginfunction)
mylogfile <- tempfile()
logme <- function(x){
mode <- "at"
if(!file.exists(mylogfile)){
mode <- "wt"
}
myconn <- file(mylogfile, mode)
writeLines(x, myconn)
close(myconn)
invisible()
}
logme(sprintf("%s: started some yadayada, ", Sys.time()))
x <- 10
x * 7
logme(sprintf("%s: done with yadayada", Sys.time()))
## Get the log
cat(readLines(mylogfile))
Run Code Online (Sandbox Code Playgroud)
日志打印出来: 2015-05-14 17:24:31:开始一些yadayada,2015-05-14 17:24:31:用yadayada完成
但我想要的是,日志文件记下了执行的表达式,而不必在每个语句周围编写包装器.我希望日志看起来像. 2015-05-14 17:24:31:开始一些yadayada, x < - 10,x*7 2015-05-14 17:24:31:用yadayada完成
所以我的问题是,如何获取R正在执行的内容,以便我可以将执行的表达式存储在日志/数据库中.而且无需在每个表达式之前编写函数调用(如myhandler(x < - 10); myhandler(x*10)).对此有何帮助?
在任何情况下这可能都很简单,但你可以尝试这样做:
将 myhandler 定义为:
myhandler <- function(x, file = stdout()) {
expr <- substitute(x)
for(e_line in as.list(expr)) {
cat( file = file, as.character(Sys.time()), capture.output(e_line), "\n")
eval(e_line, envir = parent.frame())
}
}
Run Code Online (Sandbox Code Playgroud)
将其与括号内的代码一起使用:
myhandler({
a <- 1
a <- a + 1
print(a)
})
Run Code Online (Sandbox Code Playgroud)
结果:
# 2015-05-14 18:46:34 `{`
# 2015-05-14 18:46:34 a <- 1
# 2015-05-14 18:46:34 a <- a + 1
# 2015-05-14 18:46:34 print(a)
# [1] 2
Run Code Online (Sandbox Code Playgroud)