Builder and inheritance in R

Asked

Viewed 408 times

7

It is a theoretical question, but it may help to understand a little the logic of programming in r.

  • What it is and how it works builder in the language r? What is its use?

  • What it is and how it works inheritance in the language r? How to identify the inheritance of an object and what is the use of knowing its inheritance?

2 answers

8


First, I think this question has been left unanswered so far because these concepts are little (not to say "nothing") important to become a good developer in R (unlike other languages).

In my answer I will explain a little bit the main structures and types of data in R and I believe this will help you to better understand the language.

In R, the basic data structure is the vector (I’m using the name in English to avoid confusion). vectors can be:

  • atomic - are the normal vectors we know, with only one guy.
  • lists - are the R lists, which may be heterogeneous.

Vectors have 3 important properties:

  • Have a method length - I mean, we can always call length(vetor).
  • They have a type, identified by the function typeof. the guys can be inteiro, double, character or list (in addition to special types for functions such as closure or builtin).
  • Can have attributes - use the function attributes to obtain them.

The vast majority of objects in R are created from combinations of vectors and its attributes.


Examples

A matrix in R is nothing more than an atomic vector with the attribute dim filled:

> x <- matrix(1:10, ncol = 2)
> y <- 1:10
> attr(y, "dim") <- c(5, 2)
> 
> identical(x, y)
[1] TRUE

A data.frame is a list where all elements need to have the same length, the attribute class is data.frame and has an attribute row.names:

> x <- data.frame(a = 1:5, b = 1:5)
> y <- list(a = 1:5, b = 1:5)
> attr(y, "class") <- "data.frame"
> attr(y, "row.names") <- 1:5
> 
> identical(x, y)
[1] TRUE

Even the object result of a lm in R is a list, with other attributes filled in. For example, the class is lm:

> mod <- lm(mpg ~cyl, data = mtcars)
> typeof(mod)
[1] "list"
> attributes(mod)
$names
 [1] "coefficients"  "residuals"     "effects"       "rank"          "fitted.values" "assign"        "qr"           
 [8] "df.residual"   "xlevels"       "call"          "terms"         "model"        

$class
[1] "lm"

Completion

Almost all R objects are combinations of vectors + its attributes.


Object orientation in R

In R there are at least 4 ways to create object-oriented codes. To better understand the heritage between classes and etc., it is worth reading that chapter of the book Advanced R.

  • 1

    Pretty cool the answer, but... didn’t answer the original question!

  • 1

    I believe that by the answer it is possible to understand well what is a class in the R, with this it is possible to create them and understand heritages without any problem.

  • 1

    Just by entering the external link, is not in the answer actually! ;-)

  • it was not clear that a class is an object of the R + an attribute class? and that to identify the type of the object or use the typeof? anyway... the O part is missing, but I don’t think that’s what was asked either. I don’t have time to write much more, but if you are willing to complete the answer I will be happy to vote +1 :)

  • 1

    I never used and I don’t know anything about R, so I thought it was cool and interesting your answer, because it gave a brush stroke on some concepts of language. I only made that comment about not having answered because the main questions were: What constructors and how they function and inheritance in the R language?, and you didn’t say anything about builders or inheritance in the R in the answer. Just this, don’t get me wrong. :-)

  • ok! I’m not taking this the wrong way! I’m trying to understand what you think is missing? if I had answered only how to create a class S3 the answer would be complete? In R there is not only one form of OO, so my choice to explain how everything works instead of writing an extensive answer about each of the OO systems. perhaps not the best way to explain. but your comment without any other addendum is superficial and does not help to improve at all the answer.

Show 1 more comment

5

The has at least 4 object guidance systems (OO): S3, S4, Reference Classes (also known as R5 or RC) and R6. The latter system is not part of the , but has been widely used by the community. The R6 comes from a bundle by the same name.

But watch out!!! You must even use oo on r?

It is not a question of defending this or that programming paradigm. It turns out that "R is a Functional Programming language; embrace it, don’t Fight it"1.

That is, if you really want to "understand a little the logic of programming in R", you should start to address the problems in a more functional way. When your problem demands, abandon the pattern of and use object orientation.

See, the system S3 is an object orientation system subordinated to functional programming logic, as its objective is to dispatch the object correctly to the appropriate function (method).

Back to the answer

Already exists a question about the difference between the native systems of the . I’m going to focus on the answer about constructor and systems heritage S3 and R6 since they are the most used.

builders

S3

In the S3 there is no formal definition of the class. Any object can be "transformed" into the desired class.

x <- "lala"
class(x) <- "lm"
print(x)
# Error: $ operator is invalid for atomic vectors

To create, or instantiate, a class simply add the class to the object, as in the example above, or add it through the function structure(). Good practice, however, is to create a constructor to create objects of that class.

pergunta <- function(x) {
  structure(x, class = c("pergunta", class(x)))
}

p1 <- pergunta("Acabei de criar uma classe?")
p1
# [1] "Acabei de criar uma classe?"
# attr(,"class")
# [1] "pergunta"  "character"

R6

In the R6 you first need to formally define the class. This is where a constructor is defined (item initialize in public).

library(R6)
Pergunta<- R6Class(
  "Pergunta",
  public = list(
    initialize = function(pergunta) {
      self$pergunta <- pergunta
      self$responder()
    },
    pergunta = NULL,
    responder = function() {
      print(sample(c("Sim!", "Não!"), 1))
    }
  )
)

To then be able to instantiate it (which is when the constructor is "activated")

set.seed(1)
P1 <- Pergunta$new("Acabei de criar uma classe?")
# [1] "Sim!"

On the usefulness of builders in the R: is the same as in any other language in which OO is used, but this paradigm has restricted use in R, as commented by Daniel.

inheritance

S3

Inheritance in the method S3 works by adding classes in front of the "mother class". This is because the way to dispatch the object to the methods goes through the class vector until finding a method for that function.

class(dplyr::starwars)
# [1] "tbl_df"     "tbl"        "data.frame"

Thus, the tibbles can work both for own methods (case of print()), which are preferred, as for methods of the data.frame (case of summary()). That’s also why, even though we haven’t defined a method for printing our class, the R turned. When no method is found, the object is played to the "default method" (nome_da_funcao.default())

R6

In the case of R6, the function defining the class has an argument to identify the inheritance (inherit). Note the fact that class itself should be passed as an object, not just its name.

PerguntaRetorica <- R6Class(
  "PerguntaRetorica", 
  inherit = Pergunta,
  public = list(responder = function() print("!?!"))
)

After the class has been defined, we can instantiate it.

retorica <- PerguntaRetorica$new("Ser ou não ser?")
[1] "!?!"

The importance of knowing the ancestry of a given object is knowing how it will behave with methods. And the way to do it is to pass the object to class().

class(retorica)
[1] "PerguntaRetorica" "Pergunta" "R6" 

Here we see that our daughter-class is heir to Pergunta which in turn descended from R6

References

1: The Tidy tools manifesto

2: Advanced R - Object oriented Programming

Browser other questions tagged

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