R语言S3类的理解与构建
R语言类
R语言的类有S3类和S4类,S3类用的比较广,创建简单粗糙但是灵活,而S4类比较精细,具有跟C++一样严格的结构。这里我们主要讲S3类。
S3类的结构
S3类内部是一个list,append某个list类名称,就能成为该类。list里面的内容就是我们所说的属性.
首先创建一个list
me <- list(seq = "ATGC", length = nchar("ATGC"))
me
$seq
[1] "ATGC"
$length
[1] 4
现在me这个list只属于list类
me
$seq
[1] "ATGC"
$length
[1] 4
attr(,"class")
[1] "list" "DNAseq"
然后我们append 一个类名"DNAseq",就这样我们创建了一个DNAseq类,类的属性有seq和length,值为ATGC和4
class(me) <- append(class(me), "DNAseq")
class(me)
[1] "list" "DNAseq"
我们可以通过普通的list的方法来获得类的属性,比如
me$seq
[1] "ATGC"
me$length
[1] 4
S3类的创建
简单直接的构建方法
依据刚才的类的结构,我们用函数进行类的构建,函数的输入是要传入进行类的初始化的值,而函数的返回就是新生成的类。这样我们就可以根据不同的初始化值进行类的实例化。
首先构造一个类
# Straight forward approach
DNAseq <- function(seq = "ATGCATGCATGCATGCATGC"){
me <- list(
seq = seq,
length = nchar(seq)
)
# Set the name for the class
class(me) <- append(class(me), "DNAseq")
return(me)
}
类的实例
seq1 <- DNAseq()
seq1
$seq
[1] "ATGCATGCATGCATGCATGC"
$length
[1] 20
attr(,"class")
[1] "list" "DNAseq"
局部环境构建类的方法
当然本质还是list,但是巧妙的利用了函数运行时的局部环境。函数运行时,内部的环境是和外界隔离的,在函数内创建的变量不会影响函数外。而这种方法巧妙的取出了这个内部环境的指针,并且将它放到了list里面。最后append类名。在环境里面存放了list的指针,而在list里面又存放了环境的指针。之所以内部环境没有消失,我猜想是因为返回的类里面具有环境的指针的引用,所以内存没有释放,是一个智能指针,当然,我没有对这深究。这次属性并不是直接存放在list里面,而是存放在函数里面的环境中。而list里面放着:方法和当前环境的指针。assign是对环境中某个变量赋值,可以用get函数中获得环境中变量的值。
# Local enviroment approach
DNASeq <- 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)
}
实例化
seq2 <- DNASeq()
seq2
$thisEnv
<environment: 0x8e86a20>
$getEnv
function ()
{
return(get("thisEnv", thisEnv))
}
<environment: 0x8e86a20>
$getseq
function ()
{
return(get("seq", thisEnv))
}
<environment: 0x8e86a20>
$reverseComplement
function ()
{
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"
获得里面的seq属性的值,这里使用get获得环境中的变量的值
get("seq", seq2$getEnv())
[1] "ATGCATGCATGCATGCATGC"
当然,如果使用这种方法生成的类,我们获得属性通常不再函数外用get,因为这样并不像面向对象的用法,我们会在给类一个方法,某个类调用这个方法之后就可以获得某个属性的值,比如可以在list中再写一个函数,getseq,就等于get("seq", thisEnv),这样就可以面向对象的使用seq2$getseq()来获得seq属性。当我们列表中添加方法时,注意应该用遵循列表的格式,用",”分开不同的方法或者不同的值。
创建方法
类中除了含有属性外,肯定还得含有方法。上面我们讲到用局部环境变量创建S3类时可以在list里面存放方法。当然还有一种比较普遍的,在两种方式创建的S3类中都能使用的创建方法的途径。使用某方法.某类来创建某类的方法。比如print.gg就是对gg类的print的方法。但是在创建这种方法之前我们首先得用这个方法的名字创建一个函数,这样运行函数时首先进入这个函数,然后在函数里面使用useMethod函数,在环境中寻找该类的该方法。虽然下面的代码比较复杂,但是重点时看UseMethod。
# Creating methods
reverseComplement <- function(object){
UseMethod("reverseComplement", object)
}
reverseComplement.default <- function(object){
print("The class of this object can not be found")
}
# Straight forward approach
#
# For S3 classes created by Straight forward approach
reverseComplement.DNAseq <- function(object){
print("Calling 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(trans_seq_vect):1]
## Collape to long character
newseq <- paste0(trans_rev_vect, collapse = "")
# Return a new DNAseq class
return(DNAseq(newseq))
}
# For S3 classed created by local enviroment approach
reverseComplement.DNASeq <- function(object){
print("Calling 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(get("seq", seq2$getEnv()), 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))
}
上面还有一个default函数,表示默认的方法,如果该类找不到该类匹配的方法,就会使用默认方法。
类继承
S3类可以使用继承,在原来类的基础上再append一个新的类名即为新的类,用NextMethod可以调用下一层类的方法。
创建一个primer类继承DNAseq类
#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] 20
attr(,"class")
[1] "list" "DNAseq" "Primer"
调用方法的时候会按照从左到右的顺序,再这个例子中,默认先调用DNAseq的方法,如果想要调用Primer类的方法,首先写一个Primer的reverseComplement方法
# Creating methods
reverseComplement.Primer <- function(object){
print("Running reverseComplement of Primer class")
}
然后在DNAseq类中调用下一类的方法,使用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] 20
attr(,"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] 20
attr(,"class")
[1] "list" "DNAseq"
R语言S3类的理解与构建的更多相关文章
- 【转】R语言知识体系概览
摘要:R语言的知识体系并非语法这么简单,如果都不了R的全貌,何谈学好R语言呢.本文将展示介绍R语言的知识体系结构,并告诉读者如何才能高效地学习R语言. 最近遇到很多的程序员都想转行到数据分析,于是就开 ...
- R语言构建蛋白质网络并实现GN算法
目录 R语言构建蛋白质网络并实现GN算法 1.蛋白质网络的构建 2.生物网络的模块发现方法 3.模块发现方法实现和图形展示 4.附录:igraph中常用函数 参考链接 R语言构建蛋白质网络并实现GN算 ...
- R语言学习笔记(二): 类与泛型函数
类 大多数R对象都是基于S3类(来源于第三代S语言),例如直方图函数hist()输出是一个包含多个组件的列表,它还有一个属性(attribute),用来指定列表的类,即histogram类. 泛型函数 ...
- R语言——实验5-聚类分析
针对课件中的例子自己实现k-means算法 调用R语言自带kmeans()对给定数据集表示的文档进行聚类. 给定数据集: a) 数据代表的是文本信息. b) 第一行代表词 ...
- 【转】基于R语言构建的电影评分预测模型
一,前提准备 1.R语言包:ggplot2包(绘图),recommenderlab包,reshape包(数据处理) 2.获取数据:大家可以在明尼苏达州大学的社会化计算研 ...
- R语言中的四类统计分布函数
R语言中提供了四类有关统计分布的函数(密度函数,累计分布函数,分位函数,随机数函数).分别在代表该分布的R函数前加上相应前缀获得(d,p,q,r).如: 1)正态分布的函数是norm,命令dnorm( ...
- 我对PageRank的理解及R语言实现
PageRank,网页排名,又称网页级别.Google左侧排名或佩奇排名,是一种由搜索引擎根据网页之间相互的超链接计算的技术,而作为网页排名的要素之一,以Google公司创办人拉里·佩奇(Larry ...
- R语言书籍的学习路线图
现在对R感兴趣的人越来越多,很多人都想快速的掌握R语言,然而,由于目前大部分高校都没有开设R语言课程,这就导致很多人不知道如何着手学习R语言. 对于初学R语言的人,最常见的方式是:遇到不会的地方,就跑 ...
- R语言 一套内容 从入门 到放弃
[怪毛匠子整理] 1.下载 wget http://mirror.bjtu.edu.cn/cran/src/base/R-3/R-3.0.1.tar.gz 2.解压: tar -zxvf R-3.0. ...
随机推荐
- adb pull 报错处理:adb: error: cannot create file/directory 'E:\': No such file or directory
adb pull /sdcard/1.txt e:/ 报错:adb: error: cannot create file/directory 'E:\': No such file or direct ...
- United States Department of Agriculture 美国农业部网站数据自动下载小脚本
帮对象写的自动点击页面的小脚本,如果有需要的可以试试,(#^.^#) https://apps.fas.usda.gov/gats/ExpressQuery1.aspx var year = '199 ...
- iView -- TimePicker 自定义修改时间选择器选择时间面板样式
iView官方组件展示效果: 期望的最终效果: 为什么要修改期望效果? 项目需要只选择小时,分钟跟秒的不需要,而官方并没有直接相关的小时组件或者是设置显示成小时或分钟或秒的时间选择器,因为自己直接修改 ...
- SQLAlchemy+Flask-RESTful使用(四)
前言 顺利出到4啦,其实学习过程中发现了不少错误,不过有些实在是没啥代表性. 最近买了两本小程序和安卓方面的书,其实从初中开始,想搞编程的目的就是写些安卓软件. 现在看来不太可能了.拿来当当兴趣爱好还 ...
- elasticsearch的CPU居高不下的问题
最近项目中遇到一个令人头疼的问题,毕竟因为工作需要刚学elasticsearch,也没有去关注elasticsearch的配置问题,安装好默认把它当做数据库一样去使用,这导致接下来的项目直接挂掉... ...
- layUI 实现自定义弹窗
需求描述:点击表格中的数据,弹出一张具体信息表.描述的不是很清楚,放效果图,就明白了,上图 放心,能看到的数据,都不是生产数据,我造的假数据,但是功能效果就是这样,点击列表中的一行,弹出某些要展示的信 ...
- clearTimeout方法在IE上的兼容问题
今天在修改公司项目的bug时发现一个问题,出错代码如下: clearTimeout(); setTimeout(function(){ // 具体业务逻辑 },100); 这段代码在chrome.fi ...
- @angular/cli (angular脚手架) 如何降级
1.卸载 npm uninstall -g @angular/cli 2.清除缓存 npm cache verify 3.查看是否卸载成功 ng v //如果显示ng 不是内部或外部的指令 则证明卸载 ...
- Linux基础-远程管理
shutdown 选项 时间 关机/重新启动 -r 重新启动 不指定选项和参数,1分钟后关闭电脑 重启必须加-r 示例: shutdown -r now now表示现在 shut ...
- centos 配置.Net core 环境并部署dotnet Core文件
一.配置环境[Microsoft dotnet Core] 1) Add the dotnet product feed sudo rpm -Uvh https://packages.microsof ...