[R]R语言里的异常处理与错误控制
之前一直只是在写小程序脚本工具,几乎不会对异常和错误进行控制和处理。
随着脚本结构和逻辑更复杂,脚本输出结果的准确性验证困难,同时已发布脚本的维护也变得困难。所以也开始考虑引入异常处理和测试工具的事情。
不过好像R语言的异常处理似乎有些辣鸡?查了下资料和try的文档说明,感觉说的并不清楚。
在网上查了一些资料,对R语言异常处理做了比较详细的说明,留档作为参考。至于测试工具的问题,后续还是再考虑下。
文章链接:R语言-处理异常值或报错的三个示例
原文参考了以下几个网页:
http://stackoverflow.com/questions/14059657/how-to-skip-an-error-in-a-loop
http://stackoverflow.com/questions/8093914/skip-to-next-value-of-loop-upon-error-in-r-trycatch (这个链接里还连接了非常多的关于R语言异常处理)。
============================= 本人的分割线 ===============================
在开始之前,或许应该参考一下其他语言里面的异常处理机制。
先奉上Java方面的参考资料:深入理解java异常处理机制
除了第4点,其他基本无参考意义。因为R已经将比较底层的东西给隐藏起来,异常(运行时异常、编译异常等)方面的资料也缺少(cran文档库也没有很具体的信息)。所以这里只参考第四点,讨论处理异常机制。
R语言处理异常机制:
异常的处理分为抛出异常和捕捉异常。
抛出异常:当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统,异常对象中包含了异常类型和异常出现时的程序状态等异常信息。
虽然不确定R中是否存在运行时系统这个概念,但是其他地方的描述,应该是跟Java的异常是一致的。
捕捉异常:
如果tryCatch中调用的语句产生一个错误,它会执行一个以error为参数的函数,并返回这个函数的值。以error为参数的函数,需要将错误本身作为一个参数(这里称之为e),但是我们可以不对它做任何操作。
当然,我们也可以使用较为简单的try语句。选择哪个基于各自的喜好。
假如你的语句产生一个错误,try会返回一个类型为try-error的对象,并将其信息输出至屏幕(若silent=FALSE)。
===== 0524 更 ========
http://stackoverflow.com/questions/8093914/skip-to-next-value-of-loop-upon-error-in-r-trycatch
使用tryCatch需要知道很关键的一点: tryCatch会返回一个对象。见如下代码:
x <- tryCatch(stop("Error"), error = function(e) e)
class(x)
"simpleError" "error" "condition"
如果在tryCatch中存在一个error,则这个返回的对象会继承error类。我们可以通过inherit函数来检验类继承。
另: 在tryCatch中的参数 error = function(e) e 是什么意思呢?
这有点难到我了。文档中也没有看到很好的解释。这当中的过程是,这个参数会捕获你在tryCatch中的代码表达式产生的任何error信息。假如捕获到error,它则将返回的值作为tryCatch的值(记住tryCatch会返回一个对象)。文档中将其称为calling handler。在 error = function(e)中的e, 就是你代码表达式中的错误信息。
关于在循环代码中使用next:
程序性编程中认为使用next不太好。所以假如想要在for循环中去掉next,可以考虑:
for (i in 1:39487) {
#ERROR HANDLING
possibleError <- tryCatch(
thing(),
error=function(e) e
)
if(!inherits(possibleError, "error")){
#REAL WORK
useful(i); fun(i); good(i);
}
} #end for
======= 果然不只是我对tryCatch的文档云里雾里.... ================
参见:Using R — Basic error Handing with tryCatch()
在开始之前,我们先了解下异常处理中的相关函数列表。以下是这方面函数的最精简的列表了:
- warning(...) - 生成warnings
- stop(...) - 生成errors
- suppressWarnings(expr) - 运行expr表达式, 并忽略任何warnings
- tryCatch(...) - 运行代码并赋值给异常处理器(exception handlers)
还有其他与异常处理相关的函数,不过以上这些已经足够我们了解R的异常处理了。
R 异常处理与 JAVA中的try-catch-finally机制不同
如果你注意到的话,R在很多问题的处理上和其他大多数语言都不一样。
Java、Python和C以及其他在此维基页面(Exception handling syntax)上提到的语言,都使用语言语句(即关键字)来实现try-catch-finally。但R就特立独行,它使用一个函数来实现....
不过如果你代码写的好的话,tryCatch()函数其实看起来和其他语言的try-catch语法差不多。上代码:
result = tryCatch({
expr
}, warning = function(w) {
warning-handler-code
}, error = function(e) {
error-handler-code
}, finally = {
cleanup-code
}
在tryCatch()中,可以处理两种情况:'warnings' 和 'errors'.要理解每一块代码的意义,关键是要清楚代码的运行状态与作用域。以下节选自?tryCatch文档:
If a condition is signaled while evaluating ‘expr’ then [...] control is transferred to the ‘tryCatch’ call
that established the handler[...] and the result returned by the handler is returned as the value of the ‘tryCatch’ call. [...]
The ‘finally’ expression is then evaluated in the context in which ‘tryCatch’ was called.
'expr'一次执行一行,直到遇到'condition',然后程序执行会完整地转移给handler。
代码能比文字表达更多信息。文末的独立R脚本展现了一个健壮的异常处理系统的各种特性:
- 在一个函数中产生warnings和errors
- 在tryCatch()中设置warning和error处理器(handler)
- 当函数产生warning或error时,提供备选的返回值
- 修改warning和error信息的内容
- 抑制warning信息
复制粘贴文末的脚本,使其可执行,并使用以下命令执行:
$ chmod +x tryCatch.Rscript
$ ./tryCatch.r 1
$ ./tryCatch.r 0
$ ./tryCatch.r a
$ ./tryCatch.r
$ ./tryCatch.r warning
$ ./tryCatch.r error
$ ./tryCatch.r suppress-warnings
注意当'suppress-warnings'时发生了什么。
以下是一些你需要知道的,关于这个实验脚本的信息:
- tryCatch()的使用并不难(一旦你知道如何使用)
- condition handler 能访问到warning()和stop()信息
- 在传递函数参数之前,准备好合适的类型转换。
- 最理想的情况是,tryCatch()的代码表达式只是一个单独的函数。
以下是tryCatch.Rscript范例脚本。Hope You enjoy Error handling.
#!/usr/bin/env Rscript
# tryCatch.Rscript -- experiments with tryCatch # Get any arguments
arguments <- commandArgs(trailingOnly=TRUE)
a <- arguments[1] # Define a division function that can issue warnings and errors
myDivide <- function(d, a) {
if (a == 'warning') {
return_value <- 'myDivide warning result'
warning("myDivide warning message")
} else if (a == 'error') {
return_value <- 'myDivide error result'
stop("myDivide error message")
} else {
return_value = d / as.numeric(a)
}
return(return_value)
} # Evalute the desired series of expressions inside of tryCatch
result <- tryCatch({ b <- 2
c <- b^2
d <- c+2
if (a == 'suppress-warnings') {
e <- suppressWarnings(myDivide(d,a))
} else {
e <- myDivide(d,a) # 6/a
}
f <- e + 100 }, warning = function(war) { # warning handler picks up where error was generated
print(paste("MY_WARNING: ",war))
b <- "changing 'b' inside the warning handler has no effect"
e <- myDivide(d,0.1) # =60
f <- e + 100
return(f) }, error = function(err) { # error handler picks up where error was generated
print(paste("MY_ERROR: ",err))
b <- "changing 'b' inside the error handler has no effect"
e <- myDivide(d,0.01) # =600
f <- e + 100
return(f) }, finally = { print(paste("a =",a))
print(paste("b =",b))
print(paste("c =",c))
print(paste("d =",d))
# NOTE: Finally is evaluated in the context of of the inital
# NOTE: tryCatch block and 'e' will not exist if a warning
# NOTE: or error occurred.
#print(paste("e =",e)) }) # END tryCatch print(paste("result =",result))
[R]R语言里的异常处理与错误控制的更多相关文章
- 【C++】异常简述(一):C语言中的异常处理机制
人的一生会遇到很多大起大落,尤其是程序员. 程序员写好的程序,论其消亡形式无非三种:无疾而终.自杀.他杀. 当然作为一名程序员,最乐意看到自己写的程序能够无疾而终,因此尽快的学习异常处理机制是非常重要 ...
- (转)\r \r\n \t 的区别
小风吹雪 \r \r\n \t 的区别 http://www.360doc.com/content/12/0530/15/16538_214756101.shtml \n 软回车: 在Wi ...
- C语言中的异常处理
一 前言: 异常处理,对于做面向对象开发的开发者来说是再熟悉不过了,例如在C#中有 try { ... } catch( Exception e){...} finally{ ..... } 在C++ ...
- 文件操作:w,w+,r,r+,a,wb,rb
1.文件操作是什么? 操作文件: f = open("文件路径",mode="模式",encoding="编码") open() # 调用操 ...
- 把十进制整数转换为r(r=2)进制输出(顺序栈实现)
上周的第二个作业补上~~ 上周的要求: 1.给出顺序栈的存储结构定义. 2.完成顺序栈的基本操作函数. 1) 初始化顺序栈 2) 实现入栈和出栈操作 3) 实现取栈顶元素 ...
- c语言里用结构体和指针函数实现面向对象思想
一.基础研究 观察如下两个程序a.c和b.c: A.c: B.c: 这两个程序都是要实现在屏幕上第10行40列打印一个绿色的字符c: 这两个程序的数据组织方式是一样的,都是使用结构体,而且对共性和个性 ...
- [原创]C语言里为何会有“2+2=5”的结果
原文链接:C语言里为何会有“2+2=5”的结果 写这篇原创文章是因为看到了极客中的一篇文章<有趣各种编程语言实现2+2=5>,其中C语言是这样实现的: int main() { ″; // ...
- const分别在C和C++语言里的含义和实现机制
const的含义 简单地说:const在c语言中表示只读的变量,而在c++语言中表示常量. C语言 const是constant的缩写,是恒定不变的意思,也翻译为常量,但是很多人都认为被 ...
- python文件操作各种模式和常用方法总结r r+ rb r+b
1.读,r r+ rb r+b read() 全部读取 read(n) 读取一部分 r模式下:n 个字符. rb模式下:n个 字节. readline() 按行读取. readlines() 返回个列 ...
随机推荐
- web项目没有run on server时..
文章转载至:http://blog.csdn.net/hongchangfirst/article/details/7722703 web项目没有run on server 1.首先确保正确安装Tom ...
- phpcms 标签
都说pc标签{pc:content参数名="参数值"参数名="参数值"参数名="参数值"} 但是 参数名对应的具体参数值有那些,菜鸟就不知道 ...
- 同一内网不能网段ping 不通
[root@NB sysconfig]# route Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use ...
- 微信支付 - V3支付问题
参考资料:http://www.2cto.com/weixin/201506/407690.html 1.微信公众号支付出错: 当前页面的URL未注册: get_brand_wcpay_reque ...
- 在ubuntu上搭建开发环境5---联想Y470安装 ubuntu,解决双显卡发热等问题
ubuntu14 没有解决显卡的问题的时候,会有这样的问题 1.耗电特别快.风扇狂转 2.鼠标键头显示有问题,乱闪,根本没法使用,容易卡住找不到鼠标箭头在哪里了:感觉图形界面显示也有问题,不稳定 解决 ...
- MSSQL数据的批量插入
一.概述: 对于数据的批量插入操作似乎成了某些大数据量操作的必用手段,MSSQL也提供了一些数据批量插入的操作方法,先将这些方法汇总,以便于下次用到使用.面对数据的批量插入操作,我们也应该考虑一个问题 ...
- 几年前做家教写的C教程(之二)
C语言学习宝典(2) 认识C语言中的运算符: (1)算术运算符 (+ - * / %) (2)关系运算符 (> < == >= <= != ) (3 ...
- sdut 1465 公共因子
公共因子 Time Limit: 1000MS Memory limit: 65536K 题目描述 题目链接:http://acm.sdut.edu.cn/sdutoj/problem.php?act ...
- ASP.NET多线程下使用HttpContext.Current为null解决方案 2015-01-22 15:23 350人阅读 评论(0) 收藏
问题一:多线程下获取文件绝对路径 当我们使用HttpContext.Current.Server.MapPath(strPath)获取绝对路径时HttpContext.Current为null,解决办 ...
- cordova+angularJS+ionic
1.创建项目 2.路由 angular.module("starter",['ionic']) // 依赖 ionic 提供的ui-router .config(function ...