6

考虑这个函数a(),它打印出传入的参数:

a <- function(x) {
  message("The input is ", deparse(substitute(x)))
}

a("foo")
# The input is "foo"

tmplist <- list(x1 = 1, x2=2)
a(tmplist)
# The input is tmplist

这样可行。但是当a()从另一个函数调用时,它不再打印出原始参数名称:

b <- function(y) {
  a(y)
}

b("foo")
# The input is y

b(tmplist)
# The input is y

一种似乎可行的解决方案是包装另一个substitute和一个eval

a1 <- function(x) {
  message("The input is ", deparse(eval(substitute(substitute(x)), parent.frame())))
}

a1("foo")
# The input is "foo"

tmplist <- list(x1 = 1, x2=2)
a1(tmplist)
# The input is tmplist

b1 <- function(y) {
  a1(y)
}

b1("foo")
# The input is "foo"

b1(tmplist)
# The input is tmplist

但这似乎不优雅。如果我添加另一层,它会失败:

c1 <- function(z) {
  b1(z)
}
c1("foo")
# The input is z

有没有一种好的、通用的方法来获得原始论点?

4

4 回答 4

3

我不确定这在所有情况下都能正常工作,但试试这个:

f0 <- function(x) {
  nn <- substitute(x)
  i <- 1
  while(TRUE) {
    on <- do.call("substitute", list(as.name(nn), parent.frame(i)))
    if (on == nn) break;
    nn <- on
    i <- i + 1
  }
  message("The input is ", nn)
}

f1 <-function(.f1) f0(.f1)
f2 <- function(.f2) f1(.f2)

接着,

> f2(foo)
The input is foo
> f1(poo)
The input is poo
> f0(moo)
The input is moo
> f2(";(")
The input is ;(
> f1(":)")
The input is :)
> f0(":p")
The input is :p
于 2012-06-05T07:37:42.983 回答
3

改编 kohske 的答案,这是可行的,但如果变量在两个连续的帧中具有相同的名称,则不会过早停止向上帧堆栈。我不知道它是否在所有情况下都能正常工作,但它似乎可以满足我的需求。字符串与变量的引用与以前略有不同,但这对我来说是可以的。

a <- function(x) {
  newname <- substitute(x)

  # Travel up the frame stack until we hit the top.
  for(i in seq_len(sys.nframe())) {
    oldname <- do.call("substitute", list(as.name(newname), parent.frame(i)))
    newname <- oldname
  }
  message("The input is ", deparse(newname))
}

b <- function(y)  a(y)

c <- function(z)  b(z)

a("adsf")
# The input is adsf
a(foo)
# The input is foo

b("adsf")
# The input is adsf
b(foo)
# The input is foo

c("adsf")
# The input is adsf
c(foo)
# The input is foo
于 2012-06-08T18:09:47.990 回答
1

虽然这本身就是一个有趣的问题,但我想知道最好的解决方案是否只是将变量名作为字符传递,即在引号中。那么这些都不是必需的。如果需要与名称对应的对象,则可以使用getoras.namedo.call获取它,具体取决于您在函数中如何使用它。

> f0 <- function(x) {message("The input is ", x)}
> f1 <- function(.f1) f0(.f1)
> f2 <- function(.f2) f1(.f2)
> f2("aa")
The input is aa
> f1("bb")
The input is bb
> f0("cc")
The input is cc
于 2012-06-05T11:47:07.327 回答
0

什么时候递归调用你的函数怎么样

deparse(substitute(x))!=deparse(eval(substitute(substitute(x)), parent.frame())
于 2012-06-05T07:38:34.483 回答