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

R语言中如何在函数内绘制二元函数及其导数图像?遇函数识别报错

解决R语言二元函数求导后绘图的问题

错误原因

你的代码报错核心问题是:D()函数返回的是表达式(比如对x*y^2求y的一阶导数会得到x * (2 * y)),而outer()函数要求第三个参数是可调用的函数,不是表达式。所以R会尝试寻找名为der的函数,自然找不到,抛出错误。

另外原代码还有两个潜在问题:

  • 参数名x和内部生成的变量x重名,容易引发作用域混淆
  • 递归逻辑中直接传递表达式给函数,处理起来容易出错

修正后的代码

DD7 <- function(expr, var, contador = 1) {
  # 检查导数阶数是否合法
  if (contador < 1) {
    stop("Grau de derivada menor que 1")
  }
  
  # 循环求导,得到最终的导数表达式
  current_expr <- substitute(expr)
  for (i in 1:contador) {
    current_expr <- D(current_expr, var)
  }
  
  # 打印导数表达式
  print(current_expr)
  
  # 将表达式转换为可矢量化的二元函数
  deriv_fun <- Vectorize(function(x, y) {
    eval(current_expr, list(x = x, y = y))
  })
  
  # 生成绘图数据
  x_vals <- y_vals <- seq(-3, 3, length = 50)
  z_vals <- outer(x_vals, y_vals, deriv_fun)
  
  # 绘制3D图
  persp(x_vals, y_vals, z_vals, main = paste(contador, "阶导数图像", sep = ""))
  
  # 返回导数函数,方便后续调用
  return(deriv_fun)
}

# 测试1阶导数
DD7(x*y^2, "y", 1)
# 测试2阶导数
DD7(x*y^2, "y", 2)

关键修正点

  1. 表达式转函数:用eval()配合list(x=x, y=y)把导数表达式转换成可执行的函数,再用Vectorize()处理矢量化,适配outer()的逐元素运算需求。
  2. 避免变量名冲突:把原函数的第一个参数从x改成expr,内部绘图变量用x_vals/y_vals,彻底避免作用域混淆。
  3. 简化求导逻辑:把递归改成循环求导,更直观易读,也避免递归调用时的表达式传递问题。

内容的提问来源于stack exchange,提问作者Matheus Nunes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 06:27:28