모든 매개 변수를 목록으로 가져 오기


80

R은 모든 함수 인수를 얻기 위해 객체 / 함수 / 메서드 / 키워드를 제공합니까?

예를 들어 사용 : function(a, b="default", ...)제공 할 것입니다 ab뿐만 아니라 ...함수 환경에서. 성명과 유사한 거기에 list(...)그 또한 포함 할 것입니다 ab결과에?

또는 또 다른 표현 : list(a=a, b=b, ...), 주어진function(a, b, ...)


1
이 질문의 문제는 당신이 요구하는 것이 명확하지 않다는 것입니다. 1) 함수가 호출 된 을 얻는 방법을 묻고 있습니까? 2) 함수가 호출 된 표현식 ; 3) 함수 정의 의 기본값 은 무엇입니까? 질문에서 전혀 명확하지 않으므로이 3 가지 옵션 모두에 대해 3 가지 유형의 답변을 얻었습니다.
TMS

답변:


67

나는 당신이 원한다고 생각합니다 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

23
함수 호출에서 기본값이 재정의되지 않으면 실패합니다. 기본 세트로 인수를 나열하지 않지만 재정의되지는 않습니다.

( ...매개 변수 로만) 그러한 함수를 내보내는 패키지를 알고 계십니까 ?
krlmlr

5
tmpfun이 다른 래퍼 함수에서 인수를받은 경우에는 작동하지 않습니다. (목록에는 평가되지 않은 인수 만 있습니다.)
RockScience

1
이러한 이유로 허용되는 답변은 c(as.list(environment()), list(...))기본 인수와 제공된 인수를 모두 캡처 하는 @ user399470의 답변이어야합니다 .
Lorenz Walthert

77

한 가지 해결책은 다음을 사용하는 것입니다.

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

이렇게하면 인수 값의 명명 된 목록이 생성됩니다.


( ...매개 변수 로만) 그러한 함수를 내보내는 패키지를 알고 계십니까 ?
krlmlr

2
또는 단순히 print (as.list (environment ())) 만약 없다면 ... 인수로
RockScience

3
이것은 훌륭하게 작동하며, 을 계산하는 데 사용할 수있는 표현식 이 아니라 함수에 전달 된 값을 캡처한다는 허용 된 답변보다 이점 이 있습니다. 나중에 함수를 호출 할 수 있도록 인수를 저장하려는 경우 값이 필요할 수 있습니다.
Ken Williams

1
argg <- c(as.list(environment()), list(...))함수의 맨 처음 에 실행하여 인수를 "캡처"하는 것이 일반적으로 중요하다는 점을 지적 할 가치가 있습니다 . 그렇지 않으면 environment()내에서 생성 된 다른 변수를 포함하게됩니다tempf()
mkirzon

12

시도 args기능

mean함수에 대한 인수는 무엇입니까 ?

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

무엇에 대한 lm기능?

    > 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

인수 목록을 얻으려면 다음을 시도하십시오.

as.list(args(lm))

더 많은 함수가 predict와 같은 args 호출과 협력하지 않는 것이 나쁘다. 따라서 기억하려고했던 하나의 매개 변수 / 플래그를 기억하기 위해 다른 곳으로 가야합니다.
DChaps 2010

9

관련 항목을 검색하는 동안이 질문을 우연히 발견했습니다. 나는 이것이 몇 년 전이라는 것을 알고 있지만 응답이 불만족스러워 보이며 질문에 대한 기성 솔루션이없는 것 같습니다.

formalsenvironment함수 의 조합을 사용하여 (불쾌한) 해결 방법을 만들 수 있습니다. 아래 예제는 형식에서 추출한 이름을 사용하여 환경에서 인수를 추출한 다음 ellipsis-list를 추가합니다. 함수 호출시 설정된 값을 유지하려면 orig_values ​​인수를 TRUE로 설정하십시오. 함수에는 함수 호출시 암시 적으로 또는 명시 적으로 설정된 변수 만 포함됩니다.

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

나는 당신이 찾고 있다고 믿습니다 formals:

formals(sd)
$x


$na.rm
[1] FALSE

그리고 dput이것을 사용하면 질문에서 지정한 양식이 제공됩니다.

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

참고 formals작동하지 않습니다 기본 기능 만 폐쇄.


2
이것은 기본 인수 만 나열합니다 .
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
이미 제안 된 솔루션에 비해이 방법을 사용하면 어떤 이점이 있습니까? 특히,이 user399470로 대답 매우 비슷한 것 같다
매트 서머스에게

1

rlang::fn_fmls 간단하고 깨끗한 솔루션을 제공합니다.

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

reprex 패키지 (v0.3.0)로 2020-02-25에 생성됨

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.