Using tryCatch in the integral and mapply

2019-09-17 21:12发布

I have the date (test):

test<-structure(list(X = c(630L, 631L, 977L, 978L), si = c(1.063166618, 
1.063166618, 1.063166618, 1.063166618), ho = c(-0.071587466, 
-0.071587466, -0.071587466, -0.071587466), bd = c(0.998351574, 
0.999361098, 0.999978304, 0.944579005), i1 = c(0.997434318, 0.997434318, 
0.997434318, 0.997434318), x1b1m = c(2.938615084, 3.220915079, 
4.088527679, 1.818297207), x1b1e = c(3.561241746, 3.843541741, 
4.711154342, 1.594420075), x1b0m = c(2.714737952, 2.997037947, 
3.864650548, 1.594420075), x1b0e = c(2.938615084, 3.220915079, 
4.088527679, 0.971793413), x2b1m = c(7.432558537, 8.66190052, 
8.643460274, 6.17045182), x2b1e = c(8.055185199, 9.284527183, 
9.266086936, 5.946574688), x2b0m = c(7.208681405, 8.438023388, 
8.419583142, 5.946574688), x2b0e = c(7.432558537, 8.66190052, 
8.643460274, 5.323948026)), .Names = c("X", "si", "ho", "bd", 
"i1", "x1b1m", "x1b1e", "x1b0m", "x1b0e", "x2b1m", "x2b1e", "x2b0m", 
"x2b0e"), class = "data.frame", row.names = c(NA, -4L))

test<-
 X       si          ho        bd        i1    x1b1m    x1b1e    x1b0m     x1b0e    x2b1m    x2b1e    x2b0m    x2b0e
1 630 1.063167 -0.07158747 0.9983516 0.9974343 2.938615 3.561242 2.714738 2.9386151 7.432559 8.055185 7.208681 7.432559
2 631 1.063167 -0.07158747 0.9993611 0.9974343 3.220915 3.843542 2.997038 3.2209151 8.661901 9.284527 8.438023 8.661901
3 977 1.063167 -0.07158747 0.9999783 0.9974343 4.088528 4.711154 3.864651 4.0885277 8.643460 9.266087 8.419583 8.643460
4 978 1.063167 -0.07158747 0.9445790 0.9974343 1.818297 1.594420 1.594420 0.9717934 6.170452 5.946575 5.946575 5.323948

I am trying to find the integral using the following code. I want the code to return NA if error occurs, otherwise the integral value. For the row 1 and 4, it returns the value but for the row 2 and 3, it returns an error. Unfortunately, I have no success using tryCatch.

funint<- function(a,b,si,ho,bd,i1){
integrate(function(x){(1/bd)*(1/si)*dnorm((log(x)-b)/si)*pnorm(a+((ho/si)*(log(x)-b))/i1)},0,Inf)$value}



rowno<-as.list(rownames(test))
var<-c("b","e")
x1b1<-as.list(c("x1b1m","x1b1e"))
x1b0<-as.list(c("x1b0m","x1b0e"))
x2b1<-as.list(c("x2b1m","x2b1e"))
x2b0<-as.list(c("x2b0m","x2b0e"))

In the following code, for each i (row number), the integral function (funint) uses the values from columns x1b1 and x2b1 or x1b0 and x2b0 plus other four variables: si,ho,bd,and i1.

 kk<-data.frame(
tryCatch(
mapply(
function(j1b1,j2b1,j1b0,j2b0){
(sapply(rowno,
function(i){
funint(test[i,j1b1],test[i,j2b1],test[i,"si"],test[i,"ho"],test[i,"bd"],test[i,"i1"])-
                     funint(test[i,j1b0],test[i,j2b0],test[i,"si"],test[i,"ho"],test[i,"bd"],
    test[i,"i1"])}))
},x1b1,x2b1,x1b0,x2b0),error=function(e) print("hello")))
                           test[i,"i1"])
}))},x1b1,x2b1,x1b0,x2b0))
names(kk)<-paste0("var")

Expected output:

kk

 b        e
1 601.2711 2578.3789
2 NA        NA
3 NA         NA
2 188.4013  354.9656

Any help in this regard will be highly appreciated.

Note: The code works. My only problem is how to skip the error (by returning NA when error occurs) and keep the code working for other rows.

1条回答
太酷不给撩
2楼-- · 2019-09-17 21:21

I think you just need to move the tryCatch farther inside the loop so that it catches exactly where the error is happening.

foo <- mapply(function(j1b1, j2b1, j1b0, j2b0) {
  sapply(rowno, function(i) {
    tryCatch({
      funint(test[i,j1b1], test[i,j2b1], test[i,"si"], 
             test[i,"ho"], test[i,"bd"], test[i,"i1"]) -
      funint(test[i,j1b0], test[i,j2b0], test[i,"si"], 
             test[i,"ho"], test[i,"bd"], test[i,"i1"])
    }, error=function(e) NA)
  })
}, x1b1, x2b1, x1b0, x2b0)
kk <- data.frame(foo)
names(kk) <- var
kk

##           b         e
## 1  601.2711 2578.3789
## 2 2046.8451        NA
## 3 2002.7819        NA
## 4  188.4013  354.9656
查看更多
登录 后发表回答