Dear Martin,

thank you very much for the guidance.


Ultimately, I got it running. But, for mysterious reasons, it was challenging:

- I skipped for now the inheritance (and used 2 explicit non-inherited slots): this is still unresolved; [*]

- the code is definitely cleaner;


[*] Mysterious errors, like:

"Error in cbind(deparse.level, ...) :
  cbind for agentMatrix is only defined for 2 agentMatrices"


One last question pops up:

If B inherits from A, how can I down-cast back to A?

b = new("B", someA);

??? as.A(b) ???

Is there a direct method?

I could not explore this, as I am still struggling with the inheritance. The information may be useful, though: it helps in deciding the design of the data-structures. [Actually, all base-methods should work natively as well - but to have a solution in any case.]


Sincerely,


Leonard


On 11/17/2021 5:48 PM, Martin Morgan wrote:
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(
     "People",
     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(
     "Employees",
     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@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-boun...@r-project.org on behalf of r-help@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;
     Note:
     - 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
     agents);

     2.) plot & line methods for this class
     plot.agentsWithPath;
     lines.agentsWithPath;


     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:

     https://github.com/discoleo/R/blob/master/Stat/ABM.Models.Particles.R


     Many thanks,


     Leonard

     ______________________________________________
     R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
     https://stat.ethz.ch/mailman/listinfo/r-help
     PLEASE do read the posting guide 
http://www.R-project.org/posting-guide.html
     and provide commented, minimal, self-contained, reproducible code.

______________________________________________
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to