第三章 类别数据可视化

Author

221527115杨诗婷

1 解释原始数据

  • Titanic数据集是datasets包的配套案例数据,可以通过as.data.frame将其转化为数据框。解析数据包含哪些变量,如果是分类变量分别有哪些类别?
  • Titanic数据集包含5个变量:
    1. 分类变量

      • Class:4类(1st头等舱、2nd二等舱、3rd三等舱、Crew船员)

      • Sex:2类(Male男性、Female女性)

      • Age:2类(Child儿童、Adult成人)

      • Survived:2类(No死亡、Yes存活)

    2. 数值变量

      • Freq:记录每个分类组合的具体人数
data = as.data.frame(Titanic)
DT::datatable(data,rownames = FALSE)

2 条形图

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

2.1 数据准备

  • 下面代码作了什么数据处理?为什么要这样处理?

  • 这段代码将数据按ClassSex分组并汇总Freq,以便计算每个组合的频数。然后使用ggPieDonut分别绘制两种饼环组合图:

    1. p1Class为饼图(主分类),Sex为环形图(子分类)

    2. p2Sex为饼图(主分类),Class为环形图(子分类)

    目的:直观展示两个分类变量的分布关系,通过不同视角分析数据的组成结构。

# 数据准备
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) 垂直并列条形图")+
  scale_fill_brewer(
   "性别",
   label=c("男","女")
 )+
  scale_fill_discrete(
     "生还",
     label=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) 垂直堆叠条形图")

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

2.3 介绍图形特点和信息

  • 条形图特点
    • 用长短不同的条形表示各类别的数值大小。
    • 分类对比:适合比较不同类别间的绝对差异。

    信息:直观展示离散变量的分布或比较。


    2.3.1 堆叠条形图特点: - 条形分段堆叠,总高度表示总和,各段表示子类别占比 ,同时展示整体规模和内部结构。

    2.3.2 信息:揭示主分类的总量及子分类的组成比例(如每个Class中男女的比例)。

2.3.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 介绍图形特点和信息

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 利用ggiraphExtra包ggSpine()

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 介绍图形特点和信息

  • 4.4.1 图形特点

    1. 结构类型

      • 采用分层可视化形式(主类别+子类别结构)

      • 主类别为 Class(Crew / Survived两组)

      • 每个主类别下包含4个子项(未标注具体名称)

    2. 数据呈现

      • 使用百分比占比(总和100%)

      • 通过扇区面积直观反映比例关系

      • 颜色区分不同子项(假设)

    3. 对比设计

      • 并排显示两组数据(Crew vs Survived)

      • 突出组内分布差异

5 树状图和旭日图

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

df<-data%>%
  ftable()%>%
  as.data.frame()%>%
  rename(频数=Freq) # 将Freq命名为频数

datatable(df,rownames = FALSE)

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

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,           # 绘制旭日图
   valueField="Survived",    # 计算大小字段的字符为vSize
   count=TRUE,                   # 在解释中包括计数和总数
   sumNodes=TRUE)                # 默认总和节点=TRUE
Legend

5.3 介绍图形特点和信息

5.3.1 1. 树状图(Treemap)

  • 特点

    • 嵌套矩形表示层级,矩形面积大小对应Survived数值。

    • 外层矩形为Class,内部按SexAge进一步分割。

    • 颜色区分不同类别(如不同Class)。

  • 信息

    • 直观比较各类别的总量(如“First Class”下男女生存人数差异)。

    • 适合快速识别主导群体(面积最大的矩形)。

5.3.2 2. 旭日图(Sunburst)

  • 特点

    • 同心圆环表示层级,从外到内依次为Class→Sex→Age,扇区角度反映Survived占比。

    • 支持交互(点击钻取查看细分数据)。

  • 信息

    • 展示数据流动路径(如“Crew→Male→Adult”的生存比例)。

    • 强调层次结构和比例关系(如某SexClass中的分布)。

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、p4

6.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 介绍图形特点和信息

  • 6.4.0.1 热图(Heatmap)

    • 特点:用颜色深浅表示数值大小(如生存率/人数),行和列对应分类变量(如Class和Sex)

    • 优点:直观显示数据分布和异常值,适合比较多维数据组合

    • 适用:分析不同舱位(Class)和性别(Sex)的生存率差异

    6.4.0.2 南丁格尔玫瑰图(Rose Chart)

    • 特点:用扇形半径长度表示数值,角度均分各分类

    • 优点:突出不同类别的绝对数值对比,视觉效果冲击力强

    • 适用:比较各舱位(Class)的生存人数总量

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 介绍图形特点和信息

  • 7.3.1 图形特点

    1. 双环结构

      • 外环(饼图):显示主分类(如Class)的总体占比。

      • 内环(环形图):嵌套在外环内,展示子分类(如Sex)在每一类Class中的分布。

    2. 比例可视化:通过扇区面积和颜色区分不同类别,直观呈现数据的层级关系。

    7.3.2 信息呈现

    • 外环:反映不同舱位(如头等舱、二等舱)的总体占比。

    • 内环:展示每个舱位中性别(如男、女)的构成比例。

    • 交互性(可选):悬停时可显示具体数值或百分比。

    7.3.3 优势

    • 在一张图中清晰呈现两层数据的分布。

    • 比单独使用饼图或环形图更节省空间,且层次分明。

    7.3.4