From mtmorgan at fhcrc.org  Fri Sep 19 21:40:39 2008
From: mtmorgan at fhcrc.org (Martin Morgan)
Date: Fri, 19 Sep 2008 12:40:39 -0700
Subject: [Rd] Extract method for a new class
In-Reply-To: <7A2D90F7A83A7547AE23FFC56E88D4F2C4B50E@scomp0039.wurnet.nl>
	(Albart Coster's message of "Fri, 19 Sep 2008 16:59:30 +0200")
References: <mailman.17.1221818408.18628.r-devel@r-project.org>
	<7A2D90F7A83A7547AE23FFC56E88D4F2C4B50E@scomp0039.wurnet.nl>
Message-ID: <6phskrvlya0.fsf@lamprey.fhcrc.org>

"Coster, Albart" <Albart.Coster at wur.nl> writes:

> Dear list,
>
> I am trying to write a package for simulating meioses in R. We defined
> a class 'haplotype' which contains the basic units of our simulation:
>
> setClass("haplotype",representation(snp = "numeric",qtl = "list", hID
> = "numeric",phID0 = "numeric",phID1 = "numeric"), prototype = list(hID
> = 0,phID0 = NaN,phID1 = NaN))
>
> In addition, we define a class 'haploList', which is just a list of
> haplotypes:
>
> setClass("haploList",contains = "list",representation(genDist =
> "numeric",roundDec = "integer"))
>
> Most things work fine, but when subsetting a haploList object an
> object of class list is returned. I realize that I need to write a
> function for subsetting this new object, and tried to find the code
> for '[.listof' or something similar could not find it, probably due to
> a suboptimal understanding of how it is organized.
>
> My question is, how could I define a extraction function for my new
> class that uses all the existing functionality of the Extract function
> for list?

You can find out what the generic looks like

> getGeneric("[")
standardGeneric for "[" defined from package "base"

function (x, i, j, ..., drop = TRUE) 
standardGeneric("[", .Primitive("["))
<environment: 0xfc17a8>
Methods may be defined for arguments: x, i, j, drop
Use  showMethods("[")  for currently available ones.

and then write method(s) for your class:

setMethod("[",
          signature=signature(x="haploList", i="ANY", j="missing"),
          function(x, i, j, ..., drop=TRUE) {
              ## update and return x
              x at .Data <- x at .Data[i, drop=drop]
              x
          })

Note though that extending 'list' has hazards, e.g.,

> hlst <- new("haploList", list(a=1,b=2))
> names(hlst)
[1] "a" "b"
> names(hlst[2])
[1] "a"

where the names have been confused! You'll want to manage the names
yourself (as a separate slot) or make sure that they're removed
entirely when you create / update your object.

(Here's a variant that I like

setMethod("[",
          signature=signature(x="haploList", i="ANY", j="missing"),
          function(x, i, j, ..., drop=TRUE) {
              ## feed updated values to 'initialize'
              initialize(x, x at .Data[i])
          })

because the initialize call will [provided any initialize methods
defined on contained classes don't interfer] minimize copying. You'll
also likely want methods for $ and [[, and assignment methods [<-
etc.)
          
Hope that helps,

Martin

> Thanks in advance,
>
> Albart Coster ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

-- 
Martin Morgan
Computational Biology / Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N.
PO Box 19024 Seattle, WA 98109

Location: Arnold Building M2 B169
Phone: (206) 667-2793



[Rd] Extract method for a new class
Martin Morgan