R中的exception处理
有没有人有R的例外/教程exception处理? 官方文件非常简洁。
除了Shane的回答指向其他StackOverflow讨论,你可以尝试一个代码searchfunction。 这个原来的答案指向谷歌的代码search已经停止,但你可以尝试
- Githubsearch例如在这个查询tryCatch in language = R ;
- Ohloh / Blackduck代码search例如这个查询R文件中的tryCatch
- Debian代码search引擎在整个Debian档案之上
只是为了logging,也有try
但tryCatch
可能是可取的。 我在Google代码search中尝试了一下,但是尝试为动词本身提供了太多的误报 – 但似乎tryCatch
被广泛使用。
基本上你想使用tryCatch()
函数。 看看帮助(“tryCatch”)的更多细节。
这是一个简单的例子(记住,你可以做任何你想要的错误):
vari <- 1 tryCatch(print("passes"), error = function(e) print(vari), finally=print("finished")) tryCatch(stop("fails"), error = function(e) print(vari), finally=print("finished"))
看看这些相关的问题:
- R中“throw”的等价
- 捕获一个错误,然后分支逻辑
- https://stackoverflow.com/search?q=%5Br%5D+trycatch
谷歌相关search的结果帮助了我: http : //biocodenv.com/wordpress/?p=15 。
for(i in 1:16){ result <- try(nonlinear_modeling(i)); if(class(result) == "try-error") next; }
在从Lispinheritance的R中,重启function是非常重要的。 如果你想在循环体中调用一些函数,并且只是希望程序在函数调用崩溃的时候继续,那么这将非常有用。 试试这个代码:
for (i in 1:20) withRestarts(tryCatch( if((a <- runif(1))>0.5) print(a) else stop(a), finally = print("loop body finished!")), abort = function(){})
函数trycatch()
是相当直接的,有很多很好的教程。 关于R中error handling的一个很好的解释可以在Hadley Wickham的Advanced-R一书中find,接下来的内容是尽可能less地描述withCallingHandlers()
和withRestarts()
:
比方说一个低级程序员写一个函数来计算绝对值。 他不知道如何计算,但知道如何构build一个错误 ,勤奋地expression他的天真:
low_level_ABS <- function(x){ if(x<0){ #construct an error negative_value_error <- structure( # with class `negative_value` class = c("negative_value","error", "condition"), list(message = "Not Sure what to with a negative value", call = sys.call(), # and include the offending parameter in the error object x=x)) # raise the error stop(negative_value_error) } cat("Returning from low_level_ABS()\n") return(x) }
一个中级程序员也写一个函数来计算绝对值,利用可悲的不完整的low_level_ABS
函数。 他知道,当x
的值为negative_value
时,低级代码会抛出一个negative_value
错误,并通过build立一个允许mid_level_ABS
用户控制mid_level_ABS
从(或不)从其中恢复的方式的restart
来解决该问题。一个negative_value
错误。
mid_level_ABS <- function(y){ abs_y <- withRestarts(low_level_ABS(y), # establish a restart called 'negative_value' # which returns the negative of it's argument negative_value_restart=function(z){-z}) cat("Returning from mid_level_ABS()\n") return(abs_y) }
最后,高级程序员使用mid_level_ABS
函数来计算绝对值,并通过使用重启处理程序build立一个条件处理器,告诉mid_level_ABS
从negative_value
错误中恢复。
high_level_ABS <- function(z){ abs_z <- withCallingHandlers( # call this function mid_level_ABS(z) , # and if an `error` occurres error = function(err){ # and the `error` is a `negative_value` error if(inherits(err,"negative_value")){ # invoke the restart called 'negative_value_restart' invokeRestart('negative_value_restart', # and invoke it with this parameter err$x) }else{ # otherwise re-raise the error stop(err) } }) cat("Returning from high_level_ABS()\n") return(abs_z) }
这一切的关键是,通过使用withRestarts()
和withCallingHandlers()
,函数mid_level_ABS
能够告诉mid_level_ABS
如何从low_level_ABS
错误引发的错误中恢复,而不会停止mid_level_ABS
的执行,这是您不能执行的操作tryCatch()
:
> high_level_ABS(3) Returning from low_level_ABS() Returning from mid_level_ABS() Returning from high_level_ABS() [1] 3 > high_level_ABS(-3) Returning from mid_level_ABS() Returning from high_level_ABS() [1] 3
在实践中, low_level_ABS
表示mid_level_ABS
调用很多(甚至可能是数百万次)的函数, mid_level_ABS
这种函数,error handling的正确方法可能因情况而异,并且如何处理特定错误的select留给较高级函数( high_level_ABS
) 。