题目
(统计学-基于R-第五版-第三章习题3.1)
下表是2022年北京冬奥会取得金牌前6名的国家获得的奖牌数。
- 绘制金牌数的简单条形图和帕累托图
- 绘制中国奖牌数的饼图和扇形图
- 绘制并列条形图、堆叠条形图和百分比条形图
- 绘制马赛克图和树状图
实现代码和结果
1、金牌数的垂直条形图和帕累托图
csv文件的建立:数据表格可以直接在记事本编辑输入文本文档,保存时后缀改为.csv即可。此时注意csv文件保存后用记事本打开再保存,并将编码改为UTF-8 BOM,这样csv文件中的表格才不会乱码。如图所示:
首先用read.csv引入北京冬奥会国家奖牌数量的数据表格命名为example1,接着读取example1中的“金牌”一列信息并命名为tab1,设置图形布局和大小,然后使用barplot函数绘制垂直条形图,xlab表示横坐标名称,ylab表示纵坐标名称,main表示图形名称,col进行填色。帕累托图跟简单条形图差不多,区别在于多了一条累计频率曲线,需要计算累计频率。
代码实现如下:
#引入奖牌数据表
example1<-read.csv("C:/Users/lenovo/OneDrive/大二/大数据统计学实验/实验表格/奖牌数据表格.csv")
tab1<-sort(table(example1$金牌),decreasing = TRUE)
layout(matrix(c(1,2,3,3),2,2,byrow=TRUE))
par(mai=c(0.6,0.6,0.3,0.1),cex=0.7,font.main=1)
#金牌数垂直条形图
barplot(tab1,xlab="金牌数",ylab="获得国家数",border=c(4),main="图1 金牌数垂直条形图",
col=c("pink","lightblue","lightgreen","yellow"))
#金牌数帕累托图
palette<-RColorBrewer::brewer.pal(4,"Blues")
bar<-barplot(tab1,xlab="金牌数",ylab="频数",col=palette,ylim=c(0,1.2*max(tab1)))
text(bar,tab1,labels=tab1,pos=3,col="black")
y<-cumsum(tab1)/sum(tab1)
par(new=TRUE)
plot(y,type="b",pch=15,axes=FALSE,xlab='',ylab='',main='图2 金牌数帕累托图')
axis(side=4)
mtext("累计频率",side=4,line=3,cex=0.8)
text(labels="累积分布曲线",x=3,y=0.92,cex=1)
绘图结果如下:
2、 中国奖牌数的饼图和扇形图
首先提取出example1中关于中国奖牌数的数据并命名为tab2,[3,2:4]表示提取表格第三行,第二至四列。接着计算饼状图各个数据的百分比,即奖牌数百分比,计算百分比使用round函数, tab2/sum(tab2)*100为计算过程,2表示保留小数点后两位,再接着用labs给每个饼块添加信息,包括name、percent、%,pie函数用于绘画饼状图。
扇形图需要用到fan.plot函数,引入plotrix数据包。由于函数要求导入的是向量,可是tab2是表格,所以要用unlist(tab2)把表格转成向量才可以正确运行。
中国奖牌数tab2表格如下图所示:
代码实现如下:
#中国奖牌数饼图
tab2<-example1[3,2:4]
#提取表格第三行“中国”的第二到第四列(金牌、银牌、铜牌数据)
name=names(tab2)
percent<-round(tab2/sum(tab2)*100,2)
labs<-paste(name,"",percent,"%",sep="")
palette<-RColorBrewer::brewer.pal(3,"Set3")
pie(unlist(tab2),labels=labs,init.angle=90,col=palette,main='图3 中国奖牌数饼状图')
#中国奖牌数扇形图
library(plotrix)
fan.plot(unlist(tab2),labels=labs,col=palette,max.span=0.9*pi,shrink=0.06,radius=1.2,
label.radius=1.4,ticks=200,main='图4 中国奖牌数扇形图')
绘图结果如下:
3、 并列条形图、堆叠条形图和百分比条形图
引入ggplot数据包,可以更加方便绘画各种条形图。为了绘制并列、堆叠、百分比条形图,我们需要把数据由短格式转为长格式,使用melt函数,将example1转成三列,分别是国家、奖牌、数量,将新表格命名为tab3。接着使用ggplot函数,导入表格,mapping里面x、y、fill分别表示横坐标、纵坐标、填充颜色的数据,再用labs添加图名,条形图默认垂直,加上coord_flip()即可变成水平,堆叠图和条形图的区别在于geom_bar函数中是否添加了position = "dodge",有就是条形,没有就是堆叠,position='fill'时就是百分比图。
转换为长格式的tab3表格如下图所示:
代码实现如下:
#垂直/水平并列条形图
attach(example1)
library(DescTools)
library(reshape2)
library(ggplot2)
tab3<-melt(example1, id.var="国家", variable.name="奖牌", value.name="数量")
par(mfrow=c(2,2),mai=c(0.7,0.7,0.65,0.1),cex=0.8,cex.main=1,font.main=1)
ggplot(data = tab3, mapping = aes(x = 国家, y = 数量, fill = 奖牌)) + geom_bar(stat = "identity", position = "dodge")+labs(title = "图5 冬奥会奖牌垂直并列条形图")
ggplot(data = tab3, mapping = aes(x = 国家, y = 数量, fill = 奖牌)) + geom_bar(stat = "identity", position = "dodge")+labs(title = "图5 冬奥会奖牌水平并列条形图")+coord_flip()
#垂直/水平堆叠条形图
ggplot(data=tab3,mapping = aes(x = 国家, y = 数量, fill = 奖牌))+geom_bar(stat='identity') +labs(title = "图6 冬奥会奖牌垂直堆叠条形图")
ggplot(data=tab3,mapping = aes(x = 国家, y = 数量, fill = 奖牌))+geom_bar(stat='identity') +labs(title = "图6 冬奥会奖牌水平堆叠条形图") +coord_flip()
#百分比条形图图
ggplot(data=tab3,mapping = aes(x = 国家, y = 数量, fill = 奖牌))+geom_bar(stat='identity',position='fill') +labs(title = "图7 冬奥会奖牌百分比条形图") +coord_flip()
绘图结果如下:
4、马赛克图和树状图
马赛克图和树状图也使用了ggplot函数,其中树状图需要导入treemap数据包,并将tab3转换成带有类别频数的数据框,在treemap函数中进行相关设置。
实现代码如下:
#马赛克图
ggplot(tab3, aes(x = 国家, y = 奖牌, fill = 数量)) + geom_tile() + labs(title = "图8 冬奥会奖牌马赛克图")
#树状图
library(treemap)
library(RColorBrewer)
tab4<-ftable(tab3)
d<-as.data.frame(tab4) # 将列联表转换成带有类别频数的数据框
df<-data.frame(d[,-4],频数=d$Freq) # 将Freq修改为频数
treemap(df,index=c("国家","奖牌","数量"),
vSize="频数",
vColor="国家",
type="index",
border.lwds=c(2,0.1),
fontcolor.labels=c('white',"grey10"),
fontsize.labels=c(12,9),
align.labels = list(c("center", "center"), c("right", "bottom")),
title="图9 冬奥会奖牌树状图")
绘图结果如下: