문제

Consider the following S4 class:

setClass('Foo', representation(model='data.frame'))

setMethod('initialize', 'Foo',
      function(.Object, a, b) {
        .Object@model <- data.frame(a, b)
        .Object
      })

It can be instantiated with:

new('Foo', a=1:4, b=4:7)

So far so good. However, when I try to subclass Foo I get an error.

setClass('Bar', contains='Foo')
>>> Error in data.frame(a, b) : argument "a" is missing, with no default

Personally, I would prefer to instantiate class Foo with explicit arguments because the code is more... well, explicit. However, this does not seem possible, does it? It looks like the signature of initialize must match the slots that the class has, otherwise it's a problem waiting to happen. Am I wrong?

도움이 되었습니까?

해결책

The requirement is that new called with no arguments, new("Foo"), must work. Also, it's probably better practice for your initialize method to take ..., to callNextMethod, and to have arguments after the ... (because initialize is documented to use unnamed arguments for initializing contained classes). So

setMethod(initialize, "Foo", function(.Object, ..., a=integer(), b=integer()) {
    callNextMethod(.Object, ..., model=data.frame(a, b))
})

Normally one wants to insulate the user from calling new, and will instead use a constructor Foo. Typically the constructor does whatever coercion you might have instead put in the initialize method, so the initialize method is just not specified.

Foo <- function(a=integer(), b=integer(), ...) {
    model <- data.frame(a, b)
    new("Foo", model=model, ...)
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top