You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R中绘制不可导函数时出现异常行为的原因咨询

分段线性函数R绘图报错问题解决

问题重现

先创建数据与分段函数:

v1 <- c(3.323,4.0034,4.6584,5.2826)
v2 <- c(1200,1300,1400,1500)
data <- cbind(v1, v2)

fun <- function(x){
  ans <- NA
  ans[x >= data[1,1] & x <= data[2,1]] <- 100*(x-data[1,1])/(data[2,1]-data[1,1])+data[1,2]
  ans[x >= data[2,1] & x <= data[3,1]] <- 100*(x-data[2,1])/(data[3,1]-data[2,1])+data[2,2]
  ans[x >= data[3,1] & x <= data[4,1]] <- 100*(x-data[3,1])/(data[4,1]-data[3,1])+data[3,2]
  ans
}

单点求值结果符合预期:

> fun(4.3309)
[1] 1350
> fun(4.0034)
[1] 1300

但执行绘图代码时出现警告,且结果不符:

plot(fun, type = 'l', xlim = c(3.323,5.2826))

警告信息:

1: In ans[x >= data[1, 1] & x <= data[2, 1]] <- 100 * (x - data[1, :
number of items to replace is not a multiple of replacement length
2: In ans[x >= data[2, 1] & x <= data[3, 1]] <- 100 * (x - data[2, :
number of items to replace is not a multiple of replacement length
3: In ans[x >= data[3, 1] & x <= data[4, 1]] <- 100 * (x - data[3, :
number of items to replace is not a multiple of replacement length

问题原因

plot函数调用自定义函数时,会自动传入一组向量值(而非单个数值)来生成绘图点。原函数中ans初始化为单个NA,当x是向量时,赋值操作的左右两边长度不匹配,导致警告和错误的计算结果。

解决方案

修改函数使其支持向量输入,初始化ans为与输入x长度一致的向量,再按区间赋值:

fun <- function(x){
  # 初始化与x同长度的向量
  ans <- numeric(length(x))
  # 第一段区间赋值
  idx1 <- x >= data[1,1] & x <= data[2,1]
  ans[idx1] <- 100*(x[idx1]-data[1,1])/(data[2,1]-data[1,1])+data[1,2]
  # 第二段区间赋值
  idx2 <- x >= data[2,1] & x <= data[3,1]
  ans[idx2] <- 100*(x[idx2]-data[2,1])/(data[3,1]-data[2,1])+data[2,2]
  # 第三段区间赋值
  idx3 <- x >= data[3,1] & x <= data[4,1]
  ans[idx3] <- 100*(x[idx3]-data[3,1])/(data[4,1]-data[3,1])+data[3,2]
  # 超出区间的设为NA
  ans[!(idx1 | idx2 | idx3)] <- NA
  ans
}

也可以用ifelse实现更简洁的向量化逻辑:

fun <- function(x){
  ifelse(x >= data[1,1] & x <= data[2,1],
         100*(x-data[1,1])/(data[2,1]-data[1,1])+data[1,2],
         ifelse(x >= data[2,1] & x <= data[3,1],
                100*(x-data[2,1])/(data[3,1]-data[2,1])+data[2,2],
                ifelse(x >= data[3,1] & x <= data[4,1],
                       100*(x-data[3,1])/(data[4,1]-data[3,1])+data[3,2],
                       NA)))
}

修改后再执行plot(fun, type='l', xlim=c(3.323,5.2826)),无警告且绘图结果与单点求值一致。

内容的提问来源于stack exchange,提问作者Edward Erisman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 05:13:11