The Big R-Book. Philippe J. S. De Brouwer

The Big R-Book - Philippe J. S. De Brouwer


Скачать книгу
are removed to ensure that positional matching is always used.+, -, *, /, ∧, \%\%, \%/\%&, |, !==, !=, <, <=, >=, >

      3 Group Summary: Members of this group dispatch on the first argument supplied.all, anysum, prodmin, maxrange

      4 Group complex: Members of this group dispatch on z.Arg, Conj, Im, Mod, Re

      Of course, a method defined for an individual member of the group takes precedence over a method defined for the group as a whole, because it is more specific.

      image Note – Distinguish groups and functions

      Math, Ops, Summary, and Complex aren't functions themselves, but instead represent groups of functions. Also note that inside a group generic function a special variable .Generic provides the actual generic function that is called.

      If you have complex class hierarchies, it is sometimes useful to call the parent method. This parent method is the method that would have been called if the object-specific one does not exist. For example, if the object is savings_account, which is a child of account then calling the function with savings_account will return the method associated to account if there is no specific method and it will call the specific method if it exists.

      image Hint – Find what is the next method

      More information can be found using ?NextMethod.

      In S4

      1 classes have formal definitions that describe their data fields and inheritance structures (parent classes);

      2 method dispatch is more flexible and can be based on multiple arguments to a generic function, not just one; and

      3 there is a special operator, @, for extracting fields from an S4 object.

      All the S4 related code is stored in the methods package.

      image Hint – Loading the library methods

      While the methods package is always available when running R interactively (like in RStudio or in the R terminal), it is not necessarily loaded when running R in batch mode. So, you might want to include an explicit library(methods) statement in your code when using S4.

      6.3.1 Creating S4 Objects

      While an S3 object can be used without defining it first, to create a valid S4 object, we need at least:

       Name: An alpha-numeric string that identifies the class

       Representation: A list of slots (or attributes), giving their names and classes. For example, a person class might be represented by a character name and a numeric age, as follows: representation(name = “character”, age = “numeric”)

       Inheritance: A character vector of classes that it inherits from, or in S4 terminology, contains. Note that S4 supports multiple inheritance, but this should be used with extreme caution as it makes method lookup extremely complicated.

      S4 objects are created with the function setClass().

       setClass()

      # Create the object type Acc to hold bank-accounts: setClass(“Acc”, representation(holder = “character”, branch = “character”, opening_date = “Date”)) # Create the object type Bnk (bank): setClass(“Bnk”, representation(name = “character”, phone = “numeric”)) # Define current account as a child of Acc: setClass(“CurrAcc”, representation(interest_rate = “numeric”, balance = “numeric”), contains = “Acc”) # Define investment account as a child of Acc setClass(“InvAcc”, representation(custodian = “Bnk”), contains = “Acc”)

       new()

      image Note – Difference between inheritance and methods

      Note the difference in syntax – for the function setClass – between how the argument representation and the argument contains take values. The representation cand we can create a firstode> argument takes a function and hence, more arguments can be passed by adding them comma separated. In order to passmore than one parent class to contains, one needs to provide a character vector (for example c(“InvAcc”,“Acc”)).

      Both the arguments slots and contains will readily use S4 classes and the implicit class of a base type. In order to use S3 classes, one needs first to register them with setOldClass(). If we do not want type control when an instance of a class is generated, we can provide to the slots argument a special class “ANY” (this tell R not to restrict the input).

      You might not have noticed right away, but we started off with a complex problem where some objects depend on others (in OO we speak about “parents” and “children”) and even where some objects take others as attributes. Those two things are very different and a little tricky to understand.

      At this point, the classes Bnk and Acc exist and we can create a first instance for both.

      # Create an instance of Bnk: my_cust_bank <- new(“Bnk”, name = “HSBC”, phone = 123456789) # Create an instance of Acc: my_acc <- new(“Acc”, holder = “Philippe”, branch = “BXL12”, opening_date = as.Date(“2018-10-02”))

      6.3.2 Using S4 Objects

      Now, we have two S4 objects and we can use them in our code as necessary. For example, we can change the phone number.

      # Check if it is really an S4 object: isS4(my_cust_bank) ## [1] TRUE # Change the phone number and check: my_cust_bank@phone = 987654321 # change the phone number print(my_cust_bank@phone) # check if it changed ## [1] 987654321

      image Note – Compare addressing slots in S4 and S3

      There is also a specific function to get attributes froman object: attr(). This function allows to create attributes, change them or even remove them (by setting them to NULL)

       attr()


Скачать книгу