Determine function name within that function

as.character(match.call()[[1]])

Demo:

my_fun <- function(){
  as.character(match.call()[[1]])
}
my_fun()
# [1] "my_fun"
foo_bar <- function(){
  as.character(match.call()[[1]])
}
foo_bar()
# [1] "foo_bar"
ballyhoo <- function(){
  foo_bar()
}
ballyhoo()
# [1] "foo_bar"
tom_foolery <- foo_bar
tom_foolery()
# [1] "tom_foolery"

Try sys.call(0) if a call object output is ok or deparse that if you just want the name as a character string. Below are a couple of tests of this. sys.call returns both the name and the arguments and the [[1]] picks out just the name.

my_fun <- function() deparse(sys.call(0)[[1]])

g <- function() my_fun()

my_fun()
## [1] "my_fun"

g()
## [1] "my_fun"

Function names

Note that functions don't actually have names. What we regard as function names are actually just variables that hold the function and are not part of the function itself. A function consists of arguments, body and an environment -- there is no function name among those constituents.

Anonymous functions

Furthermore one can have anonymous functions and these might return strange results when used with the above.

sapply(1:3, function(x) deparse(sys.call(0)[[1]]))
## [1] "FUN" "FUN" "FUN"

Edge cases

There do exist some situations, particularly involving anonymous functions, where deparse will return more than one element so if you want to cover such edge cases use the nlines = 1 argument to deparse or use deparse(...)[[1]] or as mentioned by @Konrad Rudolph by using deparse1 in R 4.0.0.

Map(function(x) deparse(sys.call(0)[[1]], nlines = 1), 1:2)
## [[1]]
## [1] "function (x) "
## 
## [[2]]
## [1] "function (x) "

Map(function(x) deparse(sys.call(0)[[1]]), 1:2)  # without nlines=1
## [[1]]
## [1] "function (x) "             "deparse(sys.call(0)[[1]])"
##
## [[2]]
## [1] "function (x) "             "deparse(sys.call(0)[[1]])"

Other

Recall. If the reason you want the function name is to recursively call the function then use Recall() instead. From the help file:

fib <- function(n)
   if(n<=2) { if(n>=0) 1 else 0 } else Recall(n-1) + Recall(n-2)
fib(4)
## [1] 3

warning and stop These both issue the name of the function along with whatever argument is passed to them so there is no need to get the current function name.

testWarning <- function() warning("X")
testWarning()
## Warning message:
## In testWarning() : X

Tags:

R