问题
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