如何检索原始函数的形式?

时间:2014-09-22 15:56:25

标签: r

目前,至少,这是一个为我学习的练习,所以实际功能或其复杂性不是问题。假设我编写了一个函数,其参数列表包含一些输入变量和一个函数名,作为字符串传递。然后,此函数在内部计算一些变量,并决定"如何将它们提供给我传入的功能名称。

对于非原始函数,我可以这样做(对于这个例子,假设我的funcname函数不具有除最多(x,y,z)以外的任何参数。如果他们这样做,我必须写一些代码用于搜索匹配的names(formals(get(funcname))),以便不删除其他参数):

foo <- function (a,b,funcname) {
    x <- 2*a
    y <- a+3*b
     z <- -b
    formals(get(funcname)) <- list(x=x, y=y, z=z)
    bar <- get(funcname)()
return(bar)
}

好的是,即使函数funcname没有错误也会执行,即使它没有使用xyz(所以只要没有其他没有违约的参数。) &#34;原语&#34;的问题功能是我不知道如何找到或修改他们的形式。除了写一个包装器,例如foosin <-function(x) sin(x),有没有办法设置我的foo函数来处理原始和非原始函数名作为输入参数?

2 个答案:

答案 0 :(得分:4)

formals(args(FUN))可用于获取原始函数的形式。

您可以在现有功能中添加if语句。

> formals(sum)
# NULL
> foo2 <- function(x) {
      if(is.primitive(x)) formals(args(x)) else formals(x)
      ## formals(if(is.primitive(x)) args(x) else x) is another option
  }
> foo2(sum)
# $...
#
#
# $na.rm
# [1] FALSE
#
> foo2(with)
# $data
# 
#
# $expr
#
#
# $...

答案 1 :(得分:1)

在理查德S的回应基础上,我最终做了以下事情。发布以防万一其他人尝试过像我一样奇怪的事情。

编辑:我认为需要进行更多的类型检查。 coleqn可能是。{1}} 对象的名称,在这种情况下get(coleqn)将返回一些数据。可能我需要 在if(is.function(rab))之后添加if(!is.null(rab))。 (当然,鉴于我根据自己的需要编写了函数,如果我愚蠢到传递一个对象,我应该得到的东西:-))。

# "coleqn" is the input argument, which is a string that could be either a function
# name or an expression.

rab<-tryCatch(get(coleqn),error=function(x) {} )
#oops, rab can easily be neither NULL nor a closure. Damn.
if(!is.null(rab)) {
# I believe this means it must be a function
# thanks to Richard Scriven of SO for this fix to handle primitives
# we are not allowed to redefine primitive's formals.
    qq <- list(x=x,y=y,z=z) 
#  matchup the actual formals names
#  by building a list of valid arguments to pass to do.call 
    argk<-NULL
    argnames<-names(formals(args(coleqn)))
    for(j in 1:length(argnames) )
        argk[j]<-which(names(qq)==argnames[1] )
    arglist<-list()
    for(j in 1:length(qq) ) 
        if(!is.na(argk[j])) arglist[[names(qq)[j]]]<-qq[[j]]
    colvar<- do.call(coleqn,arglist) 
    } else {
# the input is just an expression (string), not a function
        colvar <- eval(parse(text=coleqn)) 
    } 

结果是一个由表达式或刚创建的函数生成的对象,使用main函数内部的变量(未在此片段中显示)