不写R包的分析师不是好全栈

S4对象的应用:没有括号的函数

    R

在R语言中,所有的函数都是以括号结尾的,可不可以建立一个没有括号的函数呢?

这个问题来源于一个群友的小问题:

我想用一个字母,比如“q”来实现quit("no")的功能


如果这个方法存在,R的使用也可以变得更加方便:

输入work 加载常用的几个包

q,直接保存并退出

…..


找找灵感


如果想找一个相似的对象的话,version是个不错的例子


version

##                _
## platform x86_64-w64-mingw32
## arch x86_64
## os mingw32
## system x86_64, mingw32
## status
## major 3
## minor 1.1
## year 2014
## month 07
## day 10
## svn rev 66115
## language R
## version.string R version 3.1.1 (2014-07-10)
## nickname Sock it to Me

class(version)

## [1] "simple.list"

version 是R中默认存在的一个对象,它会打印出R内核的版本,建立时间,nickname等等~如果你注意到的话,version是一个simple.list,并不是常见的list,vector等变量.


当然上述的功能是可以实现的,具体的实现是依靠R中的S4对象来完成的,一个不错的博客可以看张丹的博客


需要做的思路如下:



  • 定义一个S4的类

  • q定义为这个类的对象

  • 定义这个S4类的方法,使得q输出的时候执行我们想要的代码




解决方法



定义一个S4的类


定义一个S4的类使用的是setClass函数,第一个参数"fruit"代表这个类的名字,slot参数定义的是这个类中各个属性的类型.


换句话说,你可以把一个S4的对象看做一个list对象,这个对象中每个元素是可以定义成你想要的类型.在这里,我随便定义四个属性,名字,价格,颜色和甜度.


fruit = setClass("fruit",
slots = c(name = "character",
price="numeric",
color="character",
sweet="logical"))



apple定义为这个类的对象


定义一个名为applefruit.其中,价格等于5,颜色是红色,而且是甜的.对于一个s4的对象,调用各个属性的方法是用@(类似dataframe是用$,还记得吧~)


apple = fruit(name = "apple",
price = 5,
color= "red",
sweet = T)
apple

## An object of class "fruit"
## Slot "name":
## [1] "apple"
##
## Slot "price":
## [1] 5
##
## Slot "color":
## [1] "red"
##
## Slot "sweet":
## [1] TRUE

apple@price

## [1] 5

apple@color

## [1] "red"

apple@sweet

## [1] TRUE



定义这个S4类的方法


以上,定义一个S4的类和一个list是没有太大区别的,都是把自己需要的对象塞到一起,然后…就没有然后了.实际上,S4对象最灵活的地方在于你可以定义这个对象的方法(method)


比如我们常见的lm对象可以使用plot,summary,predict来调用它,实际上,这些方法是定义在plot.lm,summary.lm,predict.lm里面的.



对fruit定义一个print的方法:


print.fruit = function(fruit){
if(fruit@sweet){
out = paste0(fruit@name,"’s price is ",
fruit@price,".\n",
"It’s ",fruit@color," and sweet!")
}else{
out = "It’s not a sweet fruit!!!"
}
cat(out)
}

用print来展示这个对象:


print(apple)

## apple’s price is 5.
## It’s red and sweet!

需要用到的一个方法是show,顾名思义,它是用来Show(展示)这个对象的方法.如果不定义的话,是这样的:


apple

## An object of class "fruit"
## Slot "name":
## [1] "apple"
##
## Slot "price":
## [1] 5
##
## Slot "color":
## [1] "red"
##
## Slot "sweet":
## [1] TRUE

接下来,我们想输入apple的时候自动跳出我们之前用print方法输出的结果,需要使用setMethod来实现:


setMethod("show","fruit",
print.fruit
)

## Warning: For function ‘show’, signature ‘fruit’: argument in method
## definition changed from (fruit) to (object)

## [1] "show"

定义完fruitshow方法,就改变了这个函数的展示方式


apple

## apple’s price is 5.
## It’s red and sweet!





一个字母退出R


同样的方法,给q这个对象添加一个方法:show


这个方法的最终意义就是在你输入q,按回车,自动退出R


abc = setClass("abc",
slots = c(x="numeric"))
q = abc(x = 1)

setMethod("show","abc",
function(x){
quit(‘no’)
}
)
q

这个不要乱运行!!会自动退出并不保存各位R中的结果哦~!!


运行一遍,R已关闭,各位晚安~


page PV:  ・  site PV:  ・  site UV: