复杂数据分析处理的一般过程为:
理解数据——>数据导入——>数据预处理——>数据计算——>数据显示
其中,数据的预处理又可分为以下步骤:选择子集——>重命名列名——>删除缺失数据——>日期的处理——>数据类型转换——>数据排序;
数据的运算可以使用dplyr 包的分组函数group_by(),组合函数summarise().
大致介绍一下dplyr包工具集
1.dplyr包简介
dplyr软件包提供了简单的“动词”,通过限制您的选项,简化了常见的数据操作任务。并将你的想法转化为代码,它使用高效的数据存储后端,有着更加高效的运行效率
2.常用函数("动词")
filter()(和slice())
用于生成子集。第一个参数是数据帧的名称。第二个和后续的参数是过滤数据框架的表达式
arrange()
工作方式类似于filter(),它重新排序了原数据帧。它需要一个数据框和一组列名(或更复杂的表达式)来排序。
select()(和rename())
select()允许您使用通常仅适用于数字变量位置的操作快速放大一个有用的子集
distinct()
distinct()用于在表中查找唯一的值
mutate()(和transmute())
添加作为现有列的函数的新列
summarise()
summarise()它将数据帧折叠到单个行,比如说进行多行的求和求平均等等数学操作
sample_n()(和sample_frac())
使用sample_n(),并sample_frac()采取行的随机抽样:使用sample_n()固定数量和sample_frac()用于固定分数。
group_by()
group_by()它将数据集分解为指定的行组。当您将上述动词应用于生成的对象时,它们将被“按组”自动应用。
使用dplyr包进行的数据处理模式是:split-Apply-combine
调用group_by()函数相当于split 步骤,是对数据进行分组,summarize()函数相当于apply和combine函数
数据计算完成后,使用ggplot2进行绘图显示,非常直观的展示计算结果
业务模块的编写
模块化的代码编写有利于代码的可读性和扩展性,有些公共的模块的有非常好的移植性,模块一般可以分大块
数据层模块(db)
业务逻辑模块(service)
视图层模块(view)
下面来实战一个案例:
根据 2015年至2017年英雄联盟的竞争性比赛统计结果,来分析游戏时长对红蓝双方胜率的走势情况
数据集采自:https://www.kaggle.com/chuckephron/leagueoflegends,按照我们的需要,只需下载LeagueofLegends.csv这个表格即可
英雄联盟(简称:LOL),是一款多人在线对战游戏,流行了很多年,到现在依然热度不减,游戏中有两大阵营:居左屏幕下角往右上角进攻的蓝色方和处于右上角往左下角对战的红色方,进行一场游戏,玩家被分配到红蓝方的概率听说是一样的(我老感觉我被分配到红色方的概率更大,导致我胜率好低...... -.-),游戏平均时长在40分钟左右,游戏主要分为四个阶段
25分钟以内 :前中期 中小规模对战发生频繁
25-35分钟 :中期,5v5 团战发生频繁,这个阶段常常因为一次团战而决定了胜负的走势
35-45分钟:中后期,能坚持到这个阶段,游戏进入了白热化,双方装备已经完全成型,装备的差距对胜负影响可以忽略
45 分钟以后:游戏进入大后期,此时一次团战的胜败就可以决定游戏的胜败
按照数据分析的一般流程
1.导入数据
#导入数据
gamesdata <- read.csv("D:/R/RStudioWorkspace/LeagueofLegends_20170416/LeagueofLegends/data/LeagueofLegends.csv")
2.选择包含我们需要的字段的子集并进行数据的整理
LeagueofLegends.csv 数据集内包含了30个字段,赛区、赛季、年份、红蓝双方、比赛结果、游戏时长、各个游戏位置的选手名字等等,对于我们来说只需要 红蓝双方、比赛结果、游戏时长、这5个字段就行了
#选择包含我们需要的字段的子集
#赛区、赛季、年份、红蓝双方、比赛结果、游戏时长
library(dplyr)
library(stringr)
library(ggplot2)
mygames = select(gamesdata ,
blueTeamTag,
bResult,
redTeamTag,
rResult,
gamelength)
line1 <- dim(mygames)
#消除含有空字段前的行:line1: int[1:2] 3645 8
mygames <- filter(mygames,
!is.na(blueTeamTag),
!is.na(bResult),
!is.na(redTeamTag),
!is.na(rResult),
!is.na(gamelength))
line2 <- dim(mygames)
#消除含有空字段前的行:line2: int[1:2] 3645 8 ,说明数据集没有空值
#游戏设定20分钟内不能投降,超过70分钟我们也不进行统计)
mygames <- filter(mygames,gamelength >= 20 & gamelength <=70)
#可以按时长进行排序整理
mygames <- arrange(mygames,gamelength)
3.将数据按时间阶段进行分组并计算蓝红两队的几个重要参数
#保留两位小数
options(digits = 2)
#对数据进行分组,将游戏时长按5分钟一个节点
mygames$length[mygames$gamelength <= 25] <- "0_25 min"
mygames$length[mygames$gamelength > 25 & mygames$gamelength<= 30] <- "25_30 min"
mygames$length[mygames$gamelength > 30 & mygames$gamelength<= 35] <- "30_35 min"
mygames$length[mygames$gamelength > 35 & mygames$gamelength<= 40] <- "35_40 min"
mygames$length[mygames$gamelength > 40 & mygames$gamelength<= 45] <- "40_45 min"
mygames$length[mygames$gamelength > 45 & mygames$gamelength<= 50] <- "45_50 min"
mygames$length[mygames$gamelength > 50 & mygames$gamelength<= 55] <- "50_55 min"
mygames$length[mygames$gamelength > 55 & mygames$gamelength<= 60] <- "55_60 min"
mygames$length[mygames$gamelength > 60 & mygames$gamelength<= 65] <- "60_65 min"
mygames$length[mygames$gamelength > 65 & mygames$gamelength<= 70] <- "65_70 min"
#数据计算,计算出各个时间段蓝红队胜利场次数和所占百分比
newdatas <- group_by(mygames,length)
rate <- summarise(newdatas,count=n(),
blueWin=(sum(bResult,na.rm = TRUE)),
redWin =(sum(rResult,na.rm=TRUE)),
blueWinPercent = blueWin/count,
redWinPercent = redWin/count)
#剔除场次少于50的分组(场次太少没有参考价值)
rate <- filter(rate,count >50)
运行结果如下图:
4.使用ggplot2 进行绘图,展示蓝色方随游戏时间长度的变化,胜率的走势
ggplot(data = rate)+geom_point(aes(x= length,y=blueWinPercent,colour=blueWinPercent))+geom_point(aes(x= length,y=redWinPercent,colour=redWinPercent))
运行结果如下:
处于下方深颜色的是红色方,上方浅颜色的是红色方
根据图形可以的看到,不管在哪个时间段,综合来说在蓝色方的胜率是大于红色方的,(这可能跟人们在游戏中的视觉习惯有一定的关系),不过随着游戏时间的增加,红色方的胜率也会趋近与50%,游戏也渐渐地公平了呢,在游戏平均时长为45分钟左右的场次中,红色方相交于蓝色方的胜率略低,但是相差也不是很大,只要你有过硬的操作水准,过人的团队意识和对胜利的无限渴望,那么红色方地理位置的劣势对胜败影响也并没有想象中的那么大。