3

I have functions f1 and f2 that are taking a function as argument, eg:

f1 <- function(FUN) {
    ...
}


f2 <- function(FUN)  {
   f1(FUN=FUN)
}

From inside function f1, I need to find back the original name of the function passed to f2, eg "myFunc", but not "FUN".

Basically can we imagine a function f1 so that f2(f1(mean)) returns "mean"? If FUN is anonymous, we can for instance return NULL or NA.

Is there an easy / standard way to do that in R? I have tried to manually search for identical function code using (but it is not very clean and I am looking for a better solution)

fn = unlist(as.list(lsf.str(envir=.GlobalEnv)))
for (f in fn) {
    if (setequal(paste(body(myFunc)),paste(body(f)))) { 
      return(f)
    }
}
RockScience
  • 17,932
  • 26
  • 89
  • 125
  • 1
    There is not enough information here. You need to create a reproducible example. If `FUN` is supposed to be a function, it could be anonymous. What should be returned in such a case? – Roland Apr 28 '15 at 07:19
  • @Roland Basically can we imagine a function `f1` so that `f2(f1(mean))` returns "mean"? If FUN is anonymous, we can for instance return NULL or NA. I modified the question with your feedback – RockScience Apr 28 '15 at 08:09

2 Answers2

1

You can use the lazyeval package too:

f1 <- function(FUN) {
  lazyeval::expr_text(FUN)
}


f2 <- function(FUN)  {
  f1(FUN = FUN)
}

f2(f2(f2(mean)))
[1] "f2(f2(mean))"

This worked for me:

f1 <- function(FUN) {
  eval(quote(substitute(FUN)), envir = parent.frame())
}


f2 <- function(FUN)  {
  f1(FUN=FUN)
}

f2(mean)

In this case, f1 evaluates the substitute(FUN) call in the f2 environment.

See theese results:

> f2(mean)
mean
> f2(function(x) {NULL})
function(x) {
  NULL
}

If you want the output to be string, you need to use deparse, then f1 can be defined:

f1 <- function(FUN) {
  eval(quote(deparse(substitute(FUN))), envir = parent.frame())
}
Daniel Falbel
  • 1,721
  • 1
  • 21
  • 41
1

In most situations, following function give the original name.

find.original.name <- function(fun) {
    objects <- ls(envir = environment(fun))
    for (i in objects) {
        if (identical(fun, get(i, envir = environment(fun)))) {
            return(i)
        }
    }
}

a <- ls
find.original.name(a)
# [1] ls

a <- glm
find.original.name(a)
# [1] "glm"

a <- function() print("test")
find.original.name(a)
# [1] "a"

But if a copy of function (to be precise, it's not a copy) and the original function are in the same environment, this function cannot work correctly...

test <- function() print("test")
a <- test
find.original.name(a)
# [1] "a"