为何uniroot函数结合plot绘图时出现报错?
使用uniroot绘制函数时出现端点符号不匹配错误
我正在编写用uniroot函数近似方程根的代码,尝试绘制随自由变量变化时传入uniroot的函数行为:
library(Deriv) f1 <- function(s) { (1 - 2*s)^(-3/2)*exp((8*s)/(1-2*s)) } f2 <- function(s) { log(f1(s)) } f3 <- Deriv(f2, 's') f4 <- Deriv(f3, 's') f5 <- Deriv(f4, 's') upp_s <- 1/2 - 1e-20 f_est <- function(x) { f3a <- function(s) {f3(s = s) - x} s_ <- uniroot(f3a, lower = -9, upper = upp_s)$root return(s_) } plot(f_est, from = 0, to=100, col="red", main="header")
单独调用f_est函数时输出符合预期,但将其传入plot函数时,uniroot出现报错:
> plot(f_est, from = 0, to=100, col="red", main="header") Error in uniroot(f3a, lower = -9, upper = upp_s) : f() values at end points not of opposite sign In addition: Warning messages: 1: In if (is.na(f.lower)) stop("f.lower = f(lower) is NA") : the condition has length > 1 and only the first element will be used 2: In if (is.na(f.upper)) stop("f.upper = f(upper) is NA") : Error in uniroot(f3a, lower = -9, upper = upp_s) : f() values at end points not of opposite sign
我设置的函数确保uniroot指定的端点始终符号相反且仅有一个实根,单独运行f_est时端点无缺失值,尝试向量化相关函数也无效。请问这是为什么?
问题原因与解决办法
核心原因
plot函数在调用传入的函数时,会一次性传入一组向量值(而非单个标量)给f_est的参数x。此时f3a <- function(s) {f3(s) - x}中的x是向量,导致f3a(s)返回的是向量而非单值。而uniroot要求传入的函数必须是单值函数(输入单个s,输出单个数值),向量运算会让uniroot无法正确判断端点符号,进而报错。
解决办法
方法1:用Vectorize包装函数
给f_est添加向量化处理,让它能接受向量输入并逐个处理:
# 用Vectorize包装f_est,使其支持向量输入 f_est_vec <- Vectorize(f_est) # 调用plot时使用向量化后的函数 plot(f_est_vec, from = 0, to=100, col="red", main="header")
方法2:内部显式遍历处理
直接修改f_est内部,用sapply遍历每个x值单独调用uniroot:
f_est <- function(x) { sapply(x, function(x_single) { f3a <- function(s) {f3(s) - x_single} uniroot(f3a, lower = -9, upper = upp_s)$root }) } # 此时直接plot即可 plot(f_est, from = 0, to=100, col="red", main="header")
验证逻辑
单独调用f_est时,你传入的是单个标量x,所以f3a是单值函数,uniroot能正常工作。但plot默认会生成一组x值(比如从0到100的序列)一次性传给f_est,这就触发了向量运算的问题。上述两种方法都是让f_est对每个x值单独调用uniroot,确保f3a始终是单值函数。
内容的提问来源于stack exchange,提问作者Tim C
相关产品推荐
相关产品推荐

