deparse(substitute()) returns function name normally, but function code when called inside for loop

你。 提交于 2021-01-26 20:38:52

问题


I'm a bit surprised by R's behaviour in a very specific case. Let's say I define a function square that returns the square of its argument, like this:

square <- function(x) { return(x^2) }

I want to call this function within another function, and I also want to display its name when I do that. I can do that using deparse(substitute()). However, consider the following examples:

ds1 <- function(x) {
  print(deparse(substitute(x)))
}

ds1(square)
# [1] "square"

This is the expected output, so all is fine. However, if I pass the function wrapped in a list and process it using a for loop, the following happens:

ds2 <- function(x) {
  for (y in x) {
    print(deparse(substitute(y)))
  }
}

ds2(c(square))
# [1] "function (x) "   "{"               "    return(x^2)" "}"  

Can anybody explain to me why this occurs and how I could prevent it from happening?


回答1:


As soon as you use x inside your function, it is evaluated, so it "stops being an (unevaluated) expression" and "starts being its resulting values (evaluated expression)". To prevent this, you must capture x by substitute before you use it for the first time.

The result of substitute is an object which you can query as if it was a list. So you can use

x <- substitute(x)

and then x[[1]] (the function name) and x[[2]] and following (the arguments of the function)

So this works:

ds2 <- function(x) {
    x <- substitute(x)
    # you can do `x[[1]]` but you can't use the expression object x in a
    # for loop. So you have to turn it into a list first
    for (y in as.list(x)[-1]) {
        print(deparse(y))
    }
}
ds2(c(square,sum))
## [1] "square"
## [1] "sum"


来源:https://stackoverflow.com/questions/47904321/deparsesubstitute-returns-function-name-normally-but-function-code-when-cal

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!