R 语言中的S3系统(笔记)

本文通过构建老虎机程序,深入浅出地介绍了R语言S3系统的运作原理,包括泛型函数、方法分派及类属性识别等内容。

**R的S3系统:由泛型函数,方法和基于类的分派方式所构成的系统就是R的S3系统。
通俗来说,当用R中固有函数时,会调用Usemethod函数来识别对象的类属性,根据类属性的不同,选择对应的方法,调整程序的输出格式。
eg:
当运行print函数时,UseMethod检查所输入的print函数的第一个参数类型属性,再将待输出的对象交给一个新的函数来处理,这个新函数专门用于处理具有某种类属性的输入对象。
for example:
当向print提供一个类属性为POSIXct的对象时,Usemethod会将print函数的所有参数交给print.POSIXct函数处理,R随后会运行print.POSIXct函数并返回针对POSIXct类属性的输出结果。
老虎机:**

get_symbols<-function(symbols){
  wheel<-c("DD","7","B","BB","BBB","0","C")
  sample(wheel,size=3,replace=TRUE,prob=c(0.03,0.03,0.06,0.1,0.25,0.01,0.52))
}
score<-function(symbols){
  same<-symbols[1]==symbols[2]&&symbols[2]==symbols[3]
  bars<-symbols %in% c("B","BB","BBB")
  if(same){
    payout<-c("DD"=100,"7"=80,"BBB"=40,"BB"=25,"B"=10,"C"=10,"0"=0)
    price<-unname(payout[symbols[1]])
    }
  else if(all(bars)){
    price<-5
  }
  else {
    cherries<-sum(symbols=="C")
  price<-c(0,2,5)[cherries+1]
  }
  diamonds<-sum(symbols=="DD")
  price*2^diamonds
}
play<-function(){
  symbols<-get_symbols()
  print(symbols)
  score(symbols)
}
play()
[1] "BB"  "C"   "BBB"
[1] 0

将结果用一种更为美观的方式显示出来:
先改写play函数:

 play<-function(){
+     symbols<-get_symbols()
+     price<-score(symbols)
+     attr(price,"symbols")<-symbols  ###将symbols属性赋给变量,对属性赋值。
+     price
+ }
> play()
[1] 0
attr(,"symbols")
[1] "0" "C" "B"

再将结果美化,去掉双引号,将结果重新排序:

slot_display<-function(price){
 #提取符号输出结果
symbols<-attr(price,"symbols")
 #将所有的符号压缩为一个字符串 
symbols<-paste(symbols,collapse=" ")
 #用正则表达式将符号与奖金信息组合起来
 #在正则表达式中\n表示另起一个新行(相当于按下回车键)
 string<-paste(symbols,price,sep="\n$")
  #在控制台上显示正则表达式的结果,但是去掉其中的引号
  cat(string)
  }
  one_play<-play()
  slot_display(one_play)
  ## C DD BB
  ##$0

总述:
paste 函数将symbols中的三个字符压缩成了一个字符串。paste函数中的collapse参数如果被赋值,便会将一个字符串向量中的元素压缩成单个字符串。
paste函数会利用collapse参数的值作为分隔字符串向量中不同元素的分隔符。因此symbols由“B”“0”“B”变成“B 0 B”。
然后用paste函数,将符号组合symbols和中奖了金额prize组合起来,在paste函数中设置sep参数可以指定如何将不同的对象组合成一个字符串。在本例中paste函数就会把symbols中的符号组合B 0 B 以及prize中的中奖金额0组合成一个字符串。\n代表另起新行。因此结果应该是
string
“B 0 B\n0catcatprintcat\ncat(string)B0B0
对于每次play的运行时结果,都可以用slot.display函数进行人工清理

可以调用print函数中的类属性函数,对上述问题实现自动清理,即用S3系统,
建立一个自己的类函数:

print.slots<-function(x,…){
slot_display(x)
}
将play函数做修改:
play<-function(){
symbols<-get_symbols()
structure(score(symbols),symbols=symbols,class=”slots”)
}
play()
BB BB BBB
$5


 ###structure函数可以将生成中奖金额和设置属性值合并为一步来完成。该函数的第一个参数是一个R对象或者对象的取值,剩下的参数是你想要添加给这个对象的属性。

![老虎机完整版](https://img-blog.youkuaiyun.com/20170317181310239?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmdsYW5sYW4wMjI0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
(终于做完了,好心累啊。。。。
果然要动手实践一下,不然有好多问题。。。
下次自己再来一遍吧)

处理百搭钻石符号的score 函数:

score<-function(symbols){
+diamonds<-sum(symbols==”DD”)
+cherries<-sum(symbols==”C”)
+slots<-symbols[symbols!=”DD”]
+same<-length(unique(slots))==1
+bars<-slots%in%c(“B”,”BB”,”BBB”)
+ if(diamonds==3){
+price<-100
+}else if(same){
+payouts<-c(“7”=80,”BBB”=40,”BB”=25,”B”=10,”C”=10,”0”=0)
+price<-unname(payouts[slots[1]])
+}else if(all(bars)){
+price<-5
+}else if(cherries<0){
+price<-c(0,2,5)[cherries+diamonds+1]
+}else{
+price<-0
+}
+price*2^diamonds
+}
“`

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值