不完全确定用例,但是当遇到问题时,可以调用函数traceback()。这将显示您的函数调用通过堆栈的路径,直到它遇到问题。如果您倾向于从顶部向下工作,则可以在进行函数调用之前对列表中给出的每个函数调用debug。然后你会从一开始就经历整个过程。
下面是一个示例,说明如何以更系统的方式执行此操作,方法是创建一个逐步执行的函数:
walk.through <- function() {
tb <- unlist(.Traceback)
if(is.null(tb)) stop("no traceback to use for debugging")
assign("debug.fun.list", matrix(unlist(strsplit(tb, "\\(")), nrow=2)[1,], envir=.GlobalEnv)
lapply(debug.fun.list, function(x) debug(get(x)))
print(paste("Now debugging functions:", paste(debug.fun.list, collapse=",")))
}
unwalk.through <- function() {
lapply(debug.fun.list, function(x) undebug(get(as.character(x))))
print(paste("Now undebugging functions:", paste(debug.fun.list, collapse=",")))
rm(list="debug.fun.list", envir=.GlobalEnv)
}
这是一个使用它的虚拟示例:
foo <- function(x) { print(1); bar(2) }
bar <- function(x) { x + a.variable.which.does.not.exist }
foo(2)
# now step through the functions
walk.through()
foo(2)
# undebug those functions again...
unwalk.through()
foo(2)
IMO,这似乎不是最明智的做法。简单地进入发生问题的函数(即在最低级别)并向后工作会更有意义。
我已经在"favorite debugging trick" 中概述了这个基本例程背后的逻辑。