R language Class
The class of R language has S3 class and S4 class, S3 class is widely used, the creation is simple and rough but flexible, and S4 class is more fine, with the same strict structure as C + +. Here we mainly talk about the S3 class.
Structure of the S3 class
Inside the S3 class is a list,append a list class name that can be the class. The contents of the list are what we call attributes.
First create a list
me <- list(seq = "ATGC", length = nchar("ATGC"))me$seq[1] "ATGC"$length[1] 4
Now me this list belongs to list class only
me$seq[1] "ATGC"$length[1] 4attr(,"class")[1] "list" "DNAseq"
Then we append a class name "Dnaseq", so we created a dnaseq class with a seq and length property, a value of ATGC and 4
class(me) <- append(class(me), "DNAseq")class(me)[1] "list" "DNAseq"
We can get the properties of the class by using the normal list method, for example
me$seq[1] "ATGC"me$length[1] 4
A simple and straightforward construction method for S3 class creation
Based on the structure of the class just now, we use the function to construct the class, and the input of the function is to pass in the initialized value of the class, and the return of the function is the newly generated class. This allows us to instantiate classes based on different initialization values.
First construct a class
# Straight forward approachDNAseq <- function(seq = "ATGCATGCATGCATGCATGC"){ me <- list( seq = seq, length = nchar(seq) ) # Set the name for the class class(me) <- append(class(me), "DNAseq") return(me)}
Instances of the class
seq1 <- DNAseq()seq1$seq[1] "ATGCATGCATGCATGCATGC"$length[1] 20attr(,"class")[1] "list" "DNAseq"
A method of building a class in local environment
Of course, the essence is the list, but it skillfully utilizes the local environment when the function is running. While the function is running, the internal environment is isolated from the outside world, and variables created within the function do not affect the function. This method cleverly takes out the pointer to the internal environment and puts it in the list. The last append class name. The pointer to the list is stored in the environment, and the pointer to the environment is stored in the list. The internal environment does not disappear, I guess because the returned class has a reference to the environment pointer, so memory is not released, is a smart pointer, of course, I did not delve into this. This property is not stored directly in the list, but in the context of the function. And the list contains: methods and pointers to the current environment. Assign is the assignment of a variable in the environment, you can use the Get function to get the value of the variable in the environment.
# Local enviroment approachDNASeq <- function(seq = "ATGCATGCATGCATGCATGC"){ ## Get the enviroment for this thisEnv <- environment() seq <- seq length <- nchar(seq) ## Create the list used to represent the ## object for this class me <- list( ## Define the enviroment where this list is defined so ## that I can refer to it thisEnv = thisEnv, ## Method to refer to the current enviroment getEnv = function(){ return(get("thisEnv", thisEnv)) } ) ## Define the value of list within the ## current enviroment assign("this", me, envir = thisEnv) ##Set the name for the class class(me) <- append(class(me), "DNASeq") return(me)}
Instantiation of
seq2 <- DNASeq()seq2$thisEnv<environment: 0x8e86a20>$getEnvfunction () { return(get("thisEnv", thisEnv))}<environment: 0x8e86a20>$getseqfunction () { return(get("seq", thisEnv))}<environment: 0x8e86a20>$reverseComplementfunction () { print("Calling the reverseComplement function of DNASeq class") to_base <- c("A", "T", "G", "C") names(to_base) <- c("T", "A", "C", "G") trans_seq_vect <- to_base[unlist(strsplit(get("seq", thisEnv), split = ""))] trans_rev_vect <- trans_seq_vect[length(trans_seq_vect):1] newseq <- paste0(trans_rev_vect, collapse = "") return(DNASeq(newseq))}<environment: 0x8e86a20>attr(,"class")[1] "list" "DNASeq"
Get the value of the Seq property inside, where you get the value of the variable in the environment using get
get("seq", seq2$getEnv())[1] "ATGCATGCATGCATGCATGC"
Of course, if you use this method to generate the class, we get the property is usually no longer the function of external get, because it is not like object-oriented usage, we will give the Class A method, a class call this method can get the value of a property, such as can be in the list to write a function, GETSEQ, is equal to get ("seq", thisenv), so you can use object-oriented seq2$getseq () to get the Seq property. When adding a method to our list, be aware that you should use "," to separate different methods or different values in the format of the following list.
Create a method
The class must contain a method in addition to the attribute. We can store the method in the list when we create the S3 class with local environment variables. There is, of course, a common way to create methods that can be used in S3 classes created in both ways. Use a method. A class to create a method of a class. For example, Print.gg is the method of print for GG. But before we create this method, we first have to create a function with the name of the method, so that when the function is run, it is first entered into the function, and then the Usemethod function is used inside the function to find the method of the class in the environment. Although the code below is more complex, the focus is on Usemethod.
# Creating Methodsreversecomplement <-Function (object) {Usemethod ("reversecomplement", Object)} Reversecomplement.default <-Function (object) {print ("The class of this object can is found")}# straight forward a pproach## for S3 classes created by straight forward approachreversecomplement.dnaseq <-function (object) {print (' Call ing the reversecomplement function of Dnaseq class ") # # Compelement According to the vector below To_base <-C (" A "," T "," G "," C ") names (To_base) <-C (" T "," A "," C "," G ") # # Transform long charactor to vector and complement trans_seq _vect <-to_base[unlist (Strsplit (object$seq, split = "")] # # Reverse trans_rev_vect <-Trans_seq_vect[length (Tran S_seq_vect): 1] # # Collape to Long character Newseq <-paste0 (trans_rev_vect, collapse = "") # Return a new DNASEQ cl Return (DNASEQ (NEWSEQ))}# for S3 classed created by local enviroment approachreversecomplement.dnaseq <-function (o Bject) {print ("calling the ReversecomplementFunction of Dnaseq class ") # # Compelement According to the vector below To_base <-C (" A "," T "," G "," C ") names (To_ba SE) <-C ("T", "A", "C", "G") # # Transform long charactor to vector and complement Trans_seq_vect <-to_base[unlist (Strsplit (Get ("seq", Seq2$getenv ()), split = "")] # # Reverse Trans_rev_vect <-trans_seq_vect[length (trans_seq_vect): 1] # # Collape to Long character Newseq <-past E0 (trans_rev_vect, collapse = "") # Return a new Dnaseq class Return (Dnaseq (NEWSEQ))}
There is also a default function, which means that if the class cannot find a method that matches the class, the default method is used.
Class inheritance
The S3 class can use inheritance to append a new class name on the basis of the original class, which is the new class, using Nextmethod to invoke the method of the next layer class.
Create a primer class to inherit the Dnaseq class
#inheritance Primer <- function(seq = "ATGCATGCATGCATGCATGCGGCC"){ pr <- strtrim(seq, 20) me <- DNAseq(pr) class(me) <- append(class(me), "Primer") return(me)}Primer1 <- Primer()Primer1$seq[1] "ATGCATGCATGCATGCATGC"$length[1] 20attr(,"class")[1] "list" "DNAseq" "Primer"
The method is called from left to right, then in this example, the default method is called Dnaseq, if you want to call the Primer class method, first write a primer reversecomplement method
# Creating methods reverseComplement.Primer <- function(object){ print("Running reverseComplement of Primer class")}
Then in the Dnaseq class, call the next class of methods, using the Nextmethod
reverseComplement.DNAseq <- function(object){ print("Calling the reverseComplement function of DNAseq class") NextMethod("reverseComplement", object) ## Compelement according to the vector below to_base <- c("A", "T", "G", "C") names(to_base) <- c("T", "A", "C", "G") ## Transform long charactor to vector and complement trans_seq_vect <- to_base[unlist(strsplit(object$seq, split = ""))] ## Reverse trans_rev_vect <- trans_seq_vect[length(trans_seq_vect):1] ## Collape to long character newseq <- paste0(trans_rev_vect, collapse = "") # Return a new DNAseq class return(DNAseq(newseq))}
reverseComplement(Primer1)[1] "Calling the reverseComplement function of DNAseq class"[1] "Running reverseComplement of Primer class"$seq[1] "GCATGCATGCATGCATGCAT"$length[1] 20attr(,"class")[1] "list" "DNAseq"
reverseComplement(seq1)[1] "Calling the reverseComplement function of DNAseq class"[1] "The class of this object can not be found"$seq[1] "GCATGCATGCATGCATGCAT"$length[1] 20attr(,"class")[1] "list" "DNAseq"
The comprehension and construction of R language S3 class