2016-03-09 6 views
1

У меня аналогичный вопрос, как this one, но более частный случай.получить имя функции, присвоенной переменной в R

Рассмотрим следующий пример кода:

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

Теперь я хочу, чтобы получить имена функций, возложенных на переменные, как charachter с.

Хотя я понимаю, что 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.


редактировать: на основе Roland «s answer, я был в состоянии упростить приведенное выше определение функции к следующему:

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). Тем не менее, я не смог включить ваш подход в функцию (используя 'findGeneric', если' is.primitive' и 'deparse' в противном случае, так как' funX' будет скопирован снова (в 'fun' в моем примере), когда будет передано как аргумент функции более высокого порядка. В этом случае 'utils ::: findGeneric (as.character (quote (fun)), parent.frame())' returns '" "', возможно, это может быть сделано путем замены ' parent.frame() 'другим' envir'? – mschilli

+0

Да, '.GlobalEnv'. – Roland

+0

' sapply (l, function (fun) utils ::: findGeneric (as.character (quote (fun)), GlobalEnv)) 'возвращает' "" "" "" ', как и' sapply (l, function (fun) utils ::: findGeneric (as.character (quote (fun)), parent.frame())) 'before ... – mschilli

Смежные вопросы