Question

Possible Duplicate:
S4 Classes: Multiple types per slot

I am trying to make my first R package. I plan to create a S4 class "test" that contains data and some methods to process data. In my case, the processing of data can be improved by multi-threading. I have tested parLapply() and it increases performance.

The problem is that I do not want to call:

cl <- makeCluster(N)
parLapply(cl, x, FUN, ...)
stopCluster(cl)

in each method I want to make parallel. This is because it is not elegant and, I presume, the repeated creation (and destruction) of the teams of thread costs.

Therefore, I was thinking about (simply) having a cluster object within my class "test". Then I could, for instance, make a "test" object "o" and call a method of "test" setNumbrOfThreads(o) <- 4.

However, I have trouble with the implementation. Since ?makeCluster() states the return value is '''An object of class 'c("SOCKcluster", "cluster")''', I have tried :

setClass("test",
    representation(
        data = "list",
        nThreads = "numeric",
        cluster = c("SOCKcluster", "cluster") #This seems incorrect
    ),
    prototype(
        data = NULL,
        nThreads = 1,
        cluster = makeCluster(1) # "cluster = NULL" does not help
    )
) 

R complained that element 3 of the representation was not a single character string . So I tried without more success: cluster = "cluster" or cluster = "SOCKcluster" (in representation).

My question is:

How can I can I create an S4 class with a member object of class c("SOCKcluster", "cluster") ?

Thank you,

Was it helpful?

Solution

Brandon asked about putting different types of objects ('apple', 'orange') into a single slot; you're asking about using an S3 class in an S4 object. The notation c("SOCKcluster", "cluster") is S3's way of saying that SOCKcluster contains cluster as a parent class. This is a duplicate of Example of Using an S3 Class in a S4 Object, not of S4 Classes: Multiple types per slot, and with a twist -- you have a (short) S3 class hierarchy, not just a single S3 class. The solution is in the same spirit, though, with

setOldClass(c("SOCKcluster", "cluster"))
A = setClass("A", representation(cluster="SOCKcluster"))

and then

> library(parallel)
> a = A(cluster=makePSOCKcluster(2))
> a
An object of class "A"
Slot "cluster":
socket cluster with 2 nodes on host 'localhost'

Trying to put an MPI cluster (requires snow and Rmpi) into your class fails

> a = A(cluster=makeCluster(2, "MPI"))
    2 slaves are spawned successfully. 0 failed.
Error in validObject(.Object) : 
  invalid class "A" object: 1: invalid object for slot "cluster" in class "A": got class "spawnedMPIcluster", should be or extend class "SOCKcluster"
invalid class "A" object: 2: invalid object for slot "cluster" in class "A": got class "MPIcluster", should be or extend class "SOCKcluster"
invalid class "A" object: 3: invalid object for slot "cluster" in class "A": got class "cluster", should be or extend class "SOCKcluster"

Creating a class that supports cluster would require reading of ?setOldClass.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top