R 在执行过程中显示函数的实际参数列表

R 在执行过程中显示函数的实际参数列表,r,function-call,R,Function Call,我试图显示调用函数时提供的参数的实际值`“match.call”按照我想要的方式执行某些操作,但它不计算变量。比如说 foo <- function(x) match.call() foo(2) 我对此感到高兴。然而: xxx <- 2 foo(xxx) 而不是我想要的foo(x=2) 我尝试了各种组合的substitute、eval和company,但都没有成功。我不知道这是否是最好的方法,但您可以通过以下方法来实现: x<-"a" y<-mean z<-1

我试图显示调用函数时提供的参数的实际值`“match.call”按照我想要的方式执行某些操作,但它不计算变量。比如说

foo <- function(x) match.call()
foo(2)
我对此感到高兴。然而:

xxx <- 2
foo(xxx)
而不是我想要的
foo(x=2)


我尝试了各种组合的
substitute
eval
和company,但都没有成功。

我不知道这是否是最好的方法,但您可以通过以下方法来实现:

x<-"a"
y<-mean
z<-1
foo <- function(x,y,z) {
  do.call("call", 
          c(list(as.character(match.call()[[1]])),
            lapply(as.list(match.call())[-1],eval)))
}
foo(x,y,z)

x不久前,我编写了一个函数expand.call(),它可以满足您的需要(我想…)。实际上,它还有一点作用:

#' Return a call in which all of the arguments which were supplied
#' or have presets are specified by their full names and supplied
#' or default values.
#'  
#' @param definition a function. See \code{\link[base]{match.call}}.
#' @param call an unevaluated call to the function specified by definition.
#'  See \code{\link[base]{match.call}}.
#' @param expand.dots logical. Should arguments matching ... in the call be 
#'  included or left as a ... argument? See \code{\link[base]{match.call}}.
#' @param doEval logical, defaults to TRUE. Should function arguments be 
#'  evaluated in the returned call or not?
#'
#' @return An object of class call. 
#' @author fabians
#' @seealso \code{\link[base]{match.call}}
expand.call <- function(definition=NULL,
         call=sys.call(sys.parent(1)),
         expand.dots = TRUE,
         doEval=TRUE)
{

    safeDeparse <- function(expr){
        #rm line breaks, whitespace             
        ret <- paste(deparse(expr), collapse="")
        return(gsub("[[:space:]][[:space:]]+", " ", ret))
    }

    call <- .Internal(match.call(definition, call, expand.dots))

    #supplied args:
    ans <- as.list(call)
    if(doEval & length(ans) > 1) {
      for(i in 2:length(ans)) ans[[i]] <- eval(ans[[i]])
    }

    #possible args:
    frmls <- formals(safeDeparse(ans[[1]]))
    #remove formal args with no presets:
    frmls <- frmls[!sapply(frmls, is.symbol)]

    add <- which(!(names(frmls) %in% names(ans)))
    return(as.call(c(ans, frmls[add])))
}
#“返回一个调用,调用中提供的所有参数
#'或具有预设由其全名指定并提供
#'或默认值。
#'  
#“@param定义一个函数。请参阅\code{\link[base]{match.call}。
#“@param调用对定义指定的函数的未赋值调用。
#'请参阅\code{\link[base]{match.call}。
#“@param expand.dots逻辑。参数是否匹配。。。在电话里
#'包含或留下作为。。。论点请参阅\code{\link[base]{match.call}。
#“@param doEval logical,默认为TRUE。函数参数应该是
#'是否在返回的呼叫中计算?
#'
#“@返回类调用的对象。
#“@作者法比安
#'@seealse\code{\link[base]{match.call}

扩张,呼叫哦,狡猾!它解决了直接在
match.call()
上使用
eval
将再次调用函数的问题。谢谢这是一个伟大的功能!不过,我认为缺少形式参数
eval
。如果我可以添加一个建议:也许你会考虑命名这个论点:代码> doEva<代码>,以免引起函数混淆<代码> EVA/COM>。谢谢,@ BenBarnes。我做了你建议的更改。使用apply for the eval会弄乱搜索路径。如果您定义了一个变量c,那么它将被计算为c基元函数。最好使用for循环。@ThomasP85谢谢,我按照你建议的方式更改了它。
x<-"a"
y<-mean
z<-1
foo <- function(x,y,z) {
  do.call("call", 
          c(list(as.character(match.call()[[1]])),
            lapply(as.list(match.call())[-1],eval)))
}
foo(x,y,z)
#' Return a call in which all of the arguments which were supplied
#' or have presets are specified by their full names and supplied
#' or default values.
#'  
#' @param definition a function. See \code{\link[base]{match.call}}.
#' @param call an unevaluated call to the function specified by definition.
#'  See \code{\link[base]{match.call}}.
#' @param expand.dots logical. Should arguments matching ... in the call be 
#'  included or left as a ... argument? See \code{\link[base]{match.call}}.
#' @param doEval logical, defaults to TRUE. Should function arguments be 
#'  evaluated in the returned call or not?
#'
#' @return An object of class call. 
#' @author fabians
#' @seealso \code{\link[base]{match.call}}
expand.call <- function(definition=NULL,
         call=sys.call(sys.parent(1)),
         expand.dots = TRUE,
         doEval=TRUE)
{

    safeDeparse <- function(expr){
        #rm line breaks, whitespace             
        ret <- paste(deparse(expr), collapse="")
        return(gsub("[[:space:]][[:space:]]+", " ", ret))
    }

    call <- .Internal(match.call(definition, call, expand.dots))

    #supplied args:
    ans <- as.list(call)
    if(doEval & length(ans) > 1) {
      for(i in 2:length(ans)) ans[[i]] <- eval(ans[[i]])
    }

    #possible args:
    frmls <- formals(safeDeparse(ans[[1]]))
    #remove formal args with no presets:
    frmls <- frmls[!sapply(frmls, is.symbol)]

    add <- which(!(names(frmls) %in% names(ans)))
    return(as.call(c(ans, frmls[add])))
}
foo <- function(x, bar="bar", gnurp=10, ...) {
    call <- expand.call(...)
    return(call)
}   

> foo(2)
foo(x = 2, bar = "bar", gnurp = 10)

> xxx <- 2
> foo(xxx)
foo(x = 2, bar = "bar", gnurp = 10)

> foo(xxx, b="bbbb")
foo(x = 2, bar = "bbbb", gnurp = 10)

> foo(xxx, b="bbbb", doEval=FALSE)
foo(x = xxx, bar = "bbbb", doEval = FALSE, gnurp = 10)