Holen Sie sich alle Parameter als Liste


79

Stellt R ein Objekt / eine Funktion / eine Methode / ein Schlüsselwort bereit, um alle Funktionsargumente abzurufen?

Anhand eines Beispiels: function(a, b="default", ...)würde aund bsowie ...innerhalb der Funktionsumgebung. Gibt es eine ähnliche Aussage list(...), die auch aund bim Ergebnis enthalten wäre?

Oder noch anders ausgedrückt: eine Abkürzung für list(a=a, b=b, ...)gegebenfunction(a, b, ...)


1
Das Problem dieser Frage ist, dass nicht klar ist, was Sie fragen. Fragen Sie, wie Sie 1) die Werte erhalten, mit denen die Funktion aufgerufen wurde ? 2) die Ausdrücke, mit denen die Funktion aufgerufen wurde; 3) die Standardwerte in der Funktionsdefinition? Aus Ihrer Frage geht überhaupt nichts hervor, daher haben Sie für alle diese drei Optionen drei verschiedene Arten von Antworten erhalten.
TMS

Antworten:


67

Ich denke, dass Sie wollen match.call:

tmpfun <- function(a,b,...) {
print(as.list(match.call()))
print(as.list(match.call(expand.dots=FALSE)))
}
> tmpfun(a=1, b=2, c=3, d=4)
[[1]]
tmpfun

$a
[1] 1

$b
[1] 2

$c
[1] 3

$d
[1] 4

[[1]]
tmpfun

$a
[1] 1

$b
[1] 2

$...
$...$c
[1] 3

$...$d
[1] 4

22
Dies schlägt fehl, wenn die Standardeinstellungen im Funktionsaufruf nicht überschrieben werden. Das Argument wird nicht mit der Standardeinstellung aufgelistet, aber nicht überschrieben.

Kennen Sie ein Paket, das eine solche Funktion exportiert (nur ...als Parameter)?
krlmlr

4
Dies funktioniert nicht, wenn tmpfun Argumente von einer anderen Wrapper-Funktion empfangen hat. (Die Liste enthält nur die nicht bewerteten Argumente)
RockScience

Aus diesen Gründen sollte die akzeptierte Antwort die von @ user399470 sein, c(as.list(environment()), list(...))die sowohl Standardargumente als auch bereitgestellte Args erfasst.
Lorenz Walthert

75

Eine Lösung ist zu verwenden:

tempf <- function(a, b = 2, ...) {
    argg <- c(as.list(environment()), list(...))
    print(argg)
}
tempf(1, c = 3)
$a
[1] 1

$b
[1] 2

$c
[1] 3

Dadurch wird eine benannte Liste der Argumentwerte erstellt.


Kennen Sie ein Paket, das eine solche Funktion exportiert (nur ...als Parameter)?
krlmlr

2
oder drucken Sie einfach (as.list (environment ())), wenn Sie nicht ... als Argument haben
RockScience

3
Dies funktioniert hervorragend. Es hat gegenüber der akzeptierten Antwort den Vorteil, dass die an die Funktion übergebenen Werte erfasst werden und nicht die Ausdrücke , mit denen die Werte berechnet werden können. Wenn Sie versuchen, die Argumente zu speichern, damit Sie die Funktion später aufrufen können, möchten Sie wahrscheinlich die Werte.
Ken Williams

12

versuchen Sie die argsFunktion

Was sind die Argumente für die meanFunktion?

> args(mean)
function (x, ...) 
NULL

Was ist mit der lmFunktion?

    > args(lm)
function (formula, data, subset, weights, na.action, method = "qr", 
    model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE, 
    contrasts = NULL, offset, ...) 
NULL

Wenn Sie eine Liste mit Argumenten erhalten möchten, versuchen Sie es

as.list(args(lm))

Es ist schade, dass mehr Funktionen nicht mit dem Aufruf von args zusammenarbeiten, wie z. B. Vorhersagen. Also Humbug, woanders hingehen zu müssen, um sich an diesen einen Parameter / Flag zu erinnern, an den Sie sich erinnern wollten.
Vielleicht

8

Stolperte über diese Frage, als ich nach etwas Ähnlichem suchte. Obwohl mir klar ist, dass dies mehrere Jahre alt ist, scheinen die Antworten unbefriedigend zu sein, und es scheint keine Standardlösung für die Frage zu geben.

Es ist möglich, eine (unelegante) Problemumgehung mithilfe einer Kombination der Funktionen formalsund environmentdurchzuführen. Im folgenden Beispiel werden Argumente aus der Umgebung mithilfe von Namen extrahiert, die aus Formalen extrahiert wurden, und anschließend wird die Ellipsenliste angehängt. Wenn Sie die Werte so haben möchten, wie sie zum Zeitpunkt des Funktionsaufrufs festgelegt wurden, setzen Sie das Argument orig_values ​​auf TRUE. Die Funktion enthält nur Variablen, die beim Funktionsaufruf implizit oder explizit festgelegt werden.

allargs <- function(orig_values = FALSE) {
  # get formals for parent function
  parent_formals <- formals(sys.function(sys.parent(n = 1)))

  # Get names of implied arguments
  fnames <- names(parent_formals)

  # Remove '...' from list of parameter names if it exists
  fnames <- fnames[-which(fnames == '...')]

  # Get currently set values for named variables in the parent frame
  args <- evalq(as.list(environment()), envir = parent.frame())

  # Get the list of variables defined in '...'
  args <- c(args[fnames], evalq(list(...), envir = parent.frame()))


  if(orig_values) {
    # get default values
    defargs <- as.list(parent_formals)
    defargs <- defargs[unlist(lapply(defargs, FUN = function(x) class(x) != "name"))]
    args[names(defargs)] <- defargs
    setargs <- evalq(as.list(match.call())[-1], envir = parent.frame())
    args[names(setargs)] <- setargs
  }
  return(args)
}


tempf <- function(a, b = 2, ...) {
  d <- 5
  b <- 3

  cat("Currently set values defined in call or formals\n")
  print(allargs())
  cat("Values as defined at the time of the call\n")
  print(allargs(T))
}

tempf(1, c = 3)

Currently set values defined in call or formals
$a
[1] 1

$b
[1] 3

$c
[1] 3

Values as defined at the time of the call
$a
[1] 1

$b
[1] 2

$c
[1] 3

6

Ich glaube, Sie suchen formals:

formals(sd)
$x


$na.rm
[1] FALSE

Und mit dputauf das gibt Ihnen das Formular Sie in der Frage geben:

dput(formals(sd))
list(x = , na.rm = FALSE)

Beachten Sie, dass formalsdies nicht für primitive Funktionen funktioniert, sondern nur für Schließungen.


2
Hier werden nur die Standardargumente aufgelistet .
RockScience

1
test <- function(
  x = 1,
  y = 2,
  ...
) {
  if(length(list(...)) == 0) {
    print(as.list(environment()))
  } else {
    print(c(as.list(environment()), list(...)))
  }
}

test()
test(z = 3)

3
Was wäre der Vorteil dieser Methode gegenüber den bereits vorgeschlagenen Lösungen? Insbesondere scheint dies der Antwort von user399470
Matt Summersgill

1

rlang::fn_fmls gibt eine kurze und saubere Lösung:

library(ggplot2)
library(rlang)

# action
argument_list <- rlang::fn_fmls(fn = geom_point)

# evaluate output
class(argument_list)
#> [1] "pairlist"

is.list(argument_list)
#> [1] TRUE

argument_list
#> $mapping
#> NULL
#> 
#> $data
#> NULL
#> 
#> $stat
#> [1] "identity"
#> 
#> $position
#> [1] "identity"
#> 
#> $...
#> 
#> 
#> $na.rm
#> [1] FALSE
#> 
#> $show.legend
#> [1] NA
#> 
#> $inherit.aes
#> [1] TRUE

Erstellt am 25.02.2020 durch das reprex-Paket (v0.3.0)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.