-1

I have created an S4 class ("card") that resembles a record with several fields. Now I want to define a collection class ("cat") to hold many "card" objects. The cat class will include methods for searching, editing, and adding cards.

Here is a simplified version of what I'm trying to create:

Card <- setClass("Card", 
               representation(dsOwner = "character", dsFile = "character", dsUrl = "character"))

Cat <- setClass("Cat", representation(cardlist = "list"))

setGeneric("addcard", 
       function(catObj, owner, file, url) 
           standardGeneric("addcard"))

setMethod("addcard", 
      signature(catObj = "Cat"), 
      function(catObj, owner, file, url){
          index <- length(catObj) + 1
          catObj[[index]] <- new("Card",
                                 dsOwner = owner,
                                 dsFile = file,
                                 dsUrl = url)
          return(index)
      })

catalog <- new("Cat")

addcard(catalog, owner = "some online resource", file = "some file name", url = "http://some.url")

Unfortunately, executing the addcard method throws an error I don't understand:

Error in '[[<-'('*tmp*`, index, value = <S4 object of class "Card">) : 
[[<- defined for objects of type "S4" only for subclasses of environment'.

Did I not define the cat class correctly?

AltShift
  • 336
  • 3
  • 18
  • It's unclear why a list of these objects would not be the simple solution to this question, or for that matter why you could not define another S4-object named a 'deck' that could hols such objects. You have not created an example that allows a specific programming solution. – IRTFM Jan 25 '16 at 23:13
  • You would probably be happier with reference classes or R6 for that type of programming. – Neal Fultz Jan 26 '16 at 01:00
  • Thanks, Neal. I have had a stab at redesigning my question in light of recent progress. I think I'm too new to S4 to think about stepping up to R6 just yet, but I'll keep it in mind. – AltShift Jan 29 '16 at 00:42
  • Thanks, 42. I am now trying to use a list of objects. (That was my 1st thought, but I was unsure of syntax.) Please see my edited question. – AltShift Jan 29 '16 at 00:43

1 Answers1

1

R does not have a coherent java/C++-like container support to handle arrays, lists, sets, maps, etc (in OOP sense.)

  • R vectors/lists are in many ways similar to java lists/c++ arrays. I don't know much about speed and efficiency though, I suspect R does many more copies unlike java/c++
  • Simple set functions with vectors can be done by union, setdiff, unique etc functions. There is also library "sets" that handled very well the simple objects I throw to it.
  • named vectors (including named lists) are in many ways like a maps. The key is the name, and with some tricks you can make a string key out of any type of object. I suspect though these are not hashed, and the performance seems not to be good. You can also implement maps via environment (see Natural way to represent hash tables/dictionaries/maps in R) and data.table (Dictionaries and pairs in R)

Usually you get pretty far by using these simple measures but I would love to see a more rigorous and efficient implementation. I would happy to be wrong though :-)

Community
  • 1
  • 1
Ott Toomet
  • 1,894
  • 15
  • 25
  • Thanks, Ott. I managed to get the behaviour I wanted by making my new class inherit from "list" and just using a function -- not a method -- to add items to it. Not really OOP, I agree, but it should work as long as nobody tries to add elements directly. – AltShift Jan 31 '16 at 22:20