Skip to content

Object-oriented programming in R

3 messages · Luc Villandre, Mark Wardle, Gabor Grothendieck

#
Dear R-users,

I have very recently started learning about object-oriented programming 
in R. I am far from being an expert in programming, although I do have 
an elementary C++ background.

Please take a look at these lines of code.
My understanding is that the object p.plot belongs to the "ggplot" 
class. However, a new class definition like
yields the warning
The ggplot object is also a list :
So, I guess I could identify mSecond as being a list.

However, I don't understand why "ggplot" is not considered a valid slot 
type. I thought setClass() was analogous to the class declaration in 
C++, but I guess I might be wrong. Would anyone care to provide 
additional explanations about this?

I decided to explore object-oriented programming in R so that I could 
organize the output from my analysis in a more rigorous fashion and then 
define custom methods that would yield relevant output. However, I'm 
starting to wonder if this aspect is not better suited for package 
builders. R lists are already very powerful and convenient templates. 
Although it wouldn't be as elegant, I could define functions that would 
take lists outputted by the different steps of my analysis and do what I 
want with them. I'm wondering what the merits of both approaches in the 
context of R would be. If anyone has any thoughts about this, I'd be 
most glad to read them.

Cheers,
#
Hi. I remember considering these options myself but concluded that for
most analyses a strictly procedural approach was satisfactory.
Although I may re-run multiple analyses, the data manipulation (and
subsequent analysis - the former always more complex than the latter
IMHO) is fairly project- and data-specific. As such, quick and
specific code always seemed more appropriate than slow (to write) and
generic.

Obviously that doesn't apply to package creators and maintainers,
creating something that is going to re-used in many different projects
and can be made generic. That's the heuristic I now use - is this good
enough for other people's consumption - if so, create a package and
adopt some of the OO approaches seen in the base R packages.
Otherwise, stick to bespoke and specific (procedural) functions.

I've a small library of helper functions, but these don't use OO
usually. They sometimes make assumptions about data passed in, don't
have particularly robust error checking, but in general, work well. I
suppose it depends on what you're trying to achieve and how much time
you've got!

Interested in other's thoughts too as clearly there's no "right answer" here.

bw

Mark

2009/5/27 Luc Villandre <villandl at dms.umontreal.ca>:

  
    
#
p.plot is an S3 object and you are attempting to define an S4 class
so you if you really want to do that then you would need this to let
S4 know about the ggplot class:

# S4 class with S3 slot
setClass("ggplot") # make ggplot visible to S4
 setClass("AClass", representation(mFirst = "numeric", mSecond = "ggplot"))
a <- new("AClass", mFirst = 1, mSecond = p.plot)

Probably you don't want to use S4 at all here but rather
define an S3 subclass, "A" of the "ggplot" class and
give it an attribute also called "A".

# S3 subclass
AClass <- function(mFirst, mSecond) {
   attr(mSecond, "A") <- mFirst
   class(mSecond) <- c("A", setdiff(class(mSecond), "A"))
   mSecond
}
a2 <- AClass(1, p.plot)

or alternately represent A as an S3 list holding with the two objects
as components:

# S3 class but not subclass
AClass2 <- function(mfirst, mSecond) {
    out <- list(mFirst = mFirst, mSecond = mSecond)
    class(out) <- "A"
    out
}
a3 <- AClass2(1, p.plot)

Also note that

1. ggplot uses S3 at the user level but uses the "proto"
package internally.  Depending on what you want to do using proto
objects might be preferable.  See home page at
http://r-proto.googlecode.com

2. R statements do not normally end in a semicolon.

On Wed, May 27, 2009 at 12:00 PM, Luc Villandre
<villandl at dms.umontreal.ca> wrote: