2

I have a function that looks like

my_function <- function(object)
{
  # code goes here
}

I'd like the function (among other things) to print the name of the argument (as passed to the function). So if my function call is:

xxx <- my_function(my_object)

then I'd like to know how to get the function to print out the string "my_object".

Can anyone help please?

Alan
  • 619
  • 6
  • 19
  • 2
    I know of formalArgs, but formals apparently also works: https://stackoverflow.com/questions/40640322/get-the-argument-names-of-an-r-function – efz Aug 23 '20 at 17:14
  • Thank you for replying so quickly – Alan Aug 23 '20 at 17:44

3 Answers3

5

A more R-ish solution would be to use substitute (get substitute for obj) in combination with deparse (cast symbol to string):

my_function <- function(obj) {deparse(substitute(obj))}

General R metaprogramming rule: prefer substitute!

my_function(my_object)
## [1] "my_object"
Gwang-Jin Kim
  • 9,303
  • 17
  • 30
2

I would suggest next approach which is closer to what you want. For sure you could modify it to obtain other outputs:

#Function
my_function <- function(x)
{
  as.character(eval(parse(text=enquo(x)))[2])
}
#Apply
my_function(x = my_object)

Output:

[1] "my_object"

An improvement thanks to @MrFlick is next:

#Function
my_function <- function(x)
{
  rlang::as_label(rlang::enquo(x))
}
#Apply
my_function(x = my_object)

Which produces same output with a more elegant style in the function:

[1] "my_object"
Duck
  • 39,058
  • 13
  • 42
  • 84
  • @Alan Thanks to you!!! Great question! If you think this answer was helpful, you could accept it by clicking the tick on the left side of this answer :) – Duck Aug 23 '20 at 17:45
  • 1
    This is a very weird combination of rlang and base R. If you are going to use `rlang::enquo`, it would make more sense to use `rlang::as_label(enquo(x))` to get the name out. Otherwise the `deparse/substitute` is more idiomatic in base R. – MrFlick Aug 23 '20 at 22:37
  • @MrFlick I have added what you mentioned to the solution ! Thanks for your comment Dr. Flick! – Duck Aug 23 '20 at 22:48
1

To display the entire call use match.call like this:

f <- function(x) { print(match.call()); x }
f(pi)
## f(x = pi)
## [1] 3.141593

IF it is desired to display the call just for debugging without modifying the function itself then use trace:

g <- function(x) x  # test function

trace(g)
g(pi)
## trace: g(pi)
## [1] 3.141593
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341