2016-12-05 3 views
0

많은 인수를 허용하는 함수를 가지고 있으며 더 쉽게 만들 수 있습니다. 인수가 목록으로 도입 된 다른 변수를 포함하기로 결정했습니다 (아래 예에서는 args).함수 내에서 인수 덮어 쓰기

다음 my_args
foo(0) 
$x 
[1] 0 

$a 
[1] 1 

$b 
[1] 2 

$c 
[1] 3 

프로파일 인수를 기록

foo <- function(x, a, b, c, args, ...) { 

ifelse(missing(a)==TRUE, a<-1, NA) 
ifelse(missing(b)==TRUE, b<-2, NA) 
ifelse(missing(c)==TRUE, c<-3, NA) 

if(missing(args)==FALSE) { 
for(i in 1:length(args)) { 
    tmp <- as.vector(args[[i]]) 
    assign(names(args)[i], get("tmp")) 
} 
} 

# Need something that overwrites "args" when the 
# other arguments are specified 

print(list(x=x, a=a, b=b, c=c)) 

} 

그리고 기능 foo는 다음과 같은 수 있습니다.

my_args <- list(a=1, b=1, c=1) 

가 생산하는 :

foo(0, args=my_args) 
$x 
[1] 0 

$a 
[1] 1 

$b 
[1] 1 

$c 
[1] 1 


내가 해당 인수가 함수에 지정된 때마다 args에 값을 덮어 쓸 수있는 방법을 찾아야하고 싶습니다. 사용자가 동일한 인수에 대해 두 개의 서로 다른 값을 지정 했더라도 이것이 의미가있는 상황이 있습니다. 예를 들어

,

foo(0, args=my_args, c=3) 
$x 
[1] 0 

$a 
[1] 1 

$b 
[1] 1 

$c 
[1] 3 

그리고 이런 것을 볼 때 my_args에 기록 된 프로파일 내 c=3.

대단히 감사합니다.

+0

간단한 생각 (A/B/C 또는 인수) 모두가 당신의 선택에 따라 설정 한 후 비 누락하는 경우()를 확인하면 추가를 가졌다. –

+1

@ joel.wilson'if (! (exists (names (args) [i])))'와'if (누락 (대체 (names (args) [i])))'성공하지 않고 여러 조건을 시험해 보았습니다. ,하지만 옵션 (a/b/c 또는 args) 모두를 보게 될 것입니다. 감사합니다 – JARO

+0

'function (x, a = NA, b = NA, c = NA, args = list (a = a, b = b, c = c), ...)'을 정의하고'args '함수에서. – Roland

답변

1

:하지만이 당신이 원하는 일을 하나의 방법입니다. 인수가 전달되지 않으면 기본값을 취합니다. stopifnot 문은 defaults에 나열된 인수 이외의 인수가 ... 또는 args에 전달되면 오류가 발생합니다. defaults에 나열되지 않은 추가 인수가 전달되지 않도록하는 데 사용할 수 있습니다. 또는 무제한 인수를 허용하기 위해 해당 행을 모두 생략 할 수 있습니다.

foo <- function(x, ..., args = list()) { 
    defaults <- list(a = -1, b = -2, c = -3, d = -4) 
    Args <- Reduce(modifyList, list(defaults, args, list(...))) 
    stopifnot(all(names(Args) %in% names(defaults))) 
    Args 
} 

foo(0, a = 1, b = 2, args = list(a = 10, c = 20)) 

제공 :

$a 
[1] 1 

$b 
[1] 2 

$c 
[1] 20 

$d 
[1] -4 
+0

이것은 훌륭한 옵션입니다! 감사. 실제로'defaults <- list (a = -1, b = -2, c = -3, d = -4, ...)를 열면'foo (0, a = 1)와 같은 무제한 인자를 포함 할 수 있습니다. , b = 2, d = 5, args = list (a = 10, c = 20), e = 9, z = "char")' – JARO

+0

이렇게하면 'defaults'에 같은 이름을 가진 두 개의 다른 구성 요소가 생길 수 있습니다. 대신 무제한의 인자를 원하면'stopifnot (...)'을 생략하면된다. 나는 이것을 해답에서 분명히했다. –

+0

맞습니다. 'defaults'를 열면 입력 된 인자가 출력됩니다. 이제 당신의 기능은 매력처럼 작동합니다. – JARO

1

abc에 대한 기본값 지정이 코드를 보면 매우 분명하지 않은 점에서이 구조의 팬이 아닙니다. 이 인수는 args 목록을 통해 전달하거나 ...를 통해이 경우 그들은 args 사람들을 덮어 쓸 수 있습니다

foo <- function(x, a = NA, b = NA, c = NA, args = NULL, ...) { 
    if (is.null(args)) { 
    a <- ifelse(is.na(a), 1, a) 
    b <- ifelse(is.na(b), 2, b) 
    c <- ifelse(is.na(c), 3, c) 
    } else { 
    args[!is.na(c(a, b, c))] <- c(a, b, c)[!is.na(c(a, b, c))] 
    lapply(names(args), function(x) assign(x, args[[x]], inherits = TRUE)) 
    } 
    print(list(x=x, a=a, b=b, c=c)) 
} 
+0

답장을 보내 주셔서 감사합니다. @Axeman. 그러나 'c (a, b, c)'는 예제 일 뿐이며 함수의 잠재적 인수의 조합을 평가해야하며 제어 흐름이 필요할 것으로 보입니다. 그럼에도 불구하고 코드가 작동하며이 옵션을 자세히 살펴볼 것입니다. – JARO

관련 문제