2016-03-09 30 views
1

我有一个类似的问题this one,但更特殊的情况。获取分配给变量的函数名称R

考虑下面的示例代码:

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

现在,我想分配给变量charachter S中的函数的名称。

虽然我明白this is not possible in general,上述情况似乎有点特殊:

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> 

所以print(funX)输出包含分配给funX函数的名称。

如何将这些信息提取到character向量中?

回答

0

我能想出迄今被解析print输出最佳:

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" 

但必须有一个更直接的方式。 毕竟这些名字首先使它成为print输出。


编辑: 基于Rolandanswer,我才得以以上函数的定义简化为以下几点:

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

尽管如此,我希望有一个更直接的/强大的解决方案(作为一个高阶函数,可能返回"fun"的情况下,真正的底层函数无法确定/不存在)。

1

使用findGeneric为S3泛型:

fun1 <- mean 

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

对于原始功能,您可以deparse函数体:

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

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

THX很多关于你的好建议。你的第二个例子帮助我简化[我的解决方案](http://stackoverflow.com/a/35885909/2451238)。尽管如此,我还是无法将你的方法包装到一个函数中(如果'is.primitive'和'deparse'使用'findGeneric',否则,因为'funX'会在被传递时再次被复制(在我的例子中为'fun')在这种情况下,utils ::: findGeneric(as.character(quote(fun)),parent.frame())''''''也许这可以通过替换' parent.frame()'由另一个'envir'? – mschilli

+0

Yes,'.GlobalEnv'。 – Roland

+0

'sapply(l,function(fun)utils ::: findGeneric(as.character(quote(fun)),. GlobalEnv)) (函数(fun)utils ::: findGeneric(as.character(quote(fun)),parent.frame()))''before ... – mschilli