我在理解如何使用嵌套函数调用和参数求值时遇到麻烦。

这是一个简单的例子。我有一个带有一个数字参数的顶级函数topfunction。在topfunction内部,我调用了另一个函数lowerfunction,该参数是对lowerfunction内部定义的函数的调用。

topfunction<-function(x){
  lowerfunction(myfun(first=x[1],second=x[2],third=if(length(x)>2) x[3]))
}

lowerfunction<-function(mycall){

  myfun<-function(first,second=0,third=NULL){
    print(first)
    print(second)
    print(third)
  }

  mc<-match.call(definition = myfun, call = match.call()[[2]])
  eval(mc)
}

lowerfunction内部,我使用match.call捕获了函数调用,并尝试评估该调用。但是由于变量x仅在topfunction的环境中定义,因此评估失败:
topfunction(x=1:3)
Error in print(first) : object 'x' not found

我知道我可以换线
lowerfunction(myfun(first=x[1],second=x[2],third=if(length(x)>2) x[3]))

作为
lowerfunction(substitute(myfun(first=x[1],second=x[2],third=if(length(x)>2) x[3])))

topfunction中,但是在我的实际应用程序中,topfunction由用户构造,因此解决方案应该以某种方式在lowerfunction甚至在myfun级别中发生。但是由于他们已经丢失了有关x的信息,所以我不知道是否可以实现?

在实际应用中,topfunction使用lowerfunction构造模型并计算其可能性,而lowerfunction的参数是一个可以包含函数调用的公式,该公式将通过eval进行评估。这些函数仅在lowerfunction中定义。另外,lowerfunction也可以直接调用,即
x<-1:3
lowerfunction(myfun(first=x[1],second=x[2],third=if(length(x)>2) x[3]))
# or
lowerfunction(myfun(first=x1,second=2)

因此,将x添加到lowerfunction的参数列表的解决方案通常不适用。

因此,问题在于eval应该从一个环境(包 namespace ,或者在这种情况下,从myfun环境)获取lowerfunction的定义,并在其他环境(即myfun环境)中评估topfunction的参数。

最佳答案

这是一个相对简单的问题,但是由于您进行的是非常不标准的评估,因此需要创建一个新的environment,并且所有这些操作都确保您可以从该环境访问所需的所有对象。

g <- function(x){
  f1(f2(x[1], x[2], if(length(x) > 2) x[3]))
}

f1 <- function(mycall, parent = parent.frame()) {
  # Parent contains x
  # New environment that contains f2 and inherits from the parent
  env <- new.env(parent = parent)
  env$f2 <- function(first, second = 0,third = NULL) {
    print(first)
    print(second)
    print(third)
  }

  # More idiomatic way of getting unevaluated expression
  expr <- substitute(mycall)
  eval(expr, env)
}

g(1:3)

我在有关domain specific languages的章节中描述了类似的技术

09-06 07:26