Deparse (substitute ()) returns the function name normally, but the function code when called inside a loop

I am a little surprised by the behavior of R in a very specific case. Let's say I define a square function that returns the square of its argument, for example:

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

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

 ds1 <- function(x) { print(deparse(substitute(x))) } ds1(square) # [1] "square" 

This is the expected result, so everything is in order. However, if I pass a function wrapped in a list and process it with a for loop, the following will happen:

 ds2 <- function(x) { for (y in x) { print(deparse(substitute(y))) } } ds2(c(square)) # [1] "function (x) " "{" " return(x^2)" "}" 

Can someone explain to me why this is happening and how I could prevent this?

+7
r
source share
1 answer

As soon as you use x inside your function, it is evaluated, so it "ceases to be an expression (unevaluated)" and "starts to be its resulting values ​​(calculated expression)". To prevent this, you should grab x at substitute before using it for the first time.

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

 x <- substitute(x) 

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

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" 
+7
source share

All Articles