Search code examples
rcollectionsr-s4

Does R support collections in S4?


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?


Solution

  • 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 :-)