Tuesday, March 31, 2015

之前用rvest帮人写了一个定期抓取amazon价格库存,并与之前价格比较的小程序,算是近期写过的第一个完整的程序了。里面涉及了一些报错的处理。

这里主要参考了stackoverflow上的以下问答:

  1. How to skip an error in a loop
  2. skip to next value of loop upon error in R

tryCatch部分,后续查找资料,发现以下博文: 1. R语言使用tryCatch进行简单的错误处理

以下是代码示例:

1)使用tryCatch函数跳过错误信息。(示例以download.file为样式)

看以下代码。这里需要批量下载一堆amazon产品信息。如果产品ID号不对,或者IP被限制,网页会打不开,而download.file会报错。我这里用tryCatch来获取网页打不开时的错误信息。并且要求执行下一步循环“”。

  1. for (n in 1:length(productlink)){
  2. tryCatch({
  3. download.file(productlink[n],paste0(getwd(),"/html/",productid[n,],".html"),cacheOK = TRUE)
  4. },error=function(e){cat("ERROR :",conditionMessage(e),"\n")})
  5. Sys.sleep(0.5) #增加了Sys.sleep(seconds)函数,让每一步循环都暂停一段时间。这个虽然会降低程序速度,但对于有访问限制的网站,不失为一个好的办法。
  6. }

上述示例由两个重要函数构成,即tryCatch和cat

查阅函数,tryCatch属于base包,condition system。在R语言使用tryCatch进行简单的错误处理这篇博文里有tryCatch的简单示范如下:

  1. result = tryCatch(
  2. {expr},
  3. warning = function(w) {warning-handler-code},
  4. error = function(e) { error-handler-code},
  5. finally = {cleanup-code}
  6. )

即如果warning时,对warning怎么处理,如果error时对error怎么处理。如果没有任何条件吻合,则最后会输出expr里的内容。如果有final项的话,则会同时输出finally项以及expr项

  1. tryCatch({a<-"c"
  2. b<-"c"
  3. b==a},
  4. error=function(e){cat("hahaha",conditionMessage(e),"\n\n")},
  5. finally={print("ccc")})

[1] "ccc"
[1] TRUE

tryCatch({a<-"c"

  1. cc==a}, #cc不存在
  2. error=function(e){cat("hahaha",conditionMessage(e),"\n\n")},
  3. finally={print("ccc")})
    hahaha object 'cc' not found 

对于代码示例,即为,download成功则返回download内容,不成功则返回error=function(e){cat("ERROR :",conditionMessage(e),"\n")}

然后是cat函数。这个cat是一个输入输出值。这里等于,要求系统输出“ERROR :”+conditionMessage(e)的内容。然后用“”分行。

另外,在stackoverflow上的这篇问答,由mmann1123回答的问题里,我们看到了更为有趣的一个应用。

这里收缩起来,展开亦可阅读。

  1. #!/usr/bin/env Rscript
  2. # tryCatch.r -- experiments with tryCatch
  3.  
  4. # Get any arguments
  5. arguments <- commandArgs(trailingOnly=TRUE)
  6. a <- arguments[1]
  7.  
  8. # Define a division function that can issue warnings and errors
  9. myDivide <- function(d, a) {
  10. if (a == 'warning') {
  11. return_value <- 'myDivide warning result'
  12. warning("myDivide warning message")
  13. } else if (a == 'error') {
  14. return_value <- 'myDivide error result'
  15. stop("myDivide error message")
  16. } else {
  17. return_value = d / as.numeric(a)
  18. }
  19. return(return_value)
  20. }
  21.  
  22. # Evalute the desired series of expressions inside of tryCatch
  23. result <- tryCatch({
  24.  
  25. b <- 2
  26. c <- b^2
  27. d <- c+2
  28. if (a == 'suppress-warnings') {
  29. e <- suppressWarnings(myDivide(d,a))
  30. } else {
  31. e <- myDivide(d,a) # 6/a
  32. }
  33. f <- e + 100
  34.  
  35. }, warning = function(war) {
  36.  
  37. # warning handler picks up where error was generated
  38. print(paste("MY_WARNING: ",war))
  39. b <- "changing 'b' inside the warning handler has no effect"
  40. e <- myDivide(d,0.1) # =60
  41. f <- e + 100
  42. return(f)
  43.  
  44. }, error = function(err) {
  45.  
  46. # warning handler picks up where error was generated
  47. print(paste("MY_ERROR: ",err))
  48. b <- "changing 'b' inside the error handler has no effect"
  49. e <- myDivide(d,0.01) # =600
  50. f <- e + 100
  51. return(f)
  52.  
  53. }, finally = {
  54.  
  55. print(paste("a =",a))
  56. print(paste("b =",b))
  57. print(paste("c =",c))
  58. print(paste("d =",d))
  59. # NOTE: Finally is evaluated in the context of of the inital
  60. # NOTE: tryCatch block and 'e' will not exist if a warning
  61. # NOTE: or error occurred.
  62. #print(paste("e =",e))
  63.  
  64. }) # END tryCatch
  65.  
  66. print(paste("result =",result))

tryCatch示范

2)利用if语句以及stop语句。

即,如果某条件不成立,则停止程序,并输出stop里的内容。我这里主要用于检查原始product id是否输入正确。

  1. if (!sum(check)==length(productlink)) {
  2. productlink<-NULL
  3. productid<-NULL
  4. stop("invalid productid please double check if any space or else in, and resave the file or the script will not run")
  5. }

3)处理使用data.frame批量读取数据时,元素因为不存在导致的data.frame报错。

譬如说以下示例,因为a不存在,而导致data.frame报错。

  1. a<-NULL
  2. b<-c("cc","dd")
  3. data.frame(a,d)
  4. > Error in data.frame(a, d) : 参数值意味着不同的行数: 0, 2

因此,对于在循环里,需要先单独合成data.frame,再使用rbind把各个data.frame合成在一起时,可以考虑增加异常值的赋值。如下面两段,如果我拉的网页里不存在product name,则length(productname)==1为FALSE,直接输出“product not download or not existing”,那么这个字段就不是空值或者2-3个行,而是1行,之后合并为data.frame时就不会报错了。

  1. data<-function(n){
  2. ####隐掉获得productname/price/category的代码
  3. if(!length(productname)==1) {productname="Product not download or not existing"}
  4. if (!length(price)==1) {
  5. price=NA
  6. category<-"Product not download or not existing"
  7. }
  8. data.frame(productname,price,category)
  9. #这里合成data.frame,如果这三个行数不等(多为空值NULL,或者某个字段有2-3行所导致。
  10. #使用上面的IF判断赋值的好处是,最后出来的productname,price,category保证是1行,可以用data.frame合并。并且对异常值也有输出。

由于处理第2/3类错误时我还不了解tryCatch函数。目前看下来,貌似tryCatch函数能做的事情更多?

写下来供以后写代码时参考。

另外,tryCatch在java,C里均有类似功效。看来R归根到底,还是脱离不了底层语言啊。

接下来4月的学习计划,学完一个就写一篇博文~~整理思路记录笔记。

1)rCurl包,以及它那个厚厚的英文说明书。希望最后能学会用它爬一些rvest无法爬的脚本网页,以及搜索框网页等

2)用R做金融时间序列分析(炼数成金的班

3)跟着肖星老师重新复习财务分析知识(mooc课),在复习过去的财务知识后,再重新来看预测者网下的股票数据,尝试做一下挖掘与分析,至少从宏观上了解当前中国上市公司的布局与特点,为以后用R研究股票打打基础。

----------

我的博客: http://www.cnblogs.com/weibaar 记录学习R与数据分析的一切。

博客总目录:http://www.cnblogs.com/weibaar/p/4507801.html

R语言-处理异常值或报错的三个示例的更多相关文章

  1. R语言安装openxl包报错解决办法

    在R语言中使用openxlsx包,会报错 解决办法就是: 下载安装Set-Rtool,安装时注意勾选对话框 然后在R中运行以下代码: Sys.setenv("R_ZIPCMD" = ...

  2. R语言安装sqldb包报错解决办法

    我使用Rtudio环境,安装sqldb几次出错.网上没有好的教程. 经过自己试验之后,这样处理.我写出来以后,供大家参考. > install.packages("sqldf" ...

  3. zTree实现地市县三级级联报错(三)

    zTree实现地市县三级级联报错(三) 1.具体报错如下 usage: java org.apache.catalina.startup.Catalina [ -config {pathname} ] ...

  4. C语言扩展动态内存报错:realloc(): invalid next size: 0x0000000002365010 ***

    晚上被这个内存扩展崩溃的问题折腾的有点崩溃,当答案揭晓的那一刻,恍然大悟,原来如此简单. 练习题目:输入一个字符串,根据字母进行排序,说白了就是一个简单的冒泡 #include <stdio.h ...

  5. 【R笔记】glm函数报错原因及解析

    R语言glm函数学习:  [转载时请注明来源]:http://www.cnblogs.com/runner-ljt/ Ljt 作为一个初学者,水平有限,欢迎交流指正. glm函数介绍: glm(for ...

  6. servlet上传文件报错(三)

    1.具体报错如下 null null Exception in thread "http-apr-8686-exec-5" java.lang.OutOfMemoryError: ...

  7. 安装STS报错(三)

    安装STS报错 1.具体报错如下 Failure to transfer org.codehaus.plexus:plexus-archiver:jar:1.2 from http://repo.ma ...

  8. android r.styleable是什么或报错

    r.styleable 是自定义控件 自定义控件写好的后,需要在res-value-attrs.xml中定义,如: <declare-styleable name="SlidingMe ...

  9. EOS签名R值过大导致报错"is_canonical( c ): signature is not canonical"

    简要 EOS中规定签名的R和S必须同时小于N/2才是合法的签名. 详细 EOS签名交易相对BTC和ETH来说,对签名的要求更加严格了. BTC中bip62规定了((Low S values in si ...

随机推荐

  1. 更改计算机名称后 导致 sql server 2008 R2 用windows账户不能附加的错误解决办法

    出错背景:本人想用sql server 2008 R2 附加sql server 2005数据库出现拒绝访问,后查询网站得知,要用windows身份验证方式登录进去附加, 然后我就用windows身份 ...

  2. 洛谷P1288 取数游戏II[博弈论]

    题目描述 有一个取数的游戏.初始时,给出一个环,环上的每条边上都有一个非负整数.这些整数中至少有一个0.然后,将一枚硬币放在环上的一个节点上.两个玩家就是以这个放硬币的节点为起点开始这个游戏,两人轮流 ...

  3. SQL编程

    变量: 变量是一块内存空间的表示, 数组是一连串空间 如何定义一个变量 第一套变量定义  整型 Declare @num int Set @num=10 Print @num 第二套变量定义   字符 ...

  4. 第1章Java入门体验

    第1章Java入门体验 1.java简介和平台应用 Java是sun公司开发出来,现在属于ORACLE公司java分为几个部分:首先是最基础的Java SE部分,这部分是Java的基础知识,主要包括: ...

  5. 嵌入式Linux驱动学习之路(十八)LCD驱动

    驱动代码: /************************************************************************* > File Name: lcd ...

  6. SSH加固

    1.修改ssh默认端口 vi /etc/ssh/sshd_config  中Port:service ssh restart 2.安装denyhosts,应对暴力破解ssh. A.直接 apt-get ...

  7. JavaScript的客户端存储

    一.前言: 客户端存储实际上就是Web浏览器的记忆功能,通过浏览器的API实现数据存储到硬盘: 二.存储的不同形式: 1.Web存储:localStorage 和 sessionStorage 代表同 ...

  8. linux基础知识与技能2

    3.编辑器vi的使用(vi和vim的联系)什么是编辑器?编辑器就是一款软件,它的主要作用就是用来编辑.譬如编写文件,编写代码.Windows中的常用编辑器,如自带的notepad.比较好用的notep ...

  9. Java部署_IntelliJ创建一个可运行的jar包(实践)

    一.本文目的:使用Intellij Idea 13生成一个简单可执行的jar,用于快速在linux验证某个功能 二.项目源码 1.结构图  2.StaticC1.java 1 2 3 4 5 6 7 ...

  10. 解决:/bin/sh: 1: /home/**/custom_app.sh: Permission denied错误

    出现如下错误,一般是执行权限不够. /bin/sh: : /home/custom_app.sh: Permission denied 解决方法是:cd 到此文件目录,对提示的文件赋予可执行权限或读写 ...