简体   繁体   中英

get name of function assigned to variable in R

I have a similar question as this one , but a more special case.

Consider the following example code:

fun1 <- mean
fun2 <- max
fun3 <- median

Now I want to get the names of the functions assigned to the variables as charachter s.

While I understand that this is not possible in general , the above case seems somewhat special:

l <- list(fun1 = fun1, fun2 = fun2, fun3 = fun3)
l
$fun1
function (x, ...)
UseMethod("mean")
<bytecode: 0x2793818>
<environment: namespace:base>
$fun2
function (..., na.rm = FALSE)  .Primitive("max")
$fun3
function (x, na.rm = FALSE)
UseMethod("median")
<bytecode: 0x28382c8>
<environment: namespace:stats>

So the output of print(funX) contains the name of the function assigned to funX .

How can I extract this information into a character vector?

Use findGeneric for the S3 generics:

fun1 <- mean

utils:::findGeneric("fun1", parent.frame())
#[1] "mean"

For a primitive function you can deparse the function body:

fun2 <- max
is.primitive(fun2)
#[1] TRUE

body <- deparse(fun2)
m <- gregexpr('(?<=\\.Primitive\\(\\").*(?=\\")', body, perl = TRUE)
regmatches(body, m)[[1]]
#[1] "max"

The best I could come up with so far is parsing the print output:

get_fun <- function(fun){
             lines <- capture.output(print(fun))
             pat <- "UseMethod|Primitive"
             index <- grep(pat, lines)
             line <- lines[index]
             pat <- paste0(".*(", pat, ")")
             chunk <- sub(pat, "", line)
             words <- strsplit(chunk, "\"")[[1]]
             return(words[2])
           }
sapply(l, get_fun)
    fun1     fun2     fun3
  "mean"    "max" "median"

But there has to be a more direct way. After all somehow these names make it to the print output in the first place.


edit: Based on Roland 's answer , I was able to simplify the above function definition to the following:

get_fun <- function(fun){
             fun <- deparse(fun)
             chunk <- tail(fun, 1)
             words <- strsplit(chunk, "\"")[[1]]
             return(words[2])
           }

Still I hope for a more direct/robust solution (as a higher-order function, maybe returning "fun" for cases were the real underlying function can not be determined/does not exist).

for (myfun in c(max,mean,median))
  print(gsub('^.*"(.*)".*','\\1',tail(deparse(myfun),1)))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM