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

发布于 2024-09-14 09:49:41 字数 423 浏览 8 评论 0原文

我试图显示调用函数时提供的参数的实际值。 `match.call' 按照我想要的方式做了一些事情,但它不评估变量。例如

foo <- function(x) match.call()
foo(2)

印刷品

foo(x = 2)

,我对此很满意。但是:

xxx <- 2
foo(xxx)

将打印

foo(x = xxx)

而不是 foo(x = 2) 因为我想要它。

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

I am trying to display the actual values of the parameters that were supplied when the function was called. `match.call' does something along the lines I want but it does not evaluate variables. For example

foo <- function(x) match.call()
foo(2)

prints

foo(x = 2)

and I am happy with that. However:

xxx <- 2
foo(xxx)

will print

foo(x = xxx)

instead of foo(x = 2) as I would like to have it.

I have tried various combinations of substitute, eval, and company, but was not succesful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

妄司 2024-09-21 09:49:42

我不久前编写了一个函数 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])))
}

如果您需要保留有关调用的更多信息或将其格式化得更好,那么您通常会使用它来代替 match.call(),例如:

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)

也许您可以使用它来解决你的问题。

I wrote a function expand.call() that does what you want (I think...) a while ago. Actually, it does a little more:

#' 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])))
}

You would normally use this as a substitute for match.call() if you need to preserve some some more info about the call or have it formatted more nicely, like:

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)

Maybe you can use it to solve your problem.

夏夜暖风 2024-09-21 09:49:42

我不知道这是否是最好的方法,但也许你可以通过以下方式做到这一点:

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)

I don't know if this is the best way, but probably you can do it by:

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文