From mtmorgan at fhcrc.org  Sat Nov 25 08:46:55 2006
From: mtmorgan at fhcrc.org (Martin Morgan)
Date: Fri, 24 Nov 2006 23:46:55 -0800
Subject: [Rd] Missing values for S4 slots [One Solution]
In-Reply-To: <20061124211854.GH4431@wheat.betterworld.us> (Ross Boylan's
	message of "Fri, 24 Nov 2006 13:18:55 -0800")
References: <20061124192314.GA16006@wheat.betterworld.us>
	<20061124211854.GH4431@wheat.betterworld.us>
Message-ID: <6phd57cge8g.fsf@gopher4.fhcrc.org>

Ross Boylan <ross at biostat.ucsf.edu> writes:

> On Fri, Nov 24, 2006 at 11:23:14AM -0800, Ross Boylan wrote:
>> Using R 2.4, the following fails:
>> setClass("testc", representation(a="ANY"))
>> makeC <- function(myarg) new("testc", a=myarg)
>> makeC()
>> -> Error in initialize(value, ...) : argument "myarg" is missing,
>>    with no default

The following might offer one paradigm:

makeC <- function(myarg) {
    new("testc",
        a=if (missing(myarg)) character(0) else myarg)
    }

A couple of things that come to mind, though: 'ANY' kind of defeats
the purpose of having a class with well-defined slots (I realize this
is a 'toy' example); presenting myarg without a default makes it
obscure to the user what the default value might be, or that a default
value will be used; if 'myarg' is an appropriately descriptive
argument for the user, then perhaps it is also appropriately
descriptive for the slot. Thus:

setClass("testc",
         representation(myarg="character"))

makeC <- function(myarg=character(0)) new("testc", myarg=myarg)

> ....
>> 
>> I suspect there's something I could do to get the constructor
>> arguments, modify the list (i.e., delete args that were missing and
>> insert new ones), and do.call(new, myArgList).  Not only am I unsure
>> how to do that (or if it would work), I'm hoping there's a better way.
>
> I didn't find a way to get all the arguments easily(*), but manually

as.list(match.call()[-1]) might help

> constructing the list works.  Here are fragments of the code:
>
> mspathCoefficients <- function(
>                    aMatrix,
>                    params,
>                    offset=0,
>                    baseConstrVec, 
>                    covLabels # other args omitted
>                    ) {
>   # innerArgs are used with do.call("new, innerArgs)
>   innerArgs <- list(
>                     Class = "mspathCoefficients",
>                     aMatrix = aMatrix,
>                     baseConstrVec = as.integer(baseConstrVec),
>                     params = params
>                     )
>
> # the next block inserts the covLabels argument
> # only if it is non-missing
>   if (missing(covLabels)) {
>     # ....
>   } else {
>     innerArgs$covLabels <- covLabels
>   }
> #...
>   map <- list() 
> # fill in the map
> # add it to the arguments
>   innerArgs$map <- map
>   do.call("new", innerArgs)
> }
>
> This calls new("mspathCoefficients", ...) with just the non-missing
> arguments.  The constructed object has appropriately "missing" values
> in the slots (e.g., character(0) given a slot of type "character").
>
>
> (*) Inside the function, arg <- list(...) will capture the unnamed
> arguments, but I don't have any.  as.list(sys.frame(sys.nframe()) is
> closer to what I was looking for, though all the values are promises.
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

-- 
Martin T. Morgan
Bioconductor / Computational Biology
http://bioconductor.org



[Rd] Missing values for S4 slots [One Solution]
Martin Morgan