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

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


Скачать книгу
alt="image"/> Warning – Silent setting to default

      Did you notice that R is silent about the missing balance? This is something to be careful with. If you forget that a default value has been assigned then this might lead to confusing mistakes.

       prototype()

      setClass(“CurrAcc”, representation(interest_rate = “numeric”, balance = “numeric”), contains = “Acc”, prototype(holder = NA_character_, interst_rate = NA_real_, balance = 0)) x_account <- new(“CurrAcc”, # no holder # no interest rate # no balance branch = “LDN12”, opening_date= as.Date(“2018-12-01”)) x_account # show what R did: ## An object of class “CurrAcc” ## Slot “interest_rate”: ## numeric(0) ## ## Slot “balance”: ## [1] 0 ## ## Slot “holder”: ## [1] NA ## ## Slot “branch”: ## [1] “LDN12” ## ## Slot “opening_date”: ## [1] “2018-12-01”

      image Warning – Changing class definitions at runtime

      Most programming languages implement an OO system where class definitions are created when the code is compiled and instances of classes are created at runtime. During runtime, it is not possible to change the class definitions.

      However, R is an interpreted language that is interactive and functional. The consequence is that it is possible to change class definitions at runtime (“while working in the R-terminal”). So it is possible to call setClass() again with the same object name, and R will assume that you want to change the previously defined class definition and silently override it. This can lead, for example, to the situation where different objects pretend to be of the same class, while they are not.

      image Hint – Locking a class definition

      To make sure that a previous class definition cannot be changed add sealed = TRUE to the call to setClass()

      image Hint – Typesetting conventions

       UpperCamelCase

       lowerCamelCase

       snake_case

       dot.separator

      6.3.4 Constructor functions

      Constructor functions should be given the same name as the class and it allows much more testing and action than the standard new() function.

      This is the constructor function to create a new instance of CurrAcc: .CurrAcc <- function (holder, interest_rate # branch we know from the user # balance should be 0 # opening_date is today ) { error_msg = “Invalid input while creating an account\n” if (is.atomic(holder) & !is.character(holder)) { stop(error_msg, “Invalid holder name.”) } if (!(is.atomic(interest_rate) & is.numeric(interest_rate) & (interest_rate >= ) & (interest_rate < 0.1))) { stop(error_msg, “Interest rate invalid.”) } br <- “PAR01” # pretending to find balance by looking up user dt <- as.Date(Sys.Date()) new(“CurrAcc”, holder = holder, interest_rate = interest_rate, balance=, branch = br, opening_date= dt) } # Create a new account: lisa_curr_acc <- .CurrAcc(“Lisa”, 0.01) lisa_curr_acc ## An object of class “CurrAcc” ## Slot “interest_rate”: ## [1] 0.01 ## ## Slot “balance”: ## [1] 0 ## ## Slot “holder”: ## [1] “Lisa” ## ## Slot “branch”: ## [1] “PAR01” ## ## Slot “opening_date”: ## [1] “2020-01-30”

       Sys.Date()

      image Hint – Calling the constructor function

       C++

      6.3.5 The .Data slot

      If an S4 object inherits from an S3 class or a base type, R will give it a special .Data slot that contains the data of this underlying object (S3 or base type):

      # Here is the prototype of a dataset that holds some extra # information in a structured way. setClass(“myDataFrame”, contains = “data.frame”, slots = list(MySQL_DB = “character”, MySQL_tbl = “character”, data_owner = “character” ) ) xdf <- new(“myDataFrame”, data.frame(matrix(1:9, nrow=3)), MySQL_DB = “[email protected]”, MySQL_tbl = “tbl_current_accounts”, data_owner = “customer relationship team”) xdf@.Data ## [[1]] ## [1] 1 2 3 ## ## [[2]] ## [1] 4 5 6 ## ## [[3]] ## [1] 7 8 9 xdf@data_owner ## [1] “customer relationship team”

       runif()

       setClass()

       new()

      6.3.6 Recognising Objects, Generic Functions, and Methods

      While we casually used already isS4() to check if an object is S4, there are multiple ways to find out if an object is S4:

       str() will report it as an S4 class,

       str()

       isS4() returns TRUE, note that this is not the same as is.S3(), this is the class-specific method of the function is(),

       isS4()

       pryr::otype() returns S4.

       otype()

      There aren't any S4 classes in the commonly used base packages (stats, graphics, utils, datasets, and base), so we will continue to use our previous example of the bank accounts.

      str(my_inv_acc)


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