= as.data.frame(Titanic)
data ::datatable(data,rownames = FALSE) DT
第三章 类别数据可视化
1 解释原始数据
Titanic
数据集是datasets
包的配套案例数据,可以通过as.data.frame
将其转化为数据框。解析数据包含哪些变量,如果是分类变量分别有哪些类别?
1 | Class | 1st, 2nd, 3rd, Crew |
2 | Sex | Male, Female |
3 | Age | Child, Adult |
4 | Survived | No, Yes |
2 条形图
绘制Sex和 Survived的并列条形图和堆叠条形图,并为条形图添加频数标签。
2.1 数据准备
下面代码作了什么数据处理?为什么要这样处理?
数据预处理,选取性别、生存人数、频数三列数据,按照性别、生存人数进行分组,然后对各个分组的频数进行求和。
# 数据准备
<- data %>% select(Sex,Survived,Freq) %>%
df summarise(n=sum(Freq),.by=c(Sex,Survived)) %>%
rename(性别=Sex,生还=Survived,人数=n)
::datatable(df,rownames = FALSE) DT
2.2 利用geom_col函数作图
# 图(a)垂直并列条形图
<-ggplot(df,aes(x=性别,y=人数,fill=生还))+
p1geom_col(width=0.8, # 设置条形宽度
position="dodge", # 绘制并列条形图
color="gray50")+ # 设置条形图的边框颜色
scale_fill_brewer(palette="Set2")+ # 设置填充颜色
geom_text(aes(label=人数),position=position_dodge(0.9),vjust=-0.5,size=3)+ # 设置标签垂直位置和字体大小
ylim(0,1.1*max(df$人数))+ # 设置y轴范围
ggtitle("(a) 垂直并列条形图")
# 图(b) 水平并列条形图
<-ggplot(df,aes(x=性别,y=人数,fill=生还))+
p2geom_col(width=0.7,color="gray50")+ # 绘制堆叠条形图(默认)
geom_text(aes(label=人数),position=position_stack(0.5),size=3)+
scale_fill_brewer(palette="Set2")+
ggtitle("(b) 垂直堆叠条形图")
grid.arrange(p1,p2,ncol=2) # 按2列组合图形
- 你可以通过修改数据或者修改刻度标签将图中性别和生还的类别标签改为中文,请给出代码完成修改。
# 图(a)垂直并列条形图
<-ggplot(df,aes(x=性别,y=人数,fill=生还))+
p1geom_col(width=0.8, # 设置条形宽度
position="dodge", # 绘制并列条形图
color="gray50")+ # 设置条形图的边框颜色
scale_fill_brewer(palette="Set2")+ # 设置填充颜色
geom_text(aes(label=人数),position=position_dodge(0.9),vjust=-0.5,size=3)+ # 设置标签垂直位置和字体大小
ylim(0,1.1*max(df$人数))+ # 设置y轴范围
ggtitle("(a) 垂直并列条形图")+
scale_x_discrete(
"性别",
labels=c(
"Male"="男",
"Female"="女"
)+
)scale_fill_discrete(
"生还",
labels=c(
"No"="否",
"Yes"="是"
)
)# 图(b) 水平并列条形图
<-ggplot(df,aes(x=性别,y=人数,fill=生还))+
p2geom_col(width=0.7,color="gray50")+ # 绘制堆叠条形图(默认)
geom_text(aes(label=人数),position=position_stack(0.5),size=3)+
scale_fill_brewer(palette="Set2")+
ggtitle("(b) 垂直堆叠条形图")+
scale_fill_discrete(
"生还",
labels=c(
"No"="否",
"Yes"="是"
)+
)scale_x_discrete(
"性别",
labels=c(
"Male"="男",
"Female"="女"
)
)
grid.arrange(p1,p2,ncol=2) # 按2列组合图形
2.3 介绍图形特点和信息
- 生还人数虽然男性和女性相差不大,但是男性没有生还的人数远远大于女性
3 帕累托图
绘制Class 的帕累托图。
3.1 数据准备
<-data |>
dfselect(Class,Freq) |>
summarise(n=sum(Freq),.by=Class) |>
rename(乘客舱位=Class,人数=n ) |>
arrange(desc(人数)) |>
mutate(累积百分比 = cumsum(人数*100/sum(人数)), #计算累积百分比
= round(累积百分比,1), #保留一位小数
累积百分比 = fct_inorder(乘客舱位) #按字符出现顺序定义因子水平
乘客舱位
)
datatable(df,rownames = FALSE)
3.2 利用geom_col()+geom_line()+geom_point()
等函数作图
<-rev(brewer.pal(4,"Reds")) # 设置调色板
palette# 绘制条形图
<-ggplot(df)+aes(x=乘客舱位,y=人数)+
pgeom_col(width=0.8,fill=palette,color="grey50")+# 绘制条形图
geom_text(aes(x=乘客舱位,y=人数,label=人数,vjust=-0.5),size=3,color="gray50")+ # 添加数值标签,垂直调整标签位置
ylab("人数\n(位)")+ # 设置y轴标签
theme(axis.text.y=element_text(angle=90,hjust=0.5,vjust=0.5))+ # 调整y轴标签角度
theme(legend.position="none") # 删除图例
# 绘制折线和点
<-p+geom_line(aes(x=as.numeric(乘客舱位),y=累积百分比*max(人数/100)))+ # 绘制累积百分比曲线
p1geom_point(aes(x=as.numeric(乘客舱位),y=累积百分比*max(人数/100)),
size=2.5,shape=23,fill="white")+ # 绘制点
geom_text(aes(label=累积百分比,x=乘客舱位,y=1*累积百分比*max(人数/100),
hjust=0.6,vjust=-0.95),size=3,colour="blue3")+ # 添加百分比数值标签
scale_y_continuous(sec.axis = sec_axis(~./max(df$人数/100)))# 添加坐标轴
+annotate("text",x=4,y=870,label="百分比(%)",angle=90,size=3.5)+
p1annotate("text",x=4,y=900,label="累积百分比曲线",size=3.5) # 添加注释文本
3.3 介绍图形特点和信息
- 图形显示船员舱人数最多,其次是一等舱,二等舱和三等舱人数差不多,都比较少。
4 脊形图
绘制Class和 Survived 的脊形图。
4.1 数据准备
# 数据处理
<-data %>%
dfselect(Class,Survived,Freq) %>%
summarise(n=sum(Freq),.by=c(Class,Survived)) %>%
mutate(percent=n*100/sum(n),.by="Survived")
datatable(df)
4.2 利用geom_col()
作图
ggplot(df)+aes(x=Survived,y=percent,fill=Class)+ylab("百分比(%)")+
geom_bar(stat = "identity",width = 0.8,color="grey50")+
scale_fill_brewer(palette = "Blues")
4.3 利用ggiraphExtra包ggSpine()
ggSpine(data=df,aes(x=Survived,y=percent,fill=Class),stat="identity",
palette="Reds",labelsize=3,reverse=TRUE) # 反转调色板颜色
4.4 介绍图形特点和信息
- 从图形中可以明显看出高舱位(一等舱)的生还率显著高于低舱位,三等舱的遇难人数最多
5 树状图和旭日图
绘制Class、Sex、Age和Survived4个变量的矩形树状图和旭日图
5.1 利用treemap::treemap()
函数作树状图
= as.data.frame(Titanic)
data ::datatable(data,rownames = FALSE) DT
# 图(a)分层顺序:Sex—Class—Age-Survived
treemap(data,index=c("Sex","Class","Age","Survived"), # 设置聚合索引的列名称
vSize="Freq", # 指定矩形大小的列名称
#fontsize.labels=9, # 设置标签字体大小
position.legend="bottom", # 设置图例位置
title="(a) 分层顺序:Sex—Class—Age-Survived")
5.2 利用sunburstR::sunburst()
函数作旭日图
- 通过
d3r::d3_nest
将数据框转化为层次数据“d3.js”作为绘图输入
library(d3r)
<-data%>%select(Sex,Class,Age,Survived,Freq) # 根据需要调整列变量的位置
df<-d3_nest(df,value_cols="Freq") # 将数据框转换为“d3.js”层次结构
df_treedatatable(df,rownames = FALSE)
library(sunburstR)
sunburst(data=df_tree, # 绘制旭日图
valueField="Freq", # 计算大小字段的字符为vSize
count=TRUE, # 在解释中包括计数和总数
sumNodes=TRUE) # 默认总和节点=TRUE
5.3 介绍图形特点和信息
6 热图和南丁格尔玫瑰图
绘制Class和Survived 的点阵图、热图和南丁格尔玫瑰图。
6.1 数据准备
library(dplyr)
library(DT)
<- as.data.frame(Titanic) %>%
df select(Class, Survived, Freq) %>%
group_by(Class, Survived) %>%
summarise(人数 = sum(Freq), .groups = "drop") %>%
rename(乘客舱位 = Class, 生还情况 = Survived)
datatable(df, rownames = FALSE)
6.2 利用ggiraphExtra::ggHeatmap()
作热力图
分别作矩形热图和极坐标热图
library(ggiraphExtra)
library(ggplot2)
<- ggHeatmap(df,
p1 aes(x = 乘客舱位, y = 生还情况, fill = 人数),
color = "white") +
scale_fill_gradient(low = "white", high = "red") +
ggtitle("泰坦尼克号生还情况矩形热图") +
theme_minimal()
<- ggHeatmap(df,
p2 aes(x = 乘客舱位, y = 生还情况, fill = 人数),
polar = TRUE) +
scale_fill_gradient(low = "white", high = "blue") +
ggtitle("泰坦尼克号生还情况极坐标热图") +
theme_minimal()
library(gridExtra)
grid.arrange(p1, p2, ncol = 2)
6.3 利用ggiraphExtra::ggRose()
作玫瑰图
library(dplyr)
library(tidyr)
library(ggplot2)
library(RColorBrewer)
library(ggrepel)
# 假设 data 是您的数据框,并且包含 Class, Survived 和 Freq 列
# 将 Class 转换为有序因子
<- factor(data$Class, ordered = TRUE, levels = unique(data$Class))
f
# 构建新的数据框
<- data.frame(Class = f, 生还 = data$Survived, 人数 = data$Freq)
df1
# 使用 dplyr 重新构建数据框,并确保 Class 是有序因子
<- data %>%
df1 select(Class, Survived, Freq) %>%
rename(生还 = Survived, 人数 = Freq) %>%
mutate(Class = factor(Class, ordered = TRUE, levels = unique(Class)))
# 检查 df1
print(df1)
Class 生还 人数
1 1st No 0
2 2nd No 0
3 3rd No 35
4 Crew No 0
5 1st No 0
6 2nd No 0
7 3rd No 17
8 Crew No 0
9 1st No 118
10 2nd No 154
11 3rd No 387
12 Crew No 670
13 1st No 4
14 2nd No 13
15 3rd No 89
16 Crew No 3
17 1st Yes 5
18 2nd Yes 11
19 3rd Yes 13
20 Crew Yes 0
21 1st Yes 1
22 2nd Yes 13
23 3rd Yes 14
24 Crew Yes 0
25 1st Yes 57
26 2nd Yes 14
27 3rd Yes 75
28 Crew Yes 192
29 1st Yes 140
30 2nd Yes 80
31 3rd Yes 76
32 Crew Yes 20
# 设置标签角度为90度,使之垂直于坐标轴
<- 90
myangle
# 设置颜色调色板
<- brewer.pal(8, "Set3")
palette
# 绘制玫瑰图
<- ggplot(df1, aes(x = 生还, y = 人数, fill = Class)) +
p1 geom_col(width = 1, colour = "grey20") + # 绘制条形图
coord_polar(theta = "y") + # 转化成极坐标图
scale_fill_manual(values = palette) + # 使用自定义颜色调色板
theme(axis.text.x = element_text(size = 5, angle = myangle, hjust = 1)) + # 设置坐标轴标签字体大小和角度
ylab("人数") + # 设置y轴标签
ggtitle("(a) 按人数顺序排序") # 设置图表标题
<- p1 + geom_text_repel(aes(label = 人数), size = 2, color = "grey30", box.padding = 0.5, max.overlaps = Inf)
p1 print(p1)
6.4 介绍图形特点和信息
- 扇形是按照人数排列顺序,是根据人数从高到低排列。
7 饼环图
绘制Class和 Sex的饼环图。
7.1 数据准备
<-data |>
dfselect(Class,Sex,Freq) |>
summarise(n=sum(Freq),.by=Class,Sex) |>
rename(乘客舱位=Class,性别=Sex,人数=n ) |>
arrange(desc(人数)) |>
mutate(百分比 = 人数*100/sum(人数))
datatable(df,rownames = FALSE)
7.2 利用ggiraphExtra::ggPieDonut()
作饼环图
library(ggiraphExtra)
<-ggPieDonut(data=df,aes(pies=乘客舱位,donuts=性别),
p1title="(a) 乘客舱位为饼图,性别为环形图")
<-ggPieDonut(data=df,aes(pies=性别,donuts=乘客舱位),
p2title="(b) 性别为饼图,乘客舱位为环形图")
grid.arrange(p1,p2,ncol=2)
7.3 介绍图形特点和信息
- 图形显示了三等舱男性遇难者群体最多,女性乘客在各舱位的生还人数都比较多。