第三章 类别数据可视化

Author

221527209 王琳慧

1 解释原始数据

  • Titanic数据集是datasets包的配套案例数据,可以通过as.data.frame将其转化为数据框。解析数据包含哪些变量,如果是分类变量分别有哪些类别?
  • 数据包含5个变量,分别是船舱、性别、年龄、生还情况、人数;分类变量包含船舱、性别、年龄、生还情况。
data = as.data.frame(Titanic)
DT::datatable(data,rownames = FALSE)

2 条形图

绘制Sex和 Survived的并列条形图和堆叠条形图,并为条形图添加频数标签。

2.1 数据准备

  • 下面代码作了什么数据处理?为什么要这样处理?
  • 将data文件中的性别、生还情况、人数三个变量取出来命名为df文件,重新命名三个变量名称为中文。
# 数据准备
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 <- data %>% select(Sex,Survived,Freq) %>% 
  summarise(n=sum(Freq),.by=c(Sex,Survived)) %>% 
  rename(性别=Sex,生还=Survived,人数=n)

DT::datatable(df,rownames = FALSE)
df$性别 <- factor(df$性别, 
                levels = c("Male", "Female"),
                labels = c("男性", "女性"))

df$生还 <- factor(df$生还,
                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$人数))+      # 设置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列组合图形

2.3 介绍图形特点和信息

  • 上面两个条形图直观展示人数绝对数,可以得到男性生还的人数为367,较女性生还人数相比多了23人,但男性未生还的人数数量大,反映出男性死亡比例大;女性生还比例大。

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")+          # 绘制条形图
  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.5,y=700,label="累积百分比曲线",size=3.5)   # 添加注释文本

3.3 介绍图形特点和信息

  • 上图用乘客舱位和人数两个变量作有序条形图,从图中可得人数从船员舱人数最多,人数最低的是二等舱人数。

绘制Class和 Survived 的脊形图。

3.4 数据准备

# 数据处理

df<- data %>% select(Class,Survived,Freq)%>%
  summarise(n=sum(Freq),.by=c(Class,Survived))%>%
  mutate(percent=n*100/sum(n),.by="Survived")

datatable(df)

3.5 利用geom_col() 作图

# 确保 Class 是因子
df$Class <- as.factor(df$Class)

ggplot(df) +
  aes(x = Survived, y = percent, fill = Class) +
  ylab("百分比 (%)") +
  geom_bar(stat = "identity", width = 0.8, color = "grey50") +
  scale_fill_brewer(palette = "Blues") 

3.6 利用ggiraphExtra包ggSpine()

# 确保数据框名称一致,且列名正确
df1 <- df %>% 
  mutate(
    Class = factor(Class, levels = c("Crew", "3rd", "2nd", "1st"))
  )

# 调用 ggSpine 时使用正确的数据框和参数
ggSpine(
  data = df1, 
  mapping = aes(x = Survived, y = percent, fill = Class),
  stat = "identity",
  palette = "Blues",
  labelsize = 3,
  reverse = FALSE  # 根据实际需求调整是否反转
)

3.7 介绍图形特点和信息

  • 图形为堆叠柱状图,展示不同舱位等级(Class)在幸存(Yes)与未幸存(No)中的比例分布。头等舱(1st)在幸存者中占比最高(45.2%),显著高于未幸存比例(8.2%),表明头等舱乘客的生存机会明显更高二等舱(2nd)幸存比例(35.4%)也高于未幸存(11.2%),但差距小于头等舱。

  • 结论:舱位等级越高,生存率越高,反映了泰坦尼克号事件中救援优先级与社会经济地位的相关性

4 树状图和旭日图

绘制Class、Sex、Age和Survived4个变量的矩形树状图和旭日图

4.1 利用treemap::treemap()函数作树状图

# 数据预处理
df <- Titanic %>%
  as.data.frame() %>%
  rename(count = Freq)  # 使用英文列名提高兼容性

# 生成树状图(分层为 Sex -> Class -> Survived,共3层)
treemap(df,
        index = c("Sex", "Class", "Survived"),  # 三层分组:性别 -> 舱位 -> 生存状态
        vSize = "count",       # 矩形大小基于频数
        vColor = "count",       # 颜色深度基于频数
        type = "value",         # 按数值映射颜色
        palette = "Blues",      # 使用蓝色渐变色板
        fontsize.labels = c(12, 10, 8),  # 分层标签字体大小(从外到内)
        fontcolor.labels = c("white", "white", "black"),  # 标签颜色适配背景
        border.col = "grey90",  # 边框颜色
        position.legend = "bottom",
        title = "Titanic乘客生存分层分析(Sex -> Class -> Survived)")

4.2 利用sunburstR::sunburst() 函数作旭日图

  • 通过d3r::d3_nest将数据框转化为层次数据“d3.js”作为绘图输入
library(d3r)
df<-data%>%select("Age","Sex","Class","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)                # 默认总和节点=TRUE
Legend

4.3 介绍图形特点和信息

  • 旭日图是一种多层环形图,通过同心圆的分层结构展示数据的层次关系。每一层代表一个分类变量,环形的宽度(扇形角度)由频数(Freq)决定。由于定义了分层顺序:Age -> Sex -> Class -> Survived,即内层到外层:年龄(Adult/Child)→ 性别(Male/Female)→ 舱位等级(Crew/1st/2nd/3rd)→ 生存状态(Yes/No)。Adult(成人)占比最大(39.2%),对应860人,说明泰坦尼克号乘客以成年人为主。Crew(船员)在成人男性中占比较高,但生存率较低(未幸存比例高)。性别差异:女性(Female)和儿童(Child)生存率显著高于男性(Male)。

  • 该旭日图直观揭示了泰坦尼克号乘客数据的多层次关联:

    • 生存率核心驱动因素:性别、舱位等级和年龄。

    • 社会不平等体现:头等舱乘客和妇孺群体的生存优势显著。

5 热图和南丁格尔玫瑰图

绘制Class和Survived 的点阵图、热图和南丁格尔玫瑰图。

5.1 数据准备

df<-data%>%ftable()%>%
  as.data.frame()%>%
  rename(人数=Freq) 

5.2 利用ggiraphExtra::ggHeatmap()作热力图

分别作矩形热图和极坐标热图

library(ggiraphExtra)
p1<-ggHeatmap(data,aes(x=Class,y=Survived,fill = Freq),          # 绘制矩形热图
   addlabel=TRUE,                                      # 添加数值标签
   palette="Reds")+                                    # 使用红色调色板
   ggtitle("(a1) 矩形热图")                            # 添加标题
p2<-ggHeatmap(data,aes(x=Class,y=Survived,fill = Freq),polar=TRUE,
   addlabel=TRUE,palette="Reds")+                      # 绘制极坐标热图
   ggtitle("(a2) 极坐标热图")


grid.arrange(p1,p2,ncol=2)             # 按2列组合图形p1、p2、p3、p4

5.3 利用ggiraphExtra::ggRose() 作玫瑰图

data$Class <- factor(data$Class, ordered = TRUE, 
                     levels = c("1st", "2nd", "3rd", "Crew"))
                                          # 将支出项目变为有序因子
df1 <- data %>%                           # 提取北京数据,构建新的数据框
  group_by(Class,Survived)%>%
  summarise(Count = sum(Freq), .groups = "drop")      
    
# 设置标签角度,使之垂直于坐标轴
myangle<-seq(-20,-340,length.out=4)   
palette<-brewer.pal(6,"Spectral")            # 设置离散型调色板

# 绘制玫瑰图
p1<-ggplot(df1,aes(x=Class,y=Count,fill=Survived,))+           
  geom_col(width=1,colour="grey20",position = "stack")+# 绘制条形图
  scale_fill_manual(values = palette) +
  coord_polar(theta="x",start=0)+   # 转化成极坐标图
  theme(axis.text.x=element_text(size=8,angle=myangle))+ # 设置坐标轴标签字体大小和角度
  ylab("人数")+                   # 设置y轴标签
  ggtitle("(a) 泰坦尼克号乘客生存情况")
  

library(ggrepel)
p1<-p1+geom_text_repel(aes(y=Count-100,label=Count),size=2.5,color="grey30")# 为图形添加文本,并设置文本字体大小和颜色

gridExtra::grid.arrange(p1)

5.4 介绍图形特点和信息

  • 南丁格尔玫瑰图(极坐标堆叠柱状图),通过环形扇区的大小和颜色展示不同舱位等级(Class)的乘客生存(Yes)与未幸存(No)人数分布。舱位等级与生存率的关系中,船员(Crew)未幸存比例极高(红色主导)。该玫瑰图直观揭示了泰坦尼克号乘客生存状态与舱位等级的强相关性,社会阶层差异体现在头等舱乘客生存机会远高于低舱位和船员。

6 饼环图

绘制Class和 Sex的饼环图。

6.1 数据准备

# 数据预处理修正
df <- Titanic %>%
  as.data.frame() %>%
  group_by(Sex, Class) %>%
  summarise(人数 = sum(Freq), .groups = "drop") %>%
  rename(性别 = Sex, 乘客舱位 = Class)

DT::datatable(df,rownames = FALSE)

6.2 利用ggiraphExtra::ggPieDonut()作饼环图

# 绘制饼环图(使用支持的参数)
pl <- ggPieDonut(
  data = df,
  aes(pies = 乘客舱位, donuts = 性别, count = 人数),
  title = "泰坦尼克号乘客分布:舱位与性别"
)

# 自定义颜色和标签(通过 ggplot2 函数)
pl <- pl +
  # 手动指定颜色
  scale_fill_manual(
    values = c("1st" = "#66C2A5", "2nd" = "#FC8D62", "3rd" = "#8DA0CB", "Crew" = "#E78AC3"),
    name = "舱位等级"
  ) +
  # 调整标签大小和位置
  theme(
    text = element_text(size = 10),          # 全局字体大小
    legend.position = "bottom",             # 图例位置
    axis.text = element_text(size = 8)      # 坐标轴标签大小
  )


# 输出图形
print(pl)

6.3 介绍图形特点和信息

  • 该图为饼环图(Pie-Donut Chart),结合了饼图和环形图的特性:内层饼图:展示乘客的舱位等级分布(1st、2nd、3rd、Crew)。外层环形图:展示各舱位内部性别比例(Male/Female)。通过内外层嵌套结构,直观呈现数据的层次关系。

  • 舱位分布:船员(40.2%)> 三等舱(32.1%)> 头等舱(14.8%)> 二等舱(12.9%)。

  • 性别比例

    • 头等舱女性占比显著(实际生存率高达97%),男性占比较少。

    • 船员群体几乎全为男性(标注应为 Male 99.7%, Female 0.3%)。