获得和清洗数据:

1.从网络上抓取数据

year<-2013
url<-paste("http://sports.yahoo.com/nfl/stats/byteam?group=Offense&cat=Total&conference=NFL&year=season_",year,"&sort=530&old_category=Total&old_group=Offense")
offense<-readHTMLTable(url,encoding="UTF-8",colClasses="character")[[7]]

执行上面的命令可以创建一个存储32个球队在2013赛季所有进攻统计数据的数据框offense

2.首先注意到下载的球队数据存在很多空白列,而且为了确保数据格式正确,我们需要先进行数据清洗工作。如下所示,我们清除空白的列,并给每列赋予我们需要的数据类型。

offense<-offense[,-c(2,4,6,8,10,12,14,16,18,20,22,24,26,28)]
offense[,1]<-as.character(offense[,1])
offense[,2:13]<-apply(offense[,2:13],2,as.numeric)
offense[,14]<-as.numeric(substr(offense[,14],1,2))*60+as.numeric(substr(offense[,14],4,6))

3.通过同样的方式获取防守数据。

url<-paste("http://sports.yahoo.com/nfl/stats/byteam?group=Defense&cat=Total&conference=NFL&year=season_",year,"&sort=530&old_category=Total&old_group=Defense")
defense<-readHTMLTable(url,encoding="UTF-8",colClasses="character")[[7]]

readHTMLTable函数会下载整个网页,所以我们通过在命令的末尾加上[[7]]来选择我们需要的第7列元素。

R语言中的paste()函数实现字符串的连接。如果你对操作数据陌生,连接指的是将两个字符串拼接在一起。我们利用paste函数来连接下载数据的URL和需要获取数据的年份,从而可以仅仅通过改变year的数值来改变整个下载数据的URL。另一个非常有用的R函数是apply()。我们可以通过它仅用一行代码同时将多列变量变成数值类型。apply()函数不仅可以用来改变数据类型,也可以执行其他数学计算。

分析和理解美式橄榄球比赛数据

1.首先,为了方便后续数据研究,我们将offense和defense两个数据框合并成combined

combined<-merge(offense,defense,by.x="Team",by.y="Team")

因为offense和defense数据框中存在相同的列名称,为了避免后面操作的混淆,我们需要为重名的列进行唯一命名。同时我们会剔出defense中和offense中重复的比赛数量列。

colnames(combined)[2]<-"Games"
colnames(combined)[3]<-"OffPPG"
colnames(combined)[4]<-"OffYPG"
colnames(combined)[5]<-"OffPassYPG"
colnames(combined)[6]<-"OffRushYPG"
combined$G.y<-NULL
colnames(combined)[15]<-"DefPPG"
colnames(combined)[16]<-"DefYPG"
colnames(combined)[17]<-"DefRushYPG"
colnames(combined)[18]<-"DefPassYPG"

直方图一直是初步研究数据的最好工具之一。因为它可以通过显示每列数据的分布而分辨偏低、偏高和在正常范围内的数值。

首先,我们为每个球队平均每场进攻得分(offensive points per game)创建一个直方图

hist(combined$OffPPG,breaks=10,main="Offensive Points Per Game",xlab="Offensive PPG",ylab="Number of Teams")

2.尝试通过条形图来理解combined数据集。

条形图和前面所创建的直方图经常容易被混淆。在这里,二者的区别在于,条形图可以刻画出每支球队在不同评价指标上的差异,而直方图却是用来显示出评价指标在不同数值段上的球队数量的分布

ppg<-transform(combined,Team=reorder(Team,combined$OffPPG))
ggplot(ppg,aes(x=Team,y=OffPPG))+geom_bar(stat='identity',color="black",fill="blue")+coord_flip()+labs(x="Team",y="Avg Points per Game")+ggtitle("Avg Points per Game")+theme(plot.title=element_text(size=18,face="bold"))

3.现在我们再看看每支球队在失守码数上的平均表现,命令如下:

ypg<-transform(combined,Team=reorder(Team,-combined$DefYPG))
ggplot(ppg,aes(x=Team,y=OffPPG))+geom_bar(stat='identity',color="black",fill="blue")+coord_flip()+labs(x="Team",y=“Avg Points per Game”)+ggtitle("Avg points per Game")+theme(plot.title=element_text(size=18,face="bold"))

4.最后我们通过散点图来观察两个变量之间的相关性

ggplot(combined,aes(x=combined$OffYPG,y=combined$OffPPG))+geom_point(shape=5,size=2)+geom_smooth()+labs(x="Yards per Game",y="Points per Game")+ggtitle("Offense Yards vs. Points per Game")+theme(plot.title=element_text(size=18,face="bold"))

构建度量攻防能力的指标

我们按照下面的流程来构造攻防指数:

1.首先,我们计算球队的进攻传球能力分值。combined变量中最能能体现传球能力的是PassYds/G(average passing yards per game),即平均每场传球码数。PassYds/G的值越高,说明球队拥有更强的传球能力。

offense$OPassStrength<-max(offense[,5])-offense[,5]
offense$OPassStrength<-(1-(offense$OPassStrength/max(offense$OPassStrength)))*100

首先我们计算每个球队的PassYds/G和最大值之间的差值,然后除以最大值。1减去比值的用意是为了使分值的大小和传球能力的大小成正比,最后将分值归一到0和100之间。

2.为了计算球队的进攻冲击能力,我们可以对数据域RushYds(average rushing yards per game)采取相同的变换。

3.对每场进攻得分和进攻码数进行上面相同的变化,然后将四个变换之后的变量综合成用户的攻击能力指标。

模拟单场由程序决定胜负的比赛

模拟比赛的基本思路是比赛双方中自身进攻能力和对手防守能力之间差值较大的队伍将获得比赛的胜利

1.选择两支参赛的队伍,为了方便起见,我们称这两支球队分别为主队和客队。

home_team<-"Chicago Bears"
away_team<-"New Orleans Saints"

2.整合前面所计算的球队的攻防能力指数

off_game<-subset(offense,Team==home_team|Team==away_team)[,c(1,15,16,19)]
def_game<-subset(defense,Team==home_team|Team==away_team)[,c(1,14,15,18)]
game<-merge(off_game,def_game,by.x="Team",by.y="Team")

3.基于汇总的参赛双方数据,我们现在可以通过比较两者的攻防能力指标来决定理论上应该胜出的队伍。

game$Net_Pass[game$Team==home_team]<-game$OPassStrength[game$Team==home_team]-game$DPassStrength[game$Team==away_team]
game$Net_Pass[game$Team==away_team]<-game$OPassStrength[game$Team==home_team]-game$DPassStrength[game$Team==home_team]

4.上面我们计算了双方在传球能力上的差别,我们现在比较两支球队在冲球能力以及总能力上的差别

game$Net_Rush[game$Team==home_team]<-game$ORushStrength[game$Team==home_team]-game$DRushStrength[game$Team==away_team]

game$Net_Rush[game$Team==away_team]<-game$ORushStrength[game$Team==away_team]-game$DRushStrength[game$Team==home_team]

game$Net_Total[game$Team==home_team]<-game$OffStrength[game$Team==home_team]-game$DefStrength[game$Team==away_team]

game$Net_Total[game$Team==away_team]<-game$OffStrength[game$Team==away_team]-game$DefStrength[game$Team==home_team]

5.因为球队的总能力表现是基于传球、冲击和总体能力初始差值得到的,我们需要重写Net_Total列。然后,通过比较两支球队的Net_Total,给出虚拟球赛中最终能够获胜的球队

game$Net_Total<-game$Net_Pass+game$Net_Rush+game$Net_Total

if(game$Net_Total[game$Team==home_team]>=game$Net_Total[game$Team==away_team]){
winner<-home_team
loser<-away_team }
else{
winner<-away_team
loser<-home_team
} print(paste(winner,"beat",loser))

模拟美式橄榄球比赛数据(R)的更多相关文章

  1. c# JD快速搜索工具,2015分析JD搜索报文,模拟请求搜索数据,快速定位宝贝排行位置。

    分析JD搜索报文 搜索关键字 女装 第二页,分2次加载. rt=1&stop=1&click=&psort=&page=3http://search.jd.com/Se ...

  2. 使用PHP模拟post提交数据

    使用PHP模拟post提交数据 分类: PHP LAMP 2013-04-13 12:03 3954人阅读 评论(0) 收藏 举报 CurlsocketPHP 这也是个老生常谈的话题了,上午花了点时间 ...

  3. 模拟提交API数据Pyqt版

    其实这个模拟提交数据之前已经写过篇: Python requests模拟登录 因为现在在做的项目中需要一个debug请求调试API,用PHP的CURL写了一个,又因Pyqt更能直观灵活的显示请求的参数 ...

  4. Fiddler模拟自动响应数据

    Fiddler模拟自动响应数据 定位到要修改的部分 2.将返回的数据保存到本地,保存成网页,并修改响应数据 找到修改的部分,修改之 3.再次请求刷新首页,将工具定位到autoresponder将接口加 ...

  5. cURL模拟POST提交数据

    首先,是这个代码: <?php //curl模拟post提交数据$url = "http://127.0.0.1/immoc/output.php";$post_data = ...

  6. vue模拟后端获取数据——json-server与express

    转载自: https://blog.csdn.net/weixin_39728230/article/details/80293892 https://blog.csdn.net/lxkll/arti ...

  7. SQL中CRUD C——create 添加数据 R——read 读取数据 U——update 修改数据 D——delete 删除数据

    在SQL server中对数据库的操作: 删除表:drop table 表名修改表:alter table 表名 添加列add 列名 列类型alter table 表名 drop column 列名 ...

  8. 爬虫实践--CBA历年比赛数据

    闲来无聊,刚好有个朋友来问爬虫的事情,说起来了CBA这两年的比赛数据,做个分析,再来个大数据啥的.来了兴趣,果然搞起来,下面分享一下爬虫的思路. 1.选取数据源 这里我并不懂CBA,数据源选的是国内某 ...

  9. shell编程系列21--文本处理三剑客之awk中数组的用法及模拟生产环境数据统计

    shell编程系列21--文本处理三剑客之awk中数组的用法及模拟生产环境数据统计 shell中的数组的用法: shell数组中的下标是从0开始的 array=("Allen" & ...

随机推荐

  1. MVC之ActionFilterAttribute自定义属性

    ActionFilterAttribute里有OnActionExecuting方法,跟Controller一样, 同是抽象实现了IActionFilter接口. // 登录认证特性 public c ...

  2. nodejs 获取指定路径下所有的文件夹名

    示例:获取 ./components 下所有的文件夹名称 let components = [] const files = fs.readdirSync('./components') files. ...

  3. chrome 浏览器 的一些控制台技巧

    1.查找dom元素.但它并不支持jquery语法. $$("#fock");   // 目前仅仅知道可以查找Dom元素 2.查找dom元素绑定的事件. getEventListen ...

  4. Atitit.android  jsbridge v1新特性

    Atitit.android  jsbridge v1新特性 1. Java代码调用js并传参其实是通过WebView的loadUrl方法去调用的.只是参数url的写法不一样而已1 2. 三.JAVA ...

  5. js模板引擎artTemplate快速上手

    腾讯的artTemplate 1,编写模板 (采用script标签并带有属性id和type="text/html") <script id="test" ...

  6. Redis 安装成windows服务- 一主二从三哨兵,sentinel安装为Windows服务

    这里只做记录说明 Redis的主从配置网上很多文章,百度一大堆,安装流程应该都可以配置通.我使用的这篇文章 https://blog.csdn.net/u010648555/article/detai ...

  7. (转)初步认识拓展UnityEditor编辑器定制

    初步认识拓展UnityEditor编辑器定制 热度 9529 2015-9-4 18:50 |个人分类:Unity3d| 编辑器, 拓展 我相信无数初学者看别人游戏都经常看到他们的Inspector中 ...

  8. Python中threading的join和setDaemon的区别及用法[例子]

    Python多线程编程时,经常会用到join()和setDaemon()方法,今天特地研究了一下两者的区别. 1.join ()方法:主线程A中,创建了子线程B,并且在主线程A中调用了B.join() ...

  9. eclipse 4.3 汉化

    打开浏览器,浏览“参考资料”内给出的“eclipse语言包下载”地址,在博客新页面找到地址链接,如图所示.“Babel Language...”开头的一栏下面就是各个eclise版本的语言包,此处以I ...

  10. W​i​n​下​h​t​t​p​d​+​p​h​p​+​m​y​s​q​l​环​境​集​成

    apache+php+mysql: php下载:  VC6就是legacy Visual Studio 6 compiler,就是使用这个编译器编译的,  VC9就是the Visual Studio ...