获取运行时运行的所有R代码

15 eval r try-catch

假设我在脚本中有一堆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)).对此有何帮助?

ber*_*ant 0

在任何情况下这可能都很简单,但你可以尝试这样做:

将 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)