ITPub博客

首页 > > > 用R语言进行NBA赛况分析

用R语言进行NBA赛况分析

作者:浪花小雨滴 时间:2020-06-16 15:30:01 0 删除 编辑
本文中的数据案例来自kaggle,下面附上案例主页的链接NBA shot logs | Kaggle感兴趣的朋友可自行下载原始数据进行分析。

首先起了一个很唬人的名字“用R语言进行NBA赛况分析”,写代码之前本以为可以分析出很多东西,然而作为一个小白吭哧吭哧一下午只得到了一点点成果,下面和大家分享。

设立目标:

首先来看一下原始数据:

共有21个变量和将近13万个观测,目前的水平还无法对如此庞大的数据进行整体分析,因此我将只选出其中的一部分数据来进行分析,而选择哪些数据又取决于我的分析目标,所以在我拿到原始数据后的第一件事就是确立分析目标:

数据预处理:

确立目标之后即可对数据进行预处理:


数据中包含了很多场比赛的信息,这里我只对其中一场进行分析,通过变量GAME_ID选择我想要的场次,再根据我的分析目标选择变量,下面是对我选择的变量的解释说明:

#加载包
  library(dplyr)
  library(magrittr)
  library(ggplot2)
  library(ggthemes)
  library(reshape2)

#数据预处理
#挑选数据
  NBA<-filter(shot_logs,GAME_ID==21400899)
  NBA<-select(NBA,GAME_ID,LOCATION,SHOT_NUMBER,PERIOD,
            SHOT_DIST,PTS_TYPE,SHOT_RESULT,player_name)
  
#将原数据SHOT_RESULT变量中的missed和made用0和1代替  
  NBA$SHOT_RESULT[NBA$SHOT_RESULT=="made"]<-1
  NBA$SHOT_RESULT[NBA$SHOT_RESULT=="missed"]<-0
  
#将SHOT_RESULT转成数值型
#计算每次投篮得分情况,添加到数据框中
  NBA$SHOT_RESULT<-as.numeric(NBA$SHOT_RESULT)
  NBA$PTS<-NBA$SHOT_RESULT*NBA$PTS_TYPE

#将两支球队分组
  NBA_A<-filter(NBA,LOCATION=="A")
  NBA_H<-filter(NBA,LOCATION=="H")

通过以上代码的预处理我们得到了A队和H队的数据框信息:

分析目标1:

#定义函数,用于计算后面每位球员的2分球命中次数
two_get<-function(x){
  
  count<-length(x)
  n<-0
  for(i in 1:count){
    if(x[i]==2) n<-n+1
  }
  return(n)
}

#定义函数,用于计算后面每位球员的3分球命中次数
three_get<-function(x){
  
  count<-length(x)
  n<-0
  for(i in 1:count){
    if(x[i]==3) n<-n+1
  }
  return(n)
}
#------------------------------------------------------------------

#group_by()根据球员将数据分组
#分别计每位球员的投篮次数、总得分、2分球命中次数、3分球命中次数

A_player<- group_by(NBA_A,player_name)%>%
  summarise(count=n(),tot_score=sum(PTS),
            two_pts_num=two_get(as.numeric(PTS)),
            three_pts_num=three_get(as.numeric(PTS)))
H_player<- group_by(NBA_H,player_name)%>%
  summarise(count=n(),tot_score=sum(PTS),
            two_pts_num=two_get(as.numeric(PTS)),
            three_pts_num=three_get(as.numeric(PTS)))

通过以上对数据的进一步处理之后即可得到两队球员在比赛中的表现情况:

下面将两队球员的得分情况绘制成条形图,并分别添加两队球员得分情况的水平线:

ggplot(data = A_player)+
  geom_col(aes(x=player_name,y=tot_score,fill=player_name))+
  geom_hline(aes(yintercept=mean(tot_score)),
             colour="red",linetype="dashed",lwd=1)+
  theme_few()
  
ggplot(data = H_player)+
  geom_col(aes(x=player_name,y=tot_score,fill=player_name))+
  geom_hline(aes(yintercept=mean(tot_score)),
             colour="red",linetype="dashed",lwd=1)+
  theme_few()

可以看到两队各有五名队员得分在平均水平以上,而其中A队(上图)球员的得分基本都在10分以上,B队(下图)却没有人得到10分。

分析目标2:

这一分析的目的是绘制两队投篮命中次数随投篮点距篮筐距离长短变化的散点图,原始数据中的SHOT_DIST变量中的观测保留了一位小数,这样使命中频率随距离的变化太过分散,而无法进行有效的比较和观察,因此用ceiling函数将SHOT_DIST变量中的观测向前进一位取整。

#数据预处理
#用ceiling()取整投篮距离

NBA_A$SHOT_DIST<-ceiling(NBA_A$SHOT_DIST)
NBA_H$SHOT_DIST<-ceiling(NBA_H$SHOT_DIST)

#挑选数据

melt_A<-select(NBA_A,SHOT_DIST,SHOT_RESULT)
melt_H<-select(NBA_H,SHOT_DIST,SHOT_RESULT)

#数据融合重铸,得到不同距离的投篮命中频率
A<-melt(melt_A,id="SHOT_DIST")%>%
  dcast(SHOT_DIST~value,sum)
H<-melt(melt_H,id="SHOT_DIST")%>%
  dcast(SHOT_DIST~value,sum)

#为两队添加主客队信息(为后面绘图做准备)
A$LOCATION<-rep("A",28)
H$LOCATION<-rep("H",24)

#合并数据框
A_B<-rbind(A,H)

#重命名变量
names(A_B)<-c("SHOT_DIST","NO","MADE_NUM","LOCATION")

#删除MADE_NUM等于0的观测(影响分析结果)
A_B<-A_B[!A_B$MADE_NUM==0,]

最后得到下面的数据框:

数据框中的MADE_NUM变量即表示相应距离下的投篮命中次数,最后将SHOT_DIST和MADE_NUM两个变量绘制成散点图并添加趋势线:

ggplot(data=A_B,aes(x=SHOT_DIST,y=MADE_NUM,
       colour=LOCATION,linetype=LOCATION))+
  geom_point()+
  geom_smooth()+
  theme_few()

比赛的结果是A队赢得比赛,根据散点图我们可以猜测,两队在篮下的的得分情况大致相同,而A队在三分线附近的得分要高于H队,因此最后赢得比赛。

总结:

代码中有很多比较麻烦的地方,主要是由于函数认识的不多,同时运用的也不够熟练。另外由于数据类型各不相同,因此虽然认识了给类图表但仍难以将其与数据进行结合,R语言只是进行数据分析的工具,数据分析的核心是分析者的分析思维,否则就如同武侠小说中的人物拿到了绝世武器却不会武功一样,难以发挥其威力。下一步打算在继续学习R语言的同时再多看一些数据分析思维方面的书籍。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31537575/viewspace-3130722/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2018-05-16

  • 博文量
    4259
  • 访问量
    40024