[R] How to create a proper S4 class?

Martin Morgan mtmorg@n@b|oc @end|ng |rom gm@||@com
Wed Nov 17 16:48:45 CET 2021

Hi Leonard --

Remember that a class can have 'has a' and 'is a' relationships. For instance, a People class might HAVE slots name and age

.People <- setClass(
    slots = c(name = "character", age = "numeric")

while an Employees class might be described as an 'is a' relationship -- all employeeds are people -- while also having slots like years_of_employment and job_title

.Employees <- setClass(
    contains = "People",
    slots = c(years_of_employment = "numeric", job_title = "character")

I've used .People and .Employees to capture the return value of setClass(), and these can be used as constructors

people <- .People(
   name = c("Simon", "Andre"),
   age = c(30, 60)

employees = .Employees(
    people, # unnamed arguments are class(es) contained in 'Employees'
    years_of_employment = c(3, 30),
    job_title = c("hard worker", "manager")

I would not suggest using attributes in addition to slots. Rather, embrace the paradigm and represent attributes as additional slots. In practice it is often helpful to write a constructor function that might transform between formats useful for users to formats useful for programming, and that can be easily documented.

Employees <-
    function(name, age, years_of_employment, job_title)
    ## implement sanity checks here, or in validity methods
    people <- .People(name = name, age = age)
    .Employees(people, years_of_employment = years_of_employment, job_title = job_title)

plot() and lines() are both S3 generics, and the rules for S3 generics using S4 objects are described in the help page ?Methods_for_S3. Likely you will want to implement a show() method; show() is an S4 method, so see ?Methods_Details. Typically this should use accessors rather than relying on direct slot access, e.g.,

person_names <- function(x) x using name
employee_names <- person_names

The next method implemented is often the [ (single bracket subset) function; this is relatively complicated to get right, but worth exploring.

I hope that gets you a little further along the road.

Martin Morgan

On 11/16/21, 11:34 PM, "R-help on behalf of Leonard Mada via R-help" <r-help-bounces using r-project.org on behalf of r-help using r-project.org> wrote:

    Dear List-Members,

    I want to create an S4 class with 2 data slots, as well as a plot and a 
    line method.

    Unfortunately I lack any experience with S4 classes. I have put together 
    some working code - but I presume that it is not the best way to do it. 
    The actual code is also available on Github (see below).

    1.) S4 class
    - should contain 2 data slots:
    Slot 1: the agents:
      = agentMatrix class (defined externally, NetlogoR S4 class);
    Slot 2: the path traveled by the agents:
       = a data frame: (x, y, id);
      - my current code: defines only the agents ("t");
    setClass("agentsWithPath", contains = c(t="agentMatrix"));

    1.b.) Attribute with colors specific for each agent
    - should be probably an attribute attached to the agentMatrix and not a 
    proper data slot;
    - it is currently an attribute on the path data.frame, but I will 
    probably change this once I get the S4 class properly implemented;
    - the agentMatrix does NOT store the colors (which are stored in another 
    class - but it is useful to have this information available with the 

    2.) plot & line methods for this class

    I somehow got stuck with the S4 class definition. Though it may be a 
    good opportunity to learn about S4 classes (and it is probably better 
    suited as an S4 class than polynomials).

    The GitHub code draws the agents, but was somehow hacked together. For 
    anyone interested:


    Many thanks,


    R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
    PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
    and provide commented, minimal, self-contained, reproducible code.

More information about the R-help mailing list