在R包中动态创建函数

bok*_*kov 3 r package

我有一个动态生成的函数(出于在底层的扰流器块中解释的原因,如果你很好奇)我想要包含在一个包中.我希望这样做,只需要最小的性能损失,而不使用不受支持的功能.到目前为止,我想到这样做的方法是将生成函数的代码放入.onLoad()并将函数存储在其中options()或作为隐藏对象存储.GlobalEnv.显然存储函数.GlobalEnv是有风险的,因为它可能被无意中修改或删除.它也可能发生options(),不太可能发生意外.

options()以最佳方式存储生成的函数吗?

我有一个多变量函数,Fn用长而丑的衍生物来称呼它.我想在在给定的评价变量每个组合以创建一个返回函数的梯度(即,在各可变第一衍生物,在给定的X评价的矢量)的另一个功能和麻布(即二阶导数的矩阵X).为了使代码的维护,我只手的原代码Fn为未评估的表达,则让D(),eval()`body<-`()做的工作的其余部分.我最终得到一个动态生成的函数对象,它返回我想要的结果.


Adam Hyland的评论对这个具体问题有最简单的答案.如果您将其作为答案发布,则会被接受.但是,Richie Cotton的答案在一般情况下非常有用,所以也谢谢你.

Ric*_*ton 6

你可以尝试使用assignInNamespace内部.onLoad(未经测试),但就像Adam H在他的评论中所说的那样,听起来你正在以艰难的方式做事.

如果我正确地理解了这个问题,你有一个导数的表达式,你想要在给定点评估该表达式,并计算该点的梯度,并计算该点的粗糙度.只需创建一个函数,接受一个表达式和一个坐标的数值向量来评估,并让它吐出你想要的所有东西.像这样的东西:

#' Evaluate an expression, its derivative and its hessian
#' 
#' Evaluates an expression, its derivative and its hessian at a given point.
#' @param expr An expression of derivatives
#' @param x A named numeric vector of coords to evaluate \code{expr} at
#' @param name String giving the name of the variable to differentiate by
#' @return A list with the following values
#' \itemize{
#'   \item{value}{The value of \code{expr} evaluated at \code{x}.}
#'   \item{gradient}{The value of the derivative of \code{expr} evaluated at \code{x}.}
#'   \item{hessian}{The value of the hessian of \code{expr} evaluated at \code{x}.}
#' }
#' @examples
#' expr <- expression(sin(cos(x + y^2)))
#' x <- c(x = pi / 2, y = pi / 3)
#' eval_expr_and_calc_grad_and_hessian(expr, x, "x")
eval_expr_and_calc_grad_and_hessian <- function(expr, x, name = names(x)[1])
{
  x <- as.list(x)
  d_by_dname <- D(expr, name)
  d2_by_dname2 <- D(d_by_dname, name)
  list(
    value    = eval(expr, x),
    gradient = eval(d_by_dname, x),
    hessian  = eval(d2_by_dname2, x)
  )
}
Run Code Online (Sandbox Code Playgroud)

  • 需要注意的一点是 - 您无法使用此机制将包提交给CRAN.请参阅`?assignInNamespace`中的警告和注释.`assignInMyNamespace`可能更容易接受,但仍然读取警告. (4认同)