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

R中如何向量化'deparse(substitute(d))'?传入c(dnorm,dcauchy)为何报错?

解答你的R函数问题:向量化处理与报错原因分析

咱们先解决你提到的报错问题,再聊向量化处理的方案,这样逻辑更顺~

问题2:为什么bb(d = c(dnorm, dcauchy))会报“object not found”?

你写的bb函数里,当传入的参数不是字符型时,会用deparse(substitute(d))把传入的表达式转成字符串。这里的关键是:substitute(d)会捕获你传入的整个调用表达式。

当你调用bb(d = c(dnorm, dcauchy))时,substitute(d)拿到的是c(dnorm, dcauchy)这个完整的调用,deparse()把它转成了字符串"c(dnorm, dcauchy)"。接下来循环里的get(d[i])就会尝试找一个叫c(dnorm, dcauchy)的对象——但这个对象根本不存在,R自然就报错了。

而你说的几个能正常运行的情况,原因很清晰:

  • bb(d = dnorm):substitute(d)拿到的是dnorm,转成字符串后get("dnorm")能正确获取正态密度函数;
  • bb(d = c("dnorm", "dcauchy")):传入的是字符向量,函数直接用每个字符串去get对应的函数,完全没问题;
  • 至于你提到的bb(d = c(dnorm))能正常执行,这大概率是个小疏漏——正常情况下get("c(dnorm)")会找不到对象,可能你实际测试的是c("dnorm")?😉

问题1:如何向量化处理deparse(substitute(d))?

要处理c(dnorm, dcauchy)这种函数向量的传入,我们不能再把整个c(...)表达式转成字符串,而是要拆解它,提取每个函数的名字,或者更直接地——直接处理函数对象本身,跳过转字符串再get的步骤。

方案1:拆解c(...)调用表达式(不依赖额外包)

修改函数逻辑,判断传入的是否是c()调用,然后提取里面的每个函数名:

bb <- function(d){
  # 处理c(函数1, 函数2)这种调用
  d_call <- substitute(d)
  if(is.call(d_call) && as.character(d_call)[1] == "c"){
    d <- sapply(as.list(d_call)[-1], deparse)
  } else if(!is.character(d)){
    # 单个函数的情况
    d <- deparse(d_call)
  }
  
  h <- numeric(length(d))
  for(i in seq_along(d)){
    h[i] <- get(d[i])(1)
  }
  h
}

现在调用bb(d = c(dnorm, dcauchy))就能正常返回两个函数在1处的取值了。

方案2:直接处理函数对象(更推荐)

其实我们完全可以跳过deparse和get的步骤,直接对传入的函数对象操作,这样逻辑更直观,也不容易出错:

bb <- function(d){
  if(is.function(d)){
    # 单个函数的情况
    h <- d(1)
  } else if(is.list(d) && all(sapply(d, is.function))){
    # 函数列表/向量的情况
    h <- sapply(d, function(func) func(1))
  } else if(is.character(d)){
    # 字符向量的情况
    h <- sapply(d, function(nm) get(nm)(1))
  } else {
    # 处理符号引用(比如直接传函数名的情况)
    d_name <- deparse(substitute(d))
    h <- get(d_name)(1)
  }
  h
}

这个版本的函数兼容所有你提到的调用方式:

  • bb(d = dnorm) → 返回dnorm(1)的结果
  • bb(d = c(dnorm, dcauchy)) → 返回两个函数在1处的取值向量
  • bb(d = c("dnorm", "dcauchy")) → 同样返回正确结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:49:23