R语言tryCatch使用方法:判断Warning和Error
1. 出门掉坑里
因为一些情况,需要判断一行命令运行的状态,然后再做出反应,整体来说:
- 是否出现warning,出现了怎么处理?
- 是否出现Error,出现了怎么处理?
- 没有出现怎么处理?
R中判断warning和error状态的函数,我没有找到。一个玩Java
的同事说,try.....catch
多经典的方法,你怎么不用呢?
我知道R中有
tryCatch
这个函数,但是没有具体用过。我一直把R语言当作科学计算语言,没有当成编程语言,伪程序员的气质从没有用过tryCatch
表现出来了。当然,我不会说这是我的问题,我会甩锅,都是R语言
的锅,它根本不是编程语言……。吐槽完毕,我还是要从编程的角度学习
R语言
,正所谓脑子一堆粪,看什么都是粪
说的就是我啊,一直把R语言当做高级计算器,怎么能知道R语言的编程功能呢!
。既然已经用到了,那我就研究一下它的用法,然后用个示例,解释一下它的用法,希望对后来者有用。
2. 梯子怎么用?
tryCatch
的整体逻辑:
tryCatch({
命令
}, warning = function(w){
# 这里是出现warning状态时,应该怎么做,可以用print打印出来,可以执行其它命令
}, error = function(e){
# 这里时出现Error状态时,应该怎么做,可以用print打印出来,也可以执行其它命令
},finally = {
# 这是运行正常时,应该怎么做,可以用print打印出来,也可以执行其它命令
})
3. 走两步试试?
下面用一个示例,看一下tryCatch
是怎么使用的。
首先看一下R中warning
的报警信息:
warning
# 示例数据
library(data.table)
dd = data.frame(ID = 1:10,y= rnorm(10))
dd
# warning
re1 = dcast(dd,y~.)
re1
> re1 = dcast(dd,y~.)
Using 'y' as value column. Use 'value.var' to override
Warning message:
In dcast(dd, y ~ .) :
The dcast generic in data.table has been passed a data.frame and will attempt to redirect to the reshape2::dcast; please note that reshape2 is deprecated, and this redirection is now deprecated as well. Please do this redirection yourself like reshape2::dcast(dd). In the next version, this warning will become an error.
可以看到,代码执行成功了,但是会给出Warning message
然后我们看一下Error
的报警信息,假定R中没有aaaaa
的对象,你直接打印出来,会报错:
# error
aaaaa
> # error
> aaaaa
错误: 找不到对象'aaaaa'
那我们用tryCatch
走两步看看?
warning处理代码
- 在代码中,写下warning的语句,在
warning
的条件下,返回2
- 在代码中,写下error的语句,在
error
的条件下,返回3
re1 = tryCatch({
dcast(dd,y~.) # warning
# aaaaa # error
},warning = function(w){
2
print("warning")
},error = function(e){
3
print("error")
})
re1
结果如下:
> re1 = tryCatch({
+ dcast(dd,y~.) # warning
+ # aaaaa # error
+
+ },warning = function(w){
+ print("warning")
+ 2
+
+ },error = function(e){
+ print("error")
+ 3
+ })
[1] "warning"
> re1
[1] 2
可以看到,因为dcast(dd,y~.) # warning
返回warning
,所以会执行function(w){}
的内容,即re1 = 2
,同时打印出warning
.
error处理代码
如果我们执行error
的代码,那么他就re1=3
,同时打印出error
re1 = tryCatch({
# dcast(dd,y~.) # warning
aaaaa # error
},warning = function(w){
print("warning")
2
},error = function(e){
print("error")
3
})
re1
结果如下:
> re1 = tryCatch({
+ # dcast(dd,y~.) # warning
+ aaaaa # error
+
+ },warning = function(w){
+ print("warning")
+ 2
+
+ },error = function(e){
+ print("error")
+ 3
+ })
[1] "error"
> re1
[1] 3
可以看到,打印出了error
的警告,同时,re1赋值为了3
。
4. 意料之外的判断
我有一个大胆的想法,如果一个程序,既有warning
,又有error
怎么办?
一般情况下,是不会存在这种情况的,但是如果有,R语言是如何处理的呢?
看示例:
melt这个函数,运行melt(dd,y~.)
会报错,同时,因为这个函数在data.table
用法有变化,因此,也会给出warning
信息。
> # 既有warning,又有error时,以warning为主
> melt(dd,y~.)
Error in match(x, y, 0L) : 'match'需要矢量参数
此外: Warning message:
In melt(dd, y ~ .) :
The melt generic in data.table has been passed a data.frame and will attempt to redirect to the relevant reshape2 method; please note that reshape2 is deprecated, and this redirection is now deprecated as well. To continue using melt methods from reshape2 while both libraries are attached, e.g. melt.list, you can prepend the namespace like reshape2::melt(dd). In the next version, this warning will become an error.
这个时候,如果用tryCatch
,它会捕捉到warning
,而不是error
代码:
re1 = tryCatch({
# dcast(dd,y~.) # warning
# aaaaa # error
melt(dd,y~.)
},warning = function(w){
print("warning")
2
},error = function(e){
print("error")
3
})
re1
运行结果:
> re1 = tryCatch({
+ # dcast(dd,y~.) # warning
+ # aaaaa # error
+ melt(dd,y~.)
+
+ },warning = function(w){
+ print("warning")
+ 2
+
+ },error = function(e){
+ print("error")
+ 3
+ })
[1] "warning"
> re1
[1] 2
所以呢,要注意上面的情况,有时候warning
和error
同时存在时,warning
的优先级是靠前的。
5. 顺利上岸
上岸过程见3. 走两步试试?
6. 被借鉴的文章
http://www.mazamascience.com/WorkingWithData/?p=912 https://sarahpenir.github.io/r/Warning-and-Error-Handling-with-trycatch/
7. 技术创作101训练营
因为参加了技术创作101训练营
,要写一篇技术文档,所以这是一篇一边debug,一边写总结
的应试文章。
- mysql替换某个字段中的某个字符
- Angular企业级开发(1)-AngularJS简介
- PHP在Apache下500错误
- mysql 学习笔记
- MongoDB学习系列(2)--使用PHP访问MongoDB
- (cljs/run-at (JSVM. :browser) "命名空间就这么简单")
- Angular企业级开发(10)-Smart Table插件开发
- 安装Ubuntu时分区选择
- linux系统下安装两个或多个tomcat
- JS魔法堂:不完全国际化&本地化手册 之 实战篇
- scala + intellij idea 环境搭建及编译、打包
- Angular企业级开发(2)-搭建Angular开发环境
- JS魔法堂:不完全国际化&本地化手册 之 拓展篇
- 使用jQuery的animate方法制作滑动菜单
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Service三问
- 事件分发机制三问
- C++核心准则T.141:如果你需要只在一个地方使用的简单的函数对象,使用无名的lambda表达式
- 基于DOM的XML文件解析类
- C++核心准则T.143:避免无意中编写非通用代码
- XML文件解析实践(DOM解析)
- golang 多协程的同步方法总结
- C++核心准则T.144:不要特化函数模板
- 三千字带你搞懂XXL-JOB任务调度平台
- Python-科学计算-pandas-14-df按行按列进行转换
- Python实现扫码工具
- C++核心准则T.150:用static_assert检查类和概念的匹配性
- 初学者也能快速写Python脚本啦——通用功能代码分享
- C++核心准则CPL.1:C++比C更好
- C++核心准则CPL.2:如果你必须使用C,使用C和C++的共同子集,并且使用C++编译器编译C代码