Dynamic functions and R's object system

Viewed 48

I'm using R's object system to create a modify objects with a number of functions. I am not sure the best way to do it for either S3 or S4 systems, or if there's any reason to prefer one over the other.

For example:

letters <- function(a) {
  rtn <- list('a'=a)
  class(rtn) <- 'letters'
  rtn
}

b <- function(letobj, b) {
  letobj$b <<- b
}

Will get the job done. But surely this isn't the preferred way to do this in S3. And what's the equivalent in S4? And which is preferred?

1 Answers

Questons soliciting opinion based answers are off topic on SO; however, this is how the code shown in the question would normally be written using S3. The key point is that we return the object in b and then the caller can set L to the modified version.

lets <- function(a) structure(list(a = a), class = "letters")
b <- function(x, b) { x$b <- b; x}

L <- lets("A")
L <- b(L, "B")
L

giving:

$a
[1] "A"

$b
[1] "B"

attr(,"class")
[1] "letters"

or we can use a replacement function:

"b<-" <- function(x, value) { x$b <- value; x }

L <- lets("A")
b(L) <- "B"
L

Alternately don't define b() at all and just use:

L$b <- "B"

If you want to support inheritance then we need to define a generic and then the method.

b <- function(x, b, ...) UseMethod("b")  # b generic
b.letters <- function(x, b, ...) { x$b <- b; x)  # b's letters method

Now it would be possible to define additional b methods for other classes.

Related