在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
第六天任务: 通过对模拟老虎机项目的改进,学会以下技能: 1)使用S3方法,它是R的面向对象的编程方法。 2)测算R代码的速度。 3)编写快速,向量化的R代码。 ………………………………………………………………………………………… 昨天的play函数结果已经看到了,是: play() ##”0” “0” “DD” ##0 而不是预料中的: play() ## 0 0 DD ##0 想要完成第二种实现,就要通过R自带的类系统S3系统来解决,它掌管这R如何处理具有不同类的对象。一些函数会首先查询R的S3类,再根据其类属性做出相应的处理。R的S3系统由三个部分组成:属性,泛型函数和方法。 1.属性 查看属性:attributes()。 attr函数可以完成很多关于属性的操作,比如给某个对象添加属性,也可以查询某个对象包含的属性: 可以根据以上内容修改play函数,让其更好的输出。 play<-function(){ symbols<-get_symbols() prize<-score(symbols) attr(prize,”symbols”)<-symbols prize} 现在play函数已经相当接近要求的输出风格了,但是还可以编写slot_display函数美化play函数。 slot_display<-function(prize){ #提取符号输出结果 symbols<-attr(prize,”symbols”) #将所有符号压缩为一个字符串 symbols<-paste(symbols,collapse=” ”) #用正则表达式将符号与奖金信息组合起来 #在正则表达式中\n表示另起一个新行 string<-paste(symbols,prize,sep=”\n$”) #在控制台上显示正则表达式的结果,但是去掉其中的引号 cat(string) } 通过注释可以大概了解各个函数的使用方法,其输出结果为: slot_display(one_play) ##B 0 B ## $0 R的泛型函数类似与C++的函数模版,其函数会自动匹配调用对象的类型,比如print()函数就可以输出任何类型的对象。R的方法就是R的使用方法,是根据泛型函数自动分析R的类属性的方法。 泛型函数,方法和基于类的分派方式构成了R的S3系统。通俗来说,当用R中固有函数时,会调用Usemethod函数来识别对象的类属性,根据类属性的不同,选择对应的方法,调整程序的输出格式。 ----------------------创建类----------------------- 可以利用S3系统为对象创建一个稳健的类,想要创建一个类,应该执行以下操作: 1.给类起一个名称。 2.给属于该类的每个对象赋class属性。 3.为属于该类的对象编写常用泛型函数的类方法。 许多R包都是按照相似的方法创建的。 ----------------------利用循环计算期望值----------------------- 在计算期望值的时候我们可以分为三步: 1)列出所有可能出现的结果。 2)决定每个结果对应的值。 3)计算每个结果出现的概率。 将第二步结果乘以第三步的结果,加一起就是期望值。 R中的expand.grid函数可以方便快捷的写出n个向量元素的所有组合。 我们可以使用类似的方法来解决老虎机问题: wheel<-c(“DD”,”7”,”BBB”,”BB”,”B”,”C”,”0”) combos<-expand.grid(wheel,wheel,wheel,stringAsFactors=FALSE) prob<-c(“DD”=0.03,”7”=0.03,”BBB”=0.06,”BB”=0.1,”B”=0.25,”C”=0.01,”0”=0.52) combos$prob1<-prob[combos$Var1] combos$prob2<-prob[combos$Var2] combos$prob3<-prob[combos$Var3] combos$prob<-combos$prob1* combos$prob12*combos$prob3 sum(combos$prob) ##1 for循环可以重复运行某段代码一定的次数,R的语法表示如下: for(value in that){ this} 在R中for循环不会返回一个输出结果,并且R的佛如循环是针对一个集合来操作的,这是和大多数编程语言不同的地方。 例子: for(value in c(“MY”,”second”,”for”,”loop”)){ print(value) } ##”MY” ##”second” ##”for” ##”loop” 接下来我们更新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(diamond==3){ prize<-100 }else if(same){ payouts<-c(“7”=80,”BBB”=40,”BB”=25,”B”=10,”C”=10,”0”=0) prize<-unname(payouts[slots[1]]) }else if(all (bars)){ prize<-5 }else if(cherries>0){ #如果有一个樱桃 #则将钻石当作樱桃 prize<-c(0,2,5)[cherries+diamonds+1] }else{ prize<-0} #根据钻石的数量,把奖金翻倍 prize*2^diamonds } 我们可以编写for函数来计算每一行的score: for(1 in1:norw(combos)){ symbols<-c(combos[i,1],combos[i,2],combos[i,3]) combos$prize[i]<-score(symbols) } 然后计算期望值: sum(combos$prize*combos$prob) ##0.934356 for循环在R中还有两个兄弟,while循环和repeat循环 while(condition){ code} 其中condition是一个逻辑测试,返回一个逻辑值,每次运行while之前都会运行一遍condition。并且while不会返回任何结果。 repeat更加初级,它会一直重复循环某代码直到你按Esc键终止循环或者遇到break命令。 repeat{code} system.time函数接受一个R表达式作为输入,运行表达式并显示代码运行时长:system.time(function) rep函数的作用是重复生成某一值或者向量,并返回一个更长的向量。 long<-rep(c(-1,1),1000000) -----------------------------注------------------------------- 1.本学习记录来自Garrett Grolemund先生所著《Hands-On Programming with R》(中文名R语言入门与实践)一书。 |
请发表评论