这是一个示例函数,假设我无法编辑它.
myfun <- function(){ x <- 1 ; stop( "error here" ) }
Run Code Online (Sandbox Code Playgroud)
当stop()发生时,我将如何访问该对象x以查看它是什么?
不确定我是否应该使用这样的东西,或者我是否需要相关的东西dump.frames,或者如果不改变就不可能myfun()
withCallingHandlers( myfun() , error = function(e){ print( e ) } )
Run Code Online (Sandbox Code Playgroud)
我正在寻找类似于这种行为的东西,但需要在没有的情况下这样做 myfun()
myfun <- function(){ on.exit( print( x ) ) ; x <- 1 ; stop( "error here" ) }
myfun()
Run Code Online (Sandbox Code Playgroud)
对于我的用例,我无法更改,myfun()因为有大约50个函数,但我想知道错误时每个函数中一致命名的对象
谢谢!
选项1:
当然,您可以逐步使用这些功能browser(),但这可能会耗费您所需的时间.
选项2
虽然你说你无法改变myfun()的原因是"因为大约有50个函数",但这并不是一个不可逾越的障碍.R的一个强大功能是它可以编辑自己的功能.所以我们可以on.exit像这样添加对函数的调用:
body(myfun) <- as.call(c(as.name("{"), expression(on.exit(print(x))), body(myfun)))
Run Code Online (Sandbox Code Playgroud)
我们可以将它包装在一个方便的函数中,它不会像这样改变原始函数:
print.on.exit = function(f, ...){
body(f) <- as.call(c(as.name("{"), expression(on.exit(print(x))), body(f)))
f(...)
}
print.on.exit(myfun)
Run Code Online (Sandbox Code Playgroud)
这是一种使用 来做到这一点的方法trace。我也使用它purr::walk,因为它是无声的,但你可以使用它sapply来达到相同的效果。
首先我们定义 3 个函数,因为您有 50 个函数:
myfun1 <- function(){ x <- 1 ; stop( "error here" ) }
myfun2 <- function(){ x <- 2 ; banana(2) }
myfun3 <- function(){ x <- 3 ; x <- "potatoe" + x }
myfun1() # Error in myfun1() : error here
myfun2() # Error in myfun2() : could not find function "banana"
myfun3() # Error in "potatoe" + x : non-numeric argument to binary operator
Run Code Online (Sandbox Code Playgroud)
然后将它们的名字放入向量中,然后应用此代码,x每当退出函数时都会打印该代码:
funs <- c("myfun1","myfun2","myfun3")
purrr::walk(funs,trace,exit = quote(print( x )))
myfun1()
# Error in myfun1() : error here
# Tracing myfun1() on exit
# [1] 1
myfun2()
# Error in myfun2() : could not find function "banana"
# Tracing myfun2() on exit
# [1] 2
myfun3()
# Error in "potatoe" + x : non-numeric argument to binary operator
# Tracing myfun3() on exit
# [1] 3
Run Code Online (Sandbox Code Playgroud)
然后恢复正常:
purrr::walk(funs,untrace)
Run Code Online (Sandbox Code Playgroud)
编辑
用上面的方法,x即使没有错误也会打印
myfun4 <- function(){ x <- 4 ; TRUE }
trace(myfun4, exit = quote(print( x )))
myfun4()
Tracing myfun4() on exit
[1] 4
[1] TRUE
Run Code Online (Sandbox Code Playgroud)
要仅在错误时打印x,您可以使用以下代码,出于同样的原因,我将print参数设置为FALSE更轻的显示,并使其比错误情况下的打印值更清晰 x :
untrace(myfun4)
funs <- c("myfun1","myfun2","myfun3","myfun4")
purrr::walk(funs,trace, print=FALSE,exit=quote(
if(exists(".Traceback") && .Traceback[[length(.Traceback)]] == sys.calls()[[1]]){
message("x at time of error:")
print(x)}))
myfun3()
# Error in "potatoe" + x : non-numeric argument to binary operator
# x at time of error:
# [1] 3
myfun4()
# [1] TRUE
Run Code Online (Sandbox Code Playgroud)