data = as.data.frame(Titanic)
DT::datatable(data,rownames = FALSE)第三章 类别数据可视化
1 解释原始数据
Titanic数据集是datasets包的配套案例数据,可以通过as.data.frame将其转化为数据框。解析数据包含哪些变量,如果是分类变量分别有哪些类别?
2 条形图
绘制Sex和 Survived的并列条形图和堆叠条形图,并为条形图添加频数标签。
2.1 数据准备
下面代码作了什么数据处理?为什么要这样处理?
从原始数据
data中选择了Sex、Survived和Freq三列,按Sex和Survived分组,计算每组的Freq总和,并将结果存储在n列中,将列名重命名为中文:Sex→性别,Survived→生还,n→人数.选择特定列是为了聚焦于分析性别与生还率的关系,按性别和生还状态分组求和,是为了得到每个组合的总人数(比如男性生还者总数、女性遇难者总数等)
# 数据准备
df <- data %>% select(Sex,Survived,Freq) %>%
summarise(n=sum(Freq),.by=c(Sex,Survived)) %>%
rename(性别=Sex,生还=Survived,人数=n)
DT::datatable(df,rownames = FALSE)2.2 利用geom_col函数作图
# 图(a)垂直并列条形图
p1<-ggplot(df,aes(x=性别,y=人数,fill=生还))+
geom_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) 水平并列条形图
p2<-ggplot(df,aes(x=性别,y=人数,fill=生还))+
geom_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)垂直并列条形图
p1<-ggplot(df,aes(x=性别,y=人数,fill=生还))+
geom_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) 水平并列条形图
p2<-ggplot(df,aes(x=性别,y=人数,fill=生还))+
geom_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)垂直并列条形图
p1<-ggplot(df,aes(x=性别,y=人数,fill=生还))+
geom_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("男","女" )
)+
scale_fill_discrete(
"生还",
labels = c("否","是" )
)
# 图(b) 水平并列条形图
p2<-ggplot(df,aes(x=性别,y=人数,fill=生还))+
geom_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_x_discrete(
"性别",
labels = c("男","女" )
)+
scale_fill_discrete(
"生还",
labels = c("否","是" )
)
grid.arrange(p1,p2,ncol=2) # 按2列组合图形2.3 介绍图形特点和信息
- 垂直并列条形图的不同类别的条形并排排列,便于直接比较同一分组内不同类别的值。垂直堆叠条形图,不同类别的条形堆叠在一起,形成整体条形,同时显示部分与整体的关系。从图中可以看出,不同性别的存活人数虽然大致相同,但女性的存活比例明显大于男性的存活比例。
3 帕累托图
绘制Class 的帕累托图。
3.1 数据准备
df<-data |>
select(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()等函数作图
palette<-rev(brewer.pal(4,"Reds")) # 设置调色板
# 绘制条形图
p<-ggplot(df)+aes(x=乘客舱位,y=人数)+
geom_col(width=0.8,fill=palette,color="grey50")+# 绘制条形图
scale_x_discrete(labels=c("食品烟酒","衣着","居住","生活用品\n及服务","交通通信","教育文化\n娱乐","医疗保健","其他用品\n及服务"))+ # 将x轴的长标签折行
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") # 删除图例
# 绘制折线和点
p1<-p+geom_line(aes(x=as.numeric(乘客舱位),y=累积百分比*max(人数/100)))+ # 绘制累积百分比曲线
geom_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)))# 添加坐标轴
p1+annotate("text",x=4.5,y=800,label="百分比(%)",angle=90,size=3.5)+
annotate("text",x=3,y=700,label="累积百分比曲线",size=3.5) # 添加注释文本3.3 介绍图形特点和信息
左侧Y轴(主坐标轴):显示绝对数量
右侧Y轴(次坐标轴):显示百分比
X轴:4个消费类别(食品烟酒、衣着、居住、生活用品及服务)
柱状图表示各分类的绝对数量
折线图表示百分比曲线
4 脊形图
绘制Class和 Survived 的脊形图。
4.1 数据准备
df<- data |> select(Class,Survived,Freq) %>%
summarise(n=sum(Freq),.by=c("Class","Survived")) %>%
mutate(percent=n*100/sum(n),.by=Survived)
datatable(df,rownames = FALSE)4.2 利用geom_col() 作图
ggplot(df)+aes(x=Survived,y=percent,fill=Class)+ylab("百分比(%)")+
geom_col(width=0.8,color="grey50")+
scale_fill_brewer(palette="Blues")4.3
df1<- df %>% mutate(
Class=factor(Class,levels=c("Crew","3rd","2nd","1st"))
)
ggSpine(data=df,aes(x=Survived,y=percent,fill=Class),stat ="identity",
palette = "Reds",labelsize = 3,reverse = TRUE)#反转调色板颜色4.4 介绍图形特点和信息
X轴:
表示 乘客类别,包括:
Crew(船员)1st(头等舱)2nd(二等舱)3rd(三等舱)
Y轴:
- 表示 百分比比例
每个类别的总高度为 100%,分割为两部分
生还率差异:
头等舱(1st) 生还率最高,未生还率最低。
三等舱(3rd) 生还率最低,未生还率最高。
船员(Crew) 生还率居中,但未生还比例显著。
社会阶层影响:
舱位等级越高(1st > 2nd > 3rd),生还率越高,反映救援时的优先级差异。
船员因职责所在,生还率低于头等舱乘客。
5 树状图和旭日图
绘制Class、Sex、Age和Survived4个变量的矩形树状图和旭日图
5.1 利用treemap::treemap()函数作树状图
df<-data%>%
ftable()%>%
as.data.frame()%>%
rename(频数=Freq) # 将Freq命名为频数
datatable(df,rownames = FALSE)df$频数<-as.numeric(df$频数)
treemap(df,index=c("Class","Sex","Age","Survived"), # 设置聚合索引的列名称
vSize="频数", # 指定矩形大小的列名称
#fontsize.labels=9, # 设置标签字体大小
position.legend="bottom", # 设置图例位置
title="(a) 分层顺序:Class—Sex—Age-Survived")5.2 利用sunburstR::sunburst() 函数作旭日图
- 通过
d3r::d3_nest将数据框转化为层次数据“d3.js”作为绘图输入
library(d3r)
df<-data%>%select("Class","Sex","Age","Survived") # 根据需要调整列变量的位置
df_tree<-d3_nest(df,value_cols="Survived") # 将数据框转换为“d3.js”层次结构
datatable(df,rownames = FALSE)library(sunburstR)
sunburst(data=df_tree, # 绘制旭日图
valueField="Survived", # 计算大小字段的字符为vSize
count=TRUE, # 在解释中包括计数和总数
sumNodes=TRUE) # 默认总和节点=TRUE5.3 树状图:每个矩形代表一个类别,子类别以嵌套形式显示在父类别矩形内,直观展示数据的层级关系;矩阵面积代表述职大小;适合展示整体中个部分比例的关系。
6 热图和南丁格尔玫瑰图
绘制Class和Survived 的点阵图、热图和南丁格尔玫瑰图。
6.1 数据准备
df<-data%>%ftable()%>%
as.data.frame()%>%
rename(人数=Freq) 6.2 利用ggiraphExtra::ggHeatmap()作热力图
分别作矩形热图和极坐标热图
library(ggiraphExtra)
p1<-ggHeatmap(df,aes(x="Class",y="Sex"), # 绘制矩形热图
addlabel=TRUE, # 添加数值标签
palette="Reds")+ # 使用红色调色板
ggtitle("(a1) 矩形热图") # 添加标题
p2<-ggHeatmap(df,aes(x="Class",y="Sex"),polar=TRUE,
addlabel=TRUE,palette="Reds")+ # 绘制极坐标热图
ggtitle("(a2) 极坐标热图")
p3<-ggHeatmap(df,aes(x="Survived",y="Sex"),
addlabel=TRUE,palette="Blues")+ # 使用蓝色调色板
ggtitle("(b1) 矩形热图")
p4<-ggHeatmap(df,aes(x="Survived",y="Sex"),polar=TRUE,
addlabel=TRUE,palette="Blues")+
ggtitle("(b2) 极坐标热图")
grid.arrange(p1,p2,p3,p4,ncol=2) # 按2列组合图形p1、p2、p3、p46.3 利用ggiraphExtra::ggRose() 作玫瑰图
df <- data %>%
group_by(Class, Survived) %>%
summarise(Freq = sum(Freq), .groups = "drop") %>%
mutate(
Class = fct_inorder(Class), # 将 Class 转为有序因子
Survived = fct_rev(Survived) # 反转因子顺序(保证"Yes"在前)
)
# 设置标签角度(避免重叠)
myangle <- seq(-20, -340, length.out = nlevels(df$Class))
# 图1:x轴为 Class(舱位等级),填充色为 Survived
p1 <- ggRose(df,
aes(x = Class, y = Freq, fill = Survived),
stat = "identity",
palette = "Reds", # 红色系配色
reverse = FALSE) +
ylab("乘客数量") +
guides(fill = guide_legend(nrow = 1, title = "是否幸存")) +
theme(legend.position = "bottom",
plot.title = element_text(size = 10),
axis.text.x = element_text(size = 8, color = "black", angle = myangle)) +
ggtitle("(a) 按舱位等级分布的生存情况")
# 图2:x轴为 Survived(是否幸存),填充色为 Class
p2 <- ggRose(df,
aes(x = Survived, y = Freq, fill = Class),
stat = "identity",
palette = "Blues", # 蓝色系配色
reverse = FALSE) +
ylab("乘客数量") +
guides(fill = guide_legend(nrow = 1, title = "舱位等级")) +
theme(legend.position = "bottom",
plot.title = element_text(size = 10),
axis.text.x = element_text(size = 8, color = "black")) +
ggtitle("(b) 按生存状态分布的舱位情况")
# 组合图形
gridExtra::grid.arrange(p1, p2, ncol = 2)6.4 介绍图形特点和信息
矩形热图:在直角坐标系中,用颜色深浅或色阶表示矩阵数据的值。通常以矩形色块排列成网格形式。
极坐标热图:在极坐标系中,用颜色或扇形区域展示数据的分布。角度轴(θ):表示周期性变量(如时间、方向)。半径轴(r):表示数值大小或层级。
玫瑰图:将条形图转换为极坐标系下的扇形区域,每个扇区的角度代表分类变量,半径长度代表数值大小。适合展示周期性数据或方向性分布(如风向、时间分布等)。图 (a):扇形区域按舱位等级划分,颜色深浅表示是否幸存,直观对比不同舱位的生存率。图 (b):扇形区域按生存状态划分,颜色表示舱位等级,揭示幸存者的舱位分布差异。
7 饼环图
绘制Class和 Sex的饼环图。
7.1 数据准备
tab1<-table(df$Class) # 生成频数表
name<-names(tab1) # 设置名称向量
percent<-prop.table(tab1)*100 # 计算百分比
labs<-paste(name," ",percent,"%",sep="") # 设置标签向量
pie(tab1,labels=labs,init.angle=90,radius=1,col=c("red1","green1","turquoise1"))7.2 利用ggiraphExtra::ggPieDonut()作饼环图
df <- data%>%
group_by(Class, Sex) %>%
summarise(Freq = sum(Freq), .groups = "drop")
library(ggiraphExtra)
p1<-ggPieDonut(df,aes(pies="Class",donuts="Sex"),
title="(a) Class为饼图,Sex为环形图")
p2<-ggPieDonut(df,aes(pies="Sex",donuts="Class"),
title="(b) Class为饼图,Sex为环形图")
grid.arrange(p1,p2,ncol=2)7.3 介绍图形特点和信息
外环(饼图):表示 舱位等级(Class),分为
1st(头等舱)、2nd(二等舱)、3rd(三等舱)、Crew(船员)。内环(环形图):表示 性别(Sex),分为
Male(男性)、Female(女性)