R语言-处理异常值或报错的三个示例

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来获取网页打不开时的错误信息。并且要求执行下一步循环“”。

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

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

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

result = tryCatch(
        {expr},
        warning = function(w) {warning-handler-code},
        error = function(e) { error-handler-code},
        finally = {cleanup-code}
        )

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

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

[1] "ccc"
[1] TRUE

tryCatch({a<-"c"

         cc==a}, #cc不存在
        error=function(e){cat("hahaha",conditionMessage(e),"\n\n")},
        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回答的问题里,我们看到了更为有趣的一个应用。

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

#!/usr/bin/env Rscript
# tryCatch.r -- 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) {

  # warning 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))

tryCatch示范

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

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

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

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

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

a<-NULL
b<-c("cc","dd")
data.frame(a,d)
> 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时就不会报错了。

data<-function(n){
        ####隐掉获得productname/price/category的代码
        if(!length(productname)==1) {productname="Product not download or not existing"}
        if (!length(price)==1) {
                        price=NA
                        category<-"Product not download or not existing"
        }
        data.frame(productname,price,category)
        #这里合成data.frame,如果这三个行数不等(多为空值NULL,或者某个字段有2-3行所导致。
        #使用上面的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与数据分析的一切。

时间: 2025-01-17 04:20:56

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

插入图片后R文件变红,报错“Error::app:mergeDebugResources&#39;. &gt; Some file crunching failed, see logs for detail”

本想做一个有爱的小东西,插入图片后发现原本之前运行成功的程序, 出现了报错“:app:mergeDebugResources'. > Some file crunching failed, see logs for detail” 一脸懵逼~~~这是什么鬼,在别人的回答和博客里找找解决办法. 不过对我好像不管用,找了好久才发现是图片的问题. 之前只是简单的在重命名的时候把图片改成“xx.png”,放在了app/src/main/res/drawable文件夹里(ps:目前每次我都是在复制图片再粘

android studio中R文件变红并报错

昨天晚上碰到一个十分费解的问题,想分享一下,希望能帮到你. 以前用studio是R文件是不报错的.当你从其他程序拷过一些代码是会发现R文件会变红并且应用程序不能运行.除了R文件其他地方没有报错,只有app运行时会报错 . 这是因为当你从其他程序拷过一些代码.你的r文件中没有自动加载,这时你需要把那些报错的代码删除并重新在android studio中输入,这样你的应用程序就可以运行了.

安装STS报错(三)

this指针只能在一个类的成员函数中调用,它表示当前对象的地址.下面是一个例子: void Date::setMonth( int mn ) { month = mn; // 这三句是等价的 this->month = mn; (*this).month = mn; } 1. this只能在成员函数中使用. 全局函数,静态函数都不能使用this. 实际上,成员函数默认第一个参数为T* const register this. 如: class A{public: int func(int p){

WebService之CXF注解报错(三)

如果你对项目管理.系统架构有兴趣,请加微信订阅号"softjg",加入这个PM.架构师的大家庭 要成为WEB架构师,首先要找到通往成功的正确方向,接下来我们就要往这个方向努力.然而如唐僧去西天取经一样,要历经种种磨难,一路上打败各种妖魔鬼怪才能继续前行,所以唐僧取经,第一件事,就是招徒弟,遇见妖魔鬼怪就让技术高超的徒弟打败它,徒弟不听话就念紧箍咒,徒弟也搞不定的妖怪,就请观音菩萨搞定,这就是唐僧成功的法宝,没法宝上路,看来我们会死的比较惨啊,哈哈. 我们在通往架构师的路上,同样会遇到各

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

zTree实现地市县三级级联报错(三) 1.详细报错例如以下 usage: java org.apache.catalina.startup.Catalina [ -config {pathname} ] [ -nonaming ] { -help | start | stop } 2014-5-11 22:37:22 org.apache.catalina.core.AprLifecycleListener init 信息: Loaded APR based Apache Tomcat Nat

freemarker自定义标签报错(三)

freemarker自定义标签 1.错误描述 freemarker.core.ParseException: Encountered " " at line 14, column 12 in myself.ftl. Was expecting one of: <STRING_LITERAL> ... <RAW_STRING> ... "false" ... "true" ... <INTEGER> ... &l

Struts2实现文件上传报错(三)

1.具体错误如下 usage: java org.apache.catalina.startup.Catalina [ -config {pathname} ] [ -nonaming ] { -help | start | stop } 2014-5-1 23:17:23 org.apache.catalina.core.AprLifecycleListener init 信息: Loaded APR based Apache Tomcat Native library 1.1.27 usin

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

R语言glm函数学习:  [转载时请注明来源]:http://www.cnblogs.com/runner-ljt/ Ljt 作为一个初学者,水平有限,欢迎交流指正. glm函数介绍: glm(formula, family=family.generator, data,control = list(...)) family:每一种响应分布(指数分布族)允许各种关联函数将均值和线性预测器关联起来. 常用的family: binomal(link='logit')         ----响应变量

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

晚上被这个内存扩展崩溃的问题折腾的有点崩溃,当答案揭晓的那一刻,恍然大悟,原来如此简单. 练习题目:输入一个字符串,根据字母进行排序,说白了就是一个简单的冒泡 #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> #define BUF_LEN 100 #define COUNT 5 int main(void) { char buf[BUF_LEN];