Object orientation in R: S3, S4 and Reference Class

Asked

Viewed 1,065 times

13

R has, among others, three main forms of object orientation:

  • S3;
  • S4; and,
  • Reference Classes.

What are the main differences between the three methods?

And how to implement them (preferably provide a minimal and simple example with code implementing each)?

  • 2

    Some readings like OO field guide from Hadley Advanced R may help to clarify.

  • @Paulocardoso, in Portuguese Please :)

  • 2

    It seems to me a very broad question pro OS, no? Maybe a community wiki?

2 answers

8

The idea of S3 and S4 in the R is to use generic functions (which serve for different objects as parameter), but nevertheless ensure that this function will behave according to the type (=class) of the object you are sending as parameter.

For example, if you call the function summary and passes as a parameter a linear function using lm, it will return the coefficients etc. If you call this function with a data.frame, it will return a summary of the columns. For different inputs, this function(s) has different methods.

In the S3 paradigm, you create the generic function as (ex: summary) - see code below also

summary<- function (arg1, arg2,…)
    UseMethod("summary")

In general, the function UseMethod will take the first argument you sent to generic function (summary, in case), look at what is defined as your class, and dispatch accordingly. The function UseMethod() does this, searches for a name function summary.nomeDaSuaClasse, and executes it with the parameters you sent.

Advantages: I think it’s obvious Disadvantages: has no control over absurdities. You can create any object and call any class (see example code). You have to trust the programmer. Second disadvantage, S3 only looks at the class of a parameter to make the dispatch. I think there are more drawbacks, but I remember those two now.

The S4 class solves these problems. But I’ll stop there. And a little more complicated and I think the answer would be too long. I’ll summarize it this way: you use a function(setGeneric()) to create your generic function. Then you use setMethod() to create the corresponding methods, and then several other functions to define how this generic function and its methods will operate.

If you are safe and your application is relatively simple, I see no problem in using S3.

I hope it helped.

# criando um objeto (vetor com uma string)
meuObjeto <- "string"

# Veja a estrutura do seu objeto:
str(meuObjeto)

#Agora adicione mais strutura: uma classe
class(meuObjeto) <- 'minhaClasse'

# Veja a estrutura do seu objeto:
str(meuObjeto)

# Exemplos de objetos S3 (summary)
exClass_glm       <- glm(c(20:1) ~ c(1:20) )
exClass_dataframe <- data.frame(1:20)
str(exClass_glm) # a lot of structure
class(exClass_glm) # ... and two classes

# veja a diferenca: nao ha methodo para a clsse "minhaClasse", porque nao definimos nada
summary(exClass_glm)
summary(exClass_dataframe)
summary(meuObjeto)

# mas se voce define um metodo para sua classe....
summary.minhaClasse <- function (x,y,...) {
print('Hey, olha so !!')
paste('minha string e:',meuObjeto)
}
summary(meuObjeto)

# mas S3 e coracao de mae e aceita qualquer coisa, o que pode gerar erro em algum momento do codigo
x <- 3
summary(x)
class(x) <- 'glm'
summary(x)

6

I suggest reading some very enlightening texts on the question that has been asked:

Documents

Manuals of the CRAN project

  • About the very language r;
  • Introduction to the object model S4

Similar issues in the SE and OS

Browser other questions tagged

You are not signed in. Login or sign up in order to post.