4 Stimmen

Anzeige der aktuellen Parameterliste der Funktion während der Ausführung

Ich versuche, die tatsächlichen Werte der Parameter anzuzeigen, die beim Aufruf der Funktion übergeben wurden. match.call" tut etwas in der Art, wie ich es möchte, aber es wertet keine Variablen aus. Zum Beispiel

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

druckt

foo(x = 2)

und damit bin ich zufrieden. Wie auch immer:

xxx <- 2
foo(xxx)

wird gedruckt

foo(x = xxx)

anstelle von foo(x = 2) wie ich es gerne hätte.

Ich habe verschiedene Kombinationen von substitute , eval und Unternehmen, war aber nicht erfolgreich.

7voto

fabians Punkte 3228

Ich habe vor einiger Zeit eine Funktion expand.call() geschrieben, die das tut, was Sie wollen (glaube ich...). Eigentlich macht sie sogar noch ein bisschen mehr:

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

Normalerweise würden Sie dies als Ersatz für match.call() verwenden, wenn Sie mehr Informationen über den Aufruf erhalten oder ihn besser formatieren möchten, z. B.:

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)

Vielleicht können Sie damit Ihr Problem lösen.

3voto

kohske Punkte 63276

Ich weiß nicht, ob dies der beste Weg ist, aber wahrscheinlich kann man es so machen:

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)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X