如何避免uniroot报错中断循环,报错时赋值NA继续执行
解决方案
你可以通过R内置的异常处理函数tryCatch()捕获uniroot的运行错误,报错时自动赋值为NA且不中断后续循环,修改后的完整代码如下:
# 定义求解函数 func <- function(f) -a*b/c*0.5*d*e^2 + (d/f-1)*g*sin(h*(pi/180))-i dat <- data.frame(a = c(0.99,0.99,0.99), b = c(0.1986572,0.1986572,0.1986572), c = c(237.5,237.5,237.5), d = c(1028.372, 1028.711, 1028.372), e = c(2.46261, 2.986461, 2.46261), f = c(-1,-1,-1), g = c(9.8,9.8,9.8), h = c(-54.97964, -51.65978, -54.97964), i = c(0.03699588, -0.0375189, 0.03699588)) for(j in 1:nrow(dat)){ a <- dat$a[j] b <- dat$b[j] c <- dat$c[j] d <- dat$d[j] e <- dat$e[j] g <- dat$g[j] h <- dat$h[j] i <- dat$i[j] # 捕获uniroot异常 sol <- tryCatch( expr = uniroot(func, c(0, 2000), extendInt = "yes"), error = function(err) list(root = NA) ) dat$f[j] <- sol$root print(j) }
运行结果
执行后查看dat$f输出符合预期:
> dat$f [1] 1526.566 NA 1526.566
优化建议
你也可以修改函数定义,把依赖的参数直接作为形参传入,避免依赖全局变量导致的意料外错误,修改方式如下:
# 显式传入所有参数 func <- function(f, a, b, c, d, e, g, h, i) { -a*b/c*0.5*d*e^2 + (d/f-1)*g*sin(h*(pi/180)) - i } # 调用uniroot时传入参数 sol <- tryCatch( expr = uniroot(func, c(0, 2000), extendInt = "yes", a = a, b = b, c = c, d = d, e = e, g = g, h = h, i = i), error = function(err) list(root = NA) )
内容的提问来源于stack exchange,提问作者imtaiky
相关产品推荐
相关产品推荐

