在另一个函数内定义函数的优雅方式

时间:2015-11-16 13:56:17

标签: r

我想构建

f <- function(...) {
   g <- function(x) x ^ 2
   list(...)
}

这样我就可以使用f(g(4))调用并list(...)生成list(16)

一般情况下,我会在f中定义几个临时函数,用户在调用f(...)时可以调用它们。

我已经尝试了assignnewenvironment,但刚刚感到困惑。感谢您提供优雅的解决方案。

想要这个的原因是我希望Hmisc包中的函数drawPlot能够让用户指定一般命名的函数作为构建一系列图形元素的输入,我不想保留这些通用类型的名称。 E.g:

d <- drawPlot(Curve(), Points())   # interactively make a curve and
                                   # a set of points

3 个答案:

答案 0 :(得分:7)

我猜你实际上需要比这更精细的东西,但以下是你在提供的例子中所要求的:

>>> f = open("myfile.mp3", "rb")
>>> print(f.read(3))
b'ID3'

或者,如果用户可以提供一个或多个函数调用,请执行以下操作:

f <- function(...) {
   g <- function(x) x ^ 2
   list(eval(substitute(...)))
}

f(g(4))
# [[1]]
# [1] 16

答案 1 :(得分:3)

this answer非常相似,但我认为可能更具可扩展性,更接近您最初的想法:

match.fun_wrapper <- function(...) {
  #   `match.fun` searches in the parent environment of the environment that
  # calls `match.fun`, so this wrapper is a hack to be able to search in
  # the current environment rather than the parent of the current environemnt
  match.fun(...)
}

f <- function(fun, ...) {
  g <- function(x) x ^ 2
  fun <- match.fun_wrapper(substitute(fun))
  fun(...)
}

如果你想取消match.fun,你也可以取消包装黑客:

f <- function(fun, ...) {
  g <- function(x) x ^ 2
  fun(...)
}

答案 2 :(得分:0)

在我看来,你尝试做的事情是这样的:

f <- function(fun, ...) {
    g <- function(x) x ^ 2
    h <- function(x) x ^ 3
    i <- function(x) x ^ 4
    switch(fun,
           'g' = g(...),
           'h' = h(...),
           'i' = i(...))
}

> f('g', 3)
[1] 9
> f('h', 3)
[1] 27
> f('i', 3)
[1] 81

除非您只是尝试将具有相似名称的函数封装在不同的名称空间中并将其用作R不提供的事实的hacky解决方案,否则您不希望这样做的原因并不明显。功能齐全的课程。如果是这种情况,您也可以使用实际的命名空间,即将您的函数放入包中,以便package::g(arg)而不是f('g', arg)调用它们。