2014-11-21 2 views
3

제네릭 함수에 대한 새 메소드 설정에 관심이 있습니다. 예를 들어, 새 클래스가 있다고 가정 해 보겠습니다 (예 : coolClass).R S4 setMethod에 대한 선택적 인수

setMethod("Math", c(x="coolClass"), 
      function(x) 
      { 
      op = .Generic[[1]] 
      switch(op, 
        `log10` = log10_for_coolClass(x), 
        stop("Undefined operation") 
      ) 
      } 
) 

는 그러나, 나는 여러 인수를 전달하는 방법을 설정하는 방법을 알아낼 수 없습니까 : 나는 다음과 같은 코드로 방법을 설정 쉽게 그 클래스의 log10를 계산하는 래퍼를 작성할 수 있습니다. 예를 들어 일반 log 메서드입니다. 다음 getGeneric("log")을 보여줍니다 실행 :

> getGeneric("log") 
standardGeneric for "log" defined from package "base" 
    belonging to group(s): Math 

function (x, ...) 
standardGeneric("log", .Primitive("log")) 
<bytecode: 0x2f9a958> 
<environment: 0x2f937f0> 
Methods may be defined for arguments: x 
Use showMethods("log") for currently available ones. 

이를보고, 나는이 옵션 base 인수를 전달 할 수 있도록 다음과 같은 쓸 수 있습니다 기대.

Error in matchSignature(signature, fdef, where) : 
    '...' used in an incorrect context 

내가 다른 오류 얻을 signature...없이 시도 :

setMethod("Math", signature(x="coolClass",...), 
      function(x, ...) 
      { 
      op = .Generic[[1]] 
      switch(op, 
        `log` = log_for_coolClass(x, ...), 
        stop("Undefined operation") 
      ) 
      } 
) 

는하지만 다음과 같은 오류 얻을

Error in rematchDefinition(definition, fdef, mnames, fnames, signature) : 
    methods can add arguments to the generic ‘Math’ only if '...' is an argument to the generic 

주어진 나에게 이상한 것 같다 getGeneric 로그 프로그램이 메소드의 ....

아이디어가 있으십니까? 추가 인수를 포착 할 수있는 방법이 있습니까? 나는 S4 메쏘드에 좀 더 익숙해 지려고 노력하고 있지만 선택적인 인자들을 전달하는 방법에 대해서는 혼란 스럽다. 만약 이것이 가능하지 않다면, 누군가가 log 함수가 어떻게 동작 하는지를 설명 할 수 있다면 감사 할 것입니다. 예를 들어 함수가 Math 그룹의 일부이지만 다중 인수를 허용하는 경우입니다. 아래 언급 된

업데이트

이상하게도, 나는 다음과 log에 직접 setMethod를 사용할 수 있습니다

setMethod("log", signature(x="big.matrix"), 
      function(x, base=exp(1)) 
      { 
      log_for_coolClass(x, base=base) 
      } 
     ) 

그러나이 꽤 나의 호기심을 진정하지 않습니다. 예를 들어, Math 그룹 내에 많은 새로운 메소드를 만들면 코드에서 반복적 인 것이 이상하게 보입니다. 이상적으로는 다음과 같이 보일 것입니다 :

setMethod("Math", c(x="coolClass"), 
      function(x, base=exp(1)) 
      { 
      op = .Generic[[1]] 
      switch(op, 
        `log10` = log10_for_coolClass(x), 
        `log` = log_for_coolClass(x, base=base), 
        stop("Undefined operation") 
      ) 
      } 
) 

답변

1

여기 log 같은 함수에 대한 클래스

.A <- setClass("A", representation(x="numeric")) 

의 서명이 ...을 포함한다 우리가

> getGeneric("log") 
standardGeneric for "log" defined from package "base" 
    belonging to group(s): Math 

function (x, ...) 
standardGeneric("log", .Primitive("log")) 
<bytecode: 0x2b41b28> 
<environment: 0x2b39df8> 
Methods may be defined for arguments: x 
Use showMethods("log") for currently available ones. 

있습니다.그래서 우리는

setMethod("log", "A", function(x, ...) { 
    log([email protected], ...) 
}) 

를 작성하지 않고이 성공

> log(.A(x=c(1, 2, NA))) 
[1] 0.0000000 0.6931472  NA 
> log(.A(x=c(1, 2, NA)), base=2) 
[1] 0 1 NA 

다음은 : LOG10

> getGeneric("log10") 
standardGeneric for "log10" defined from package "base" 
    belonging to group(s): Math 

function (x) 
standardGeneric("log10", .Primitive("log10")) 
<bytecode: 0x2b4a700> 
<environment: 0x2b43138> 
Methods may be defined for arguments: x 
Use showMethods("log10") for currently available ones. 

없음 ... 인수를 일반에, 그래서 우리는 기본적으로 붙어있어 - 우리 자신의 일반적인 쓰기 ...을 포함하는 메소드를 구현하거나 ... 인수가없는 log10, A- 메소드를 작성하십시오.

...에 대한 동일한 원리가 그룹 제네릭에 적용 - 수학 그룹 일반적인 그래서 우리의 방법 (모든 수학 작업을 을 구현 점

> getGeneric("Math") groupGenericFunction for "Math" defined from package "base" function (x) standardGeneric("Math") <bytecode: 0x2771d40> <environment: 0x275ee20> Methods may be defined for arguments: x Use showMethods("Math") for currently available ones. 

이없는, 단지 기록하지;주의 우리는 일반적으로

setMethod("Math", "A", function(x) { 
    callGeneric([email protected]) 
}) 

수 있습니다 우리의 클래스의 객체에 .Generic 명시 적으로)를 참조하지 않는 지금 우리는 예를 들어,

, 모든 수학 기능을위한 방법을
> sqrt(.A(x=1:4)) 
[1] 1.000000 1.414214 1.732051 2.000000 

도 사용할 수있는 log의 변형은 계속 사용할 수 있으므로 모든 수학 제네릭에 대한 클래스의 동작을 정의하고 특정 제네릭에 대한 특수 구현을 제공 할 수 있습니다.

해결해야 할 그룹 제네릭의 구현에 버그가있을 수 있습니다. 새로운 세션에서 우리가 ... 인수와 함께 우리의 클래스 및 일반 Math 아닌 log 기능을 정의한 경우, 우리는 두 번째 인수가 무시되는 경우 여전히

> log(.A(x=1:4)) 
[1] 0.0000000 0.6931472 1.0986123 1.3862944 
> log(.A(x=1:4), base=2) 
[1] 0.0000000 0.6931472 1.0986123 1.3862944 

를 호출 할 수 있지만 정말 오류가 발생합니다.

+0

대답은'setMethod'를'log'에 직접 발견 한 것과 같습니다. 'callGeneric'을 사용하여 모든 수학 연산에 액세스하는 것은 흥미 롭습니다. 그러나 클래스에는 별도로 작성하고 호출해야하는보다 복잡한 함수가 필요합니다. 따라서 특정 방법을 별도로 설정해야하는 것으로 보입니다. 더 간결하게 (업데이트 된 질문 참조) 바라고 있었지만 그것이 유일한 방법 일 경우. – cdeterman