data = as.data.frame(Titanic)
DT::datatable(data,rownames = FALSE)第三章 类别数据可视化
1 解释原始数据
Titanic数据集是datasets包的配套案例数据,可以通过as.data.frame将其转化为数据框。解析数据包含哪些变量,如果是分类变量分别有哪些类别?Class(乘客舱位/等级) - 分类变量
- 类别:1st (头等舱), 2nd (二等舱), 3rd (三等舱), Crew (船员)
Sex(性别) - 分类变量
- 类别:Male (男性), Female (女性)
Age(年龄) - 分类变量
- 类别:Child (儿童), Adult (成人)
Survived(是否幸存) - 分类变量
- 类别:No (未幸存), Yes (幸存)
Freq(频数) - 数值变量
- 表示每个组合类别中的乘客数量
2 条形图
绘制Sex和 Survived的并列条形图和堆叠条形图,并为条形图添加频数标签。
2.1 数据准备
下面代码作了什么数据处理?为什么要这样处理?
这段代码对Titanic数据集进行了数据汇总和重命名处理
简化分析目标:聚焦于核心变量(性别与生还率),忽略无关维度(如舱位、年龄)。
数据聚合:原始数据是分组的频数表,需汇总为每个性别和生还状态的总人数,才能计算比例(如女性生还率)。
可视化友好:交互式表格便于快速观察数据分布(如女性生还人数明显高于男性)。
# 数据准备
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列组合图形- 你可以通过修改数据或者修改刻度标签将图中性别和生还的类别标签改为中文,请给出代码完成修改。
# 修改数据框中的分类变量
df <- df %>%
mutate(
性别 = factor(性别, levels = c("Male", "Female"), labels = c("男性", "女性")),
生还 = factor(生还, levels = c("No", "Yes"), labels = c("未生还", "已生还")))
# 图(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$人数)) +
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.3 介绍图形特点和信息
这两幅图展示了泰坦尼克号乘客按性别划分的生还情况:
(a) 并列条形图
直接对比男女性的生还(367男/344女)和未生还人数(1384男/128女)。
显示男性遇难人数远超女性,而女性生还比例更高。
(b) 堆叠条形图
以堆叠形式呈现各性别的生还比例。
男性生还率仅约21%,女性高达73%,凸显“妇女儿童优先”政策的影响。
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()等函数作图
library(ggplot2)
library(scales) # 用于百分比格式
library(DT) # 用于交互式表格
# 准备数据
df <- as.data.frame(Titanic) |>
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)# 创建组合图表
ggplot(df, aes(x = 乘客舱位)) +
# 柱状图 - 各舱位人数(主Y轴)
geom_col(aes(y = 人数),
width = 0.6,
fill = "#1F77B4",
alpha = 0.7) +
# 折线图 - 累积百分比(次Y轴)
geom_line(aes(y = 累积百分比 * max(人数) / 100, group = 1),
color = "#FF7F0E",
linewidth = 1.2) +
# 点图 - 标记累积百分比点
geom_point(aes(y = 累积百分比 * max(人数) / 100),
color = "#FF7F0E",
size = 3) +
# 添加人数标签
geom_text(aes(y = 人数, label = 人数),
vjust = -0.5,
size = 3.5,
color = "black") +
# 添加累积百分比标签
geom_text(aes(y = 累积百分比 * max(人数) / 100,
label = paste0(累积百分比, "%")),
vjust = -1,
color = "#FF7F0E",
size = 3.5) +
# 设置双Y轴
scale_y_continuous(
name = "乘客人数",
expand = expansion(mult = c(0, 0.1)), # 为顶部标签留空间
sec.axis = sec_axis(~ . * 100 / max(df$人数),
name = "累积百分比(%)",
labels = function(x) paste0(x, "%"))
) +
# 图表标题和标签
labs(title = "泰坦尼克号各舱位乘客人数及累积百分比",
x = "乘客舱位") +
# 主题设置
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
axis.title.y.left = element_text(color = "#1F77B4"),
axis.text.y.left = element_text(color = "#1F77B4"),
axis.title.y.right = element_text(color = "#FF7F0E"),
axis.text.y.right = element_text(color = "#FF7F0E"),
panel.grid.major.x = element_blank()
)3.3 介绍图形特点和信息
- 这张图表展示了泰坦尼克号上不同舱位的乘客人数及累积百分比,采用柱状图与折线图结合的形式。数据显示:船员(Crew)人数最多(706人),其次为三等舱(385人)、一等舱(400人)和二等舱(250人)。累积百分比表明,船员与三等舱乘客占总人数的72.3%,加上一等舱后达87.1%,最终覆盖全部乘客。图表直观呈现了舱位分布及比例关系。
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)4.2 利用geom_col() 作图
ggplot(df) +
aes(x = Survived, y = percent, fill = Class) +
geom_bar(
stat = "identity",
width = 0.8,
color = "grey50", # 边框颜色
linewidth = 0.3 # 边框粗细
) +
scale_fill_brewer(
palette = "Blues", # 使用Blues调色板
name = "舱位等级", # 修改图例标题
labels = c("一等舱", "二等舱", "三等舱", "船员") # 自定义图例标签
) +
labs(
title = "泰坦尼克号生还情况按舱位分布",
x = "生还状态",
y = "百分比 (%)"
) +
scale_x_discrete(
labels = c("No" = "未生还", "Yes" = "已生还") # 修改x轴标签
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, size = 14, face = "bold"), # 标题居中加粗
legend.position = "top", # 图例置于顶部
axis.text = element_text(size = 10), # 坐标轴文字大小
panel.grid.major.x = element_blank() # 隐藏x轴主要网格线
)4.3 利用ggiraphExtra包ggSpine()
ggSpine(data=df,aes(x=Survived,y=percent,fill=Class),stat="identity",
palette="Reds",labelsize=3,reverse=TRUE) # 反转调色板颜色4.4 介绍图形特点和信息
该图表以双向堆叠条形图的形式,对比了泰坦尼克号不同舱位乘客的生还比例。图表核心信息如下:
- 结构特征
- 左右分列显示未生还(No)与生还(Yes)两组数据
- 每组数据中各舱位(船员/1-3等舱)以比例形式堆叠呈现
- 每个舱位区块标注具体百分比数值
- 关键发现
- 未生还群体中船员占比最高(45.2%),三等舱次之(35.4%)
- 生还群体中一等舱比例最大(28.6%),二等舱次之(25%)
- 船员在生还组中比例最低(16.6%)
- 核心结论 图表清晰展现了舱位等级与生还率的显著相关性:高等级舱位乘客生还机会明显优于低舱位乘客和船员,直观反映了灾难中的社会阶层差异。船员群体在救援中处于最不利地位,未生还比例最高而生还比例最低。
5 树状图和旭日图
绘制Class、Sex、Age和Survived4个变量的矩形树状图和旭日图
5.1 利用treemap::treemap()函数作树状图
data = as.data.frame(Titanic)
DT::datatable(data,rownames = FALSE)# 图(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)
df<-data%>%select(Sex,Class,Age,Survived,Freq) # 根据需要调整列变量的位置
df_tree<-d3_nest(df,value_cols="Freq") # 将数据框转换为“d3.js”层次结构
datatable(df,rownames = FALSE)library(sunburstR)
sunburst(data=df_tree, # 绘制旭日图
valueField="Freq", # 计算大小字段的字符为vSize
count=TRUE, # 在解释中包括计数和总数
sumNodes=TRUE) # 默认总和节点=TRUE5.3 介绍图形特点和信息
该图形采用分层环形设计,最内层环表示性别,中间层环代表乘客舱位,最外层环则对应年龄信息,
6 热ndefined图和南丁格尔玫瑰图
绘制Class和Survived 的点阵图、热图和南丁格尔玫瑰图。
6.1 数据准备
library(dplyr)
library(DT)
df <- as.data.frame(Titanic) %>%
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)
p1 <- ggHeatmap(df,
aes(x = 乘客舱位, y = 生还情况, fill = 人数),
color = "white") +
scale_fill_gradient(low = "white", high = "red") +
ggtitle("泰坦尼克号生还情况矩形热图") +
theme_minimal()
p2 <- ggHeatmap(df,
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 转换为有序因子
f <- factor(data$Class, ordered = TRUE, levels = unique(data$Class))
# 构建新的数据框
df1 <- data.frame(Class = f, 生还 = data$Survived, 人数 = data$Freq)
# 使用 dplyr 重新构建数据框,并确保 Class 是有序因子
df1 <- data %>%
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度,使之垂直于坐标轴
myangle <- 90
# 设置颜色调色板
palette <- brewer.pal(8, "Set3")
# 绘制玫瑰图
p1 <- ggplot(df1, aes(x = 生还, y = 人数, fill = Class)) +
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 <- p1 + geom_text_repel(aes(label = 人数), size = 2, color = "grey30", box.padding = 0.5, max.overlaps = Inf)
print(p1)6.4 介绍图形特点和信息
- 扇形的排列顺序严格遵循人数多少,从高到低顺时针方向依次显示。
7 饼环图
绘制Class和 Sex的饼环图。
7.1 数据准备
df<-data |>
select(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)
# 假设你的数据框 df 已经按照上面的代码创建好了
# df <- data |> ...
# 使用 ggPieDonut 创建饼环图
ggPieDonut(
data = df,
aes(pies = 乘客舱位, donuts = 性别, count = 人数),
interactive = TRUE, # 设置为交互式图表
title = "乘客舱位与性别分布" # 添加标题
)7.3 介绍图形特点和信息
- 根据可视化结果可以看出,三等舱男性乘客的遇难人数最为突出,而女性乘客在各舱位中的生还比例普遍较高。