查看原文
其他

Kaggle案例~R可视化分析美国枪击案(附数据集和代码)

2017-10-25 邬书豪 R语言中文社区


作者:邬书豪,车联网数据挖掘工程师 ,R语言中文社区专栏作者。微信ID:wsh137552775

知乎专栏:https://www.zhihu.com/people/wu-shu-hao-67/activities


数据集:自1966~2017年发生在美国的大规模枪击案(死伤人数在三人以上的枪击案)

一、探索数据

#加载此次所要用到的包 library(lubridate)#日期处理 library(data.table)#更改数据框的格式,使之更为易用 library(dplyr)#包含诸多常用函数 library(ggplot2)#绘图 library(stringr)#对文本进行处理 library(tidyr)#对数据分类汇总 library(ggmap)#进行地图绘制 #设置工作路径 setwd("D:/US Mass Shootings") #导入数据 shoot <- fread("Mass Shootings Dataset.csv",header = TRUE,stringsAsFactors = FALSE) #将过长过大的数据集转换为显示更友好的 tbl_df 类型: shoot <- tbl_df(shoot) #对部分列名进行重命名 shoot<- rename(shoot,ID=`S#`,Total=`Total victims`,Mental=`Mental Health Issues`) #观察数据 glimpse(shoot)
shoot数据集中共有398行,13个变量
  • ID:各案件编号

  • Title:案件名称

  • Location:案件发生所在的州

  • Date:案件发生日期,时间跨度:1966-08-01 ~ 2017-10-01

  • Summary:对案件的概述,如枪手名字,年龄,事件经过等

  • Fatalities:该次案件中死亡人数

  • Injured:该次案件中受伤人数

  • Total:该次案件中总计伤亡人数

  • Mental:枪手是否有精神问题

  • Race:枪手的种族/肤色,有White、Black、Asian等等

  • Gender:枪手性别

  • Latitude:纬度

  • Longitude经度

二、数据整理

由于第一条关于Las vegas枪击案不完善,据最近新闻报道对其进行修改补充

shoot$Injured[shoot$ID==1] <- 527 shoot$Fatalities[shoot$ID==1] <- 59 shoot$Total[shoot$ID==1] <- 586 shoot$Race[shoot$ID==1] <- "White" shoot$Gender[shoot$ID==1] <- "Male" shoot$Latitude[shoot$ID==1] <- 36.0918365 shoot$Longitude[shoot$ID==1] <- -115.1754113 shoot$Summary[shoot$ID==1] <- "Stephen Paddock, a 64-year-old gunman opened fire on a large crowd of concertgoers at the Route 91 Harvest music festival on the Las Vegas Strip, killing 59 people and injuring 527"

数据集(Gender、Mental、Race)变量下的观测值命名较为混乱,咱们将它修补统一哈!

shoot$Gender[shoot$Gender=="M"] <- "Male" shoot$Gender[shoot$Gender=="M/F"] <- "Male/Female" shoot$Mental[shoot$Mental=="Unclear" | shoot$Mental=="unknown"] <- "Unknown" shoot$Race[shoot$Race=="black" | shoot$Race=="Black American or African American" | shoot$Race=="Black American or African American/Unknown"] <- "Black" shoot$Race[shoot$Race=="white" | shoot$Race=="White American or European American" | shoot$Race=="White American or European American/Some other Race"] <- "White" shoot$Race[shoot$Race=="unclear" | shoot$Race==""] <- "Unknown" shoot$Race[shoot$Race=="Asian American/Some other race" | shoot$Race=="Asian American"] <- "Asian" shoot$Race[shoot$Race=="Latino" | shoot$Race=="Native American" | shoot$Race=="Native American or Alaska Native" | shoot$Race=="Some other race" | shoot$Race=="Two or more races"] <- "Other"

通过浏览对比发现一部分事件存在重复,即Summary不同但所描述事件过程基本一样,经纬度及伤亡人数上区别很小,可能是数据集录入之初产生的错误,故去重!

shoot<- distinct(shoot,Location,Date,Mental,Gender,.keep_all=TRUE) shoot<- distinct(shoot,Date,Total,Gender,.keep_all=TRUE) shoot<- distinct(shoot,Date,Fatalities,Gender,.keep_all=TRUE)

三、数据可视化分析

按年份、月份、性别以及精神问题进行可视化分析!

shoot$Date <- as.Date(shoot$Date,"%m/%d/%Y") #增加一个新变量year。按照年份统计枪击频率 shoot$year <- year(shoot$Date) #直方图设置为6个组数,故设置breaks = 6 hist(shoot$year,breaks = 6,col = "lightblue",xlab = "year",main = "Frequency of shoot")
按照年份统计枪击频率

枪击案发生频率连年递增,尤其近几年来显著增多

#按照月份统计枪击频率 hist(month(shoot$Date),xlab="Month",ylab="Count",main="the distribution of month")

发生在一月份的枪击案的频率较其它月份相对显著

按照月份统计枪击频率
#将plot()函数绘制的四幅图形组合在一个大的1×2的图中,按照性别及种族统计枪击频率 par(mfrow=c(1,2)) barplot(table(shoot$Gender),xlab = "Gender",ylab="Count",main="the distribution of Gender") barplot(table(shoot$Mental),xlab = "Mental Health Issue",ylab="Count",main="the distribution of mental")
按照性别及种族统计枪击频率
  • 绝大多数枪手都是男性

  • 在已知的枪手中,过半数人有精神问题

#增加一个Level变量,按照死伤人数多少对案件划分严重程度。 shoot$Level <- NA shoot$Level[shoot$Total<5] <- "Under 5" shoot$Level[shoot$Total>=5 & shoot$Total<=10] <- "5 to 10" shoot$Level[shoot$Total>10] <- "Above 10" #统计各Level的频次 ggplot(shoot,aes(factor(Level,levels=c("Under 5","5 to 10","Above 10"))))+geom_bar(fill="orange")+xlab("Level") #统计各Level累计死伤人数 Levelsum<- as.data.frame(tapply(shoot$Total,shoot$Level,sum)) colnames(Levelsum) <- "Sum" ggplot(Levelsum,aes(reorder(row.names(Levelsum),Sum),Sum))+geom_bar(stat="identity",fill="red")+xlab("Level")

统计各Level的频次

本数据集只包含死伤三人及以上的数据集,5至10人发生频次较高。然而论死伤总人数,超过10人死伤的案件虽然只占总体案件的约20%,然而累计死伤人数却占了近60%。

#精神问题与伤亡,subset()函数抽取出已知枪手精神问题的部分 mental<- subset(shoot,Mental!="Unknown") mental_cas<- data.frame(table(mental$Mental,mental$Level)) colnames(mental_cas) <- c("Mental","Level","Freq") ggplot(mental_cas,aes(x=factor(Level,levels=c("Under 5","5 to 10","Above 10")),y=Freq,fill=Mental))+geom_bar(stat="identity",position = "dodge")+xlab("Level")

从前两个与第三个箱线图的比较来看,被杀死的受害者中,明显被有精神问题杀害的人居多!

#先用tapply()函数计算被是否患有精神问题的枪手导致的伤亡累计,然后绘图! barplot(tapply(mental$Total,mental$Mental,sum),main="Shooter with mental health issue",col = "lightblue",ylab = "No. of Casualties")

有精神问题的枪手导致的伤亡甚至占到了三分之二。

#分析枪手所属种族所占比例 shooter <- data.frame(table(shoot$Race)) colnames(shooter) <- c("Race","Freq") ggplot(shooter,aes(x=reorder(Race,Freq),y=Freq,fill=Race))+geom_bar(stat="identity",width = 1)+coord_polar(theta = "y")

shooter

枪手里面,白人以及黑人占绝大多数!!而亚裔枪手只占一小丢丢!

#cut()函数将变量year按值域切割为多个区间,赋值为新变量yearcut,对年份进行分段 shoot$yearcut <- cut(year(shoot$Date),breaks = 10) shoot_year<- select(shoot,yearcut,Fatalities,Injured) shoot_year<- gather(shoot_year,type,victim,-yearcut) #随年份的改变枪手种族比例的变化 ggplot(shoot,aes(yearcut,fill=Race))+geom_bar()

随年份的改变枪手种族比例的变化

在2012年以前枪手主要是白人,最近5年来黑人以及其它族裔的种族枪手所占比例提升较大!

#年份与死伤人数统计 shoot_year2<- group_by(shoot_year,yearcut,type) %>% summarise(Sum=sum(victim)) ggplot(shoot_year2,aes(yearcut,Sum,fill=type))+geom_bar(stat="identity",position = "dodge")

年份与死伤人数统计

在2012年以前,死亡人数一直保持在与受伤人数相差无几的状态下,而2012年以后受伤人群-大幅增加!~~~~~其主要原因在于2017-10-01日发生的拉斯维加斯露天音乐会枪击案!!!!~~~~死59人,伤527人,实乃美国枪击案件之最也!!!

~~~~看到这幅图,我们无比震惊!!!仿佛可以听到拉斯维加斯露天音乐会枪击案现场“哒哒哒哒哒哒哒哒哒哒哒哒”的子弹声!!!

#各年份中各Level所占比例 ggplot(shoot,aes(yearcut,fill=Level))+geom_bar(position = "fill")+ggtitle("How year impact Level")

各年份中各Level所占比例

综上~虽然近5年来死伤人数远超以往!!

但超过10人死伤的严重枪击案反而只占很小一部分,更反映出小规模枪击案的频繁!

#从文本概述中运用正则表达式抽取出年龄 tem <- mutate(shoot,age=str_extract_all(shoot$Summary,pattern="(,\\s)\\d{2}(,)"),age2=str_extract_all(shoot$Summary,pattern="(a\\s)\\d{2}(-year)")) tem$age<- str_sub(tem$age,3,4) tem$age2<- str_sub(tem$age2,3,4) te <- subset(tem,tem$age!="ar") te2 <- subset(tem,tem$age2!="ar") te <- rbind(te,te2) for(i in 1:nrow(te))  if(te$age[i]=="ar") te$age[i] <- te$age2[i] te <- arrange(te,age) te<- te[-c(1:4),]#去除非数字部分 te <- arrange(te,ID) te$age <- as.integer(te$age) te3 <- te %>% select(ID,age) %>% mutate(agecut=cut(te$age,breaks = 10*(1:7))) #将年龄分段 shoot_age <- left_join(te3,shoot,by="ID") #年龄分布 ggplot(shoot_age,aes(agecut))+geom_bar(fill="lightblue")+ggtitle("the distribution of age")

年龄分布
已知年龄的枪手中,50岁以下占主要比例,青年与中年人的比例不相上下!
#绘制出各年龄段中是否有精神问题的比例 ggplot(shoot_age,aes(agecut,fill=Mental))+geom_bar(position = "fill")+ggtitle("The relationship between Age and Mental")

各年龄段中是否有精神问题的比例

已知年龄的犯罪分子中,有精神问题者居多,其中30岁至40岁的人比例略大一些!

#年龄与种族的关系 ggplot(shoot_age,aes(agecut,fill=Race))+geom_bar(position="fill")+ggtitle("the relationhship between Age and Race")

在20岁以下及50岁以上,白人占比都超过六成;黑人枪手则主要集中于20岁至50岁的年龄段



ggplot2包它精致唯美博大精深,万言不如一图!

掌握ggplot2包可视化技巧对于数据分析至关重要!

就像一门顶尖 的厨师,它的厨艺技能绝对不是看来跟师傅看来的,而是十年如一日的孜孜不倦的练习!学习ggplot2可视化也一样,需要孜孜不倦的对大量数据集进行练习!


公众号后台回复“枪击”获取数据集下载链接。


公众号后台回复关键字即可学习

回复 R              R语言快速入门免费视频 
回复 统计          统计方法及其在R中的实现
回复 用户画像   民生银行客户画像搭建与应用 
回复 大数据      大数据系列免费视频教程
回复 可视化      利用R语言做数据可视化
回复 数据挖掘   数据挖掘算法原理解释与应用
回复 机器学习   R&Python机器学习入门 

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存