第三章 类别数据可视化

Author

221527210刘念佳音

1 解释原始数据

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

    Class(船舱等级)

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

    类型:有序分类变量(反映社会等级)

    Sex(性别)

    类别:Male(男性)、Female(女性)

    类型:名义分类变量

    Age(年龄)

    类别:Child(儿童)、Adult(成人)

    类型:分类变量(原始数据中年龄为连续变量,但此处已分组)

    Survived(是否幸存)

    类别:No(否)、Yes(是)

    类型:二分类变量(目标变量)

    Freq(频数)

    类型:数值型变量,表示对应组合的乘客人数。

data = as.data.frame(Titanic)
DT::datatable(data,rownames = FALSE)

2 条形图

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

2.1 数据准备

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

    这段代码对原始数据(泰坦尼克号数据集)进行了以下处理:

    数据选择:提取 Sex(性别)、Survived(生还状态)、Freq(频数)三列关键变量。

    分组汇总:按性别和生还状态分组,计算每组的总人数(sum(Freq))。

    列名重命名:将列名改为中文(性别、生还、人数),提高可读性。

    目的: 将原始的列联表数据转换为简洁的统计格式,便于后续分析和可视化(如绘制条形图时直接使用中文标签)。交互式表格(DT::datatable)用于快速验证数据处理结果。

# 数据准备
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_x_discrete(
    "性别",
    labels = c(
      "Male" = "男性",
      "Female" = "女性"
    )
  )+
  scale_fill_discrete(
    "生还",
    labels = c(
      "No" = "否",
      "Yes" = "是"
    )
  )

# 图(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(
      "Male" = "男性",
      "Female" = "女性"
    )
  )+
  scale_fill_discrete(
    "生还",
    labels = c(
      "No" = "否",
      "Yes" = "是"
    )
  )

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")+# 绘制条形图
  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 介绍图形特点和信息

  • 累积百分比曲线展示泰坦尼克号各舱位人数分布:3等舱(706人)占比最高使曲线陡升,2等舱(285人)占比最少,反映明显的阶级差异。

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)+ylab("百分比(%)")+
  geom_bar(stat = "identity",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 = df1,aes(x=Survived,y=percent,fill=Class),stat = "identity",
        palette = "Blues",labelsize = 3,reverse = TRUE)

4.4 介绍图形特点和信息

  • 脊形图直观对比泰坦尼克号不同群体的生还率:1等舱生还率最高(45.2%),船员和3等舱较低(29.8%/25%),清晰展现阶级差异对生存机会的影响。

5 树状图和旭日图

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

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

df <- data %>% select(Class,Sex,Age,Survived,Freq) %>% 
  summarise(n=sum(Freq),.by=c(Class,Sex,Age,Survived)) %>% 
  rename(乘客舱位=Class,性别=Sex,年龄=Age,生还=Survived,人数=n)

DT::datatable(df,rownames = FALSE)
#分层顺序:乘客舱位-性别-年龄-生还
treemap(df,index=c("乘客舱位","性别","年龄","生还"),  # 设置聚合索引的列名称
        vSize="人数",                                  # 指定矩形大小的列名称
        #fontsize.labels=9,                             # 设置标签字体大小
        position.legend="bottom",                      # 设置图例位置
        title="分层顺序:乘客舱位-性别-年龄-生还")

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

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

5.3 介绍图形特点和信息

树状图分层展示泰坦尼克号遇难者特征:按舱位→性别→年龄→生还状态逐级细分,直观呈现不同群体(如头等舱女性儿童)的生还优势,揭示阶级和人口因素对生存率的影响。

旭日图通过环形分层展示泰坦尼克号数据:从外到内依次为舱位、性别、年龄和生还状态,扇形面积代表数量比例,直观揭示高舱位女性儿童生还率最高的生存规律。

6 热图和南丁格尔玫瑰图

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

6.1 数据准备

df <- data %>% select(Class,Survived,Freq) %>% 
  summarise(n=sum(Freq),.by=c(Class,Survived)) %>% 
  rename(乘客舱位=Class,生还=Survived,人数=n)

DT::datatable(df,rownames = FALSE)

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

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

library(ggiraphExtra)
p1<-ggHeatmap(df,aes(x=乘客舱位,y=生还,fill=人数),          # 绘制矩形热图
              addlabel=TRUE,                                      # 添加数值标签
              palette="Reds")+                                    # 使用红色调色板
  ggtitle("矩形热图")                            # 添加标题
p2<-ggHeatmap(df,aes(x=乘客舱位,y=生还,fill=人数),polar=TRUE,
              addlabel=TRUE,palette="Reds")+                      # 绘制极坐标热图
  ggtitle("极坐标热图")

grid.arrange(p1,p2,ncol=2)

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

library(ggrepel)
# 只分析生还者数据
df_survived <- df %>% filter(生还 == "Yes")

# 将舱位转为有序因子
df_survived <- df_survived %>%
  mutate(乘客舱位 = fct_reorder(乘客舱位, 人数))  # 按人数排序

# 调色板设置
palette <- brewer.pal(nlevels(df_survived$乘客舱位), "Set3")

# 标签角度计算(放射状排列)
n_categories <- nrow(df_survived)
myangle <- 90 - 360 * (1:n_categories - 0.5) / n_categories

# 绘制玫瑰图
ggplot(df_survived, aes(x = 乘客舱位, y = 人数, fill = 乘客舱位)) +
  geom_col(width = 1, color = "grey20") +
  scale_fill_manual(values = palette) +
  coord_polar(theta = "x", start = 0) +
  theme_minimal() +
  theme(
    axis.text.x = element_text(size = 8, angle = myangle, hjust = 0.5),
    axis.title.y = element_blank(),
    panel.grid = element_blank(),
    legend.position = "none"
  ) +
  labs(title = "各舱位生还人数玫瑰图") +
  geom_text_repel(
    aes(label = 人数),
    size = 4,
    color = "black",
    point.padding = 0.5,
    min.segment.length = 0
  )

6.4 介绍图形特点和信息

  • 热力图通过色块大小和颜色深浅,直观对比泰坦尼克号各舱位生还情况:矩形热图显示3等舱遇难最多(673人),极坐标热图突出1等舱生还优势(203人),共同揭示舱位等级对生存率的显著影响。

  • 南丁格尔玫瑰图以扇形面积直观展示泰坦尼克号各舱位生还人数差异:1等舱生还最多(203人),3等舱最少(178人),船员舱突出(206人),环形布局强化了舱位等级与生存人数的关联性。

7 饼环图

绘制Class和 Sex的饼环图。

7.1 数据准备

# 数据准备
df <- data %>% select(Class,Sex,Freq) %>% 
  summarise(n=sum(Freq),.by=c(Class,Sex)) %>% 
  rename(乘客舱位=Class,性别=Sex,人数=n)

DT::datatable(df,rownames = FALSE)

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

library(ggiraphExtra)

ggPieDonut(df,aes(pies=性别,donuts=乘客舱位,count=人数),
  title="性别为饼图,乘客舱位为环形图")

7.3 介绍图形特点和信息

  • 饼环图通过双层结构展示泰坦尼克号数据:内环为性别比例(女性21.4%,男性78.6%),外环细分各舱位占比(如3等舱23.2%),直观呈现乘客构成与阶级分布特征。