R - 在嵌套函数中使用替换

cst*_*sta 3 r substitution

我有一个函数可能最终被嵌套(Inner)和我正在调用的一些其他函数(通常这个函数将不知道),Outer我希望Inner能够产生相同的结果,无论包装函数如何(Outer在下面的例子中).

Inner <- function(x,baz,bang){
  # code stuff things ...
  x.prime = as.character(substitute(x))
  return(c(x.prime,y,z))
}

Outer <- function(y){
  Inner(y)
}
Inner(a)
# "a" "stuff" "things" , which is what I'm expecting, in particular the "a".
Outer(a)
# "y" .... , but I was expecting to get "a"?
Run Code Online (Sandbox Code Playgroud)

当然,如果有人知道更好的方法,我就不会使用替代品.

有没有人有任何线索如何让Inner输出相同的结果,无论它是否嵌套?

提前致谢.

Bro*_*ieG 7

以下是一个可以帮助您解决问题的大纲:

Inner <- function(x) {
  my.call <- quote(substitute(x))    # we quote this here because we are going to re-use this expression
  var.name <- eval(my.call)

  for(i in rev(head(sys.frames(), -1L))) { # First frame doesn't matter since we already substituted for first level, reverse since sys.frames is in order of evaluation, and we want to go in reverse order
    my.call[[2]] <- var.name         # this is where we re-use it, modified to replace the variable
    var.name <- eval(my.call, i)
  }
  return(var.name)
}
Outer <- function(y) Inner(y)
Outer2 <- function(z) Outer(z)
Run Code Online (Sandbox Code Playgroud)

现在让我们运行这些功能:

Inner(1 + 1)
# 1 + 1
Outer(2 + 2)
# 2 + 2
Outer2(3 + 3)
# 3 + 3
Run Code Online (Sandbox Code Playgroud)

Inner总是返回最外面的表达式(你没有看到y或者z只看到输入的表达式.GlobalEnv.

这里的诀窍是sys.frames()反复使用,substitute直到我们达到顶级水平.

请注意,这假设所有"外部"函数只是将其参数转发到下一个内部函数.如果你有类似的东西,事情可能变得更加复杂/不可能:

Outer <- function(y) Inner(y + 1)
Run Code Online (Sandbox Code Playgroud)

此代码不会检查该类型的问题,但您可能应该在代码中.另外,请记住,此处的假设是您的函数只能从R命令行调用.如果有人将你的功能包裹在你的周围,你可能会得到意想不到的结果.