2016-03-09 125 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