From my example, as(employees, "People")
more general coercion is possible; see the documentation ?setAs. From your problem description I would have opted for the solution that you now have, with two slots rather than inheritance. Inheritance has a kind of weird contract when using another package, where you're agreeing to inherit whatever generics and methods are / will be defined on the object, by any package loaded by the user; a usual benefit of object-oriented programming is better control over object type, and this contract seems to total undermine that. I actually don't know how to navigate the mysterious error; the secret is somewhere in the cbind / cbind2 documentation, but this seems quite opaque to me. Martin On 11/17/21, 8:00 PM, "Leonard Mada" <leo.m...@syonic.eu> wrote: 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.