第三章 类别数据可视化

Author

221527101关子桃

1 解释原始数据

  • Titanic数据集是datasets包的配套案例数据,可以通过as.data.frame将其转化为数据框。解析数据包含哪些变量,如果是分类变量分别有哪些类别?
  • Class(乘客舱位等级)
    • 分类变量,表示乘客的社会经济阶层,分为4个类别:

      • 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 2.1数据准备

  • 下面代码作了什么数据处理?为什么要这样处理?
# 数据准备
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)

# 方法1:直接修改数据框中的因子水平(推荐)
df$性别 <- factor(df$性别, levels = c("Male", "Female"), labels = c("男性", "女性"))
df$生还 <- factor(df$生还, levels = c("Yes", "No"), 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) 垂直堆叠条形图")

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

  • 2.3介绍图形特点和信息

    2.3 垂直并列条形图

    2.3.1 图形特点

    1. 图表类型:纯色垂直并列条形图

    2. 坐标轴

      • X轴:性别(男/女)

      • Y轴:人数(0-1500区间)

    3. 数据展示

      • 每个性别分类下并列显示两个条形(代表生存/未生存)

      • 条形高度对应具体数值

    4. 视觉编码

      • 不同颜色区分生存状态(虽然具体颜色未说明,但应有区分)

      • 数值标签直接标注在条形上方

    2.3.2 数据信息

    1. 男性总数:1364人(367生还 + 未标注的未生还人数)

    2. 女性总数:344人(128生还 + 216未生还,根据总数推算)

    3. 生还率:

      • 男性生还率 ≈ 26.9%(367/1364)

      • 图形特点

    图表类型:纯色垂直并列条形图

    1. 坐标轴

      • X轴:性别(男/女)

      • Y轴:人数(0-1500区间)

    2. 数据展示

      • 每个性别分类下并列显示两个条形(代表生存/未生存)

      • 条形高度对应具体数值

    3. 视觉编码

      • 不同颜色区分生存状态(虽然具体颜色未说明,但应有区分)

      • 数值标签直接标注在条形上方

      • 2.4 垂直堆叠条形图

        2.4.1 图形特点

        1. 图表类型:垂直堆叠条形图

        2. 坐标轴

          • X轴:性别(男/女)

          • Y轴:人数(0-1500区间)

        3. 数据展示

          • 每个性别一个堆叠条形

          • 条形总高度表示该性别总人数

          • 分段显示生存/未生存构成

        4. 图例

          • 底部显示”No/Yes”图例(对应未生还/生还)

        2.4.2 数据信息

        1. 男性总人数:1384人(与并列图略有差异,可能是绘图误差)

        2. 女性总人数:344人(与并列图一致)

        3. 堆叠构成:

          • 男性条形明显高于女性

    2.4.3 数据信息

    1. 男性总数:1364人(367生还 + 未标注的未生还人数)

    2. 女性总数:344人(128生还 + 216未生还,根据总数推算)

    3. 生还率:

      • 男性生还率 ≈ 26.9%(367/1364)

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

    1. 图表类型

      • 主图表为累积百分比曲线图(帕累托曲线)

      • 可能结合了柱状图(显示绝对数值)和折线图(显示累积百分比)

    2. 坐标轴

      • X轴:消费类别(食品烟酒、衣着、居住、生活用品及服务)

      • 左Y轴:绝对数值(0-885区间,单位未标明但可能是元或支出金额)

      • 右Y轴:百分比(0%-100%)

    3. 数据展示

      • 柱状高度表示各类别的绝对数值

      • 曲线连接点表示累积百分比

      • 关键数值直接标注在图表上

    4. 特殊元素

      • 使用annotate("text")添加了”累积百分比曲线”标签(位于x=3,y=700位置)

      • 存在”家长百分比曲线”文字(可能是误写,应为”累积百分比曲线”)

    3.4 数据信息解读

    1. 绝对数值

      • 食品烟酒:885

      • 衣着:776

      • 居住:325

      • 生活用品及服务:285

    2. 百分比数据

      • 87.1%、72.3%、70.6%、75%等(具体对应关系不明确)

      • 100%标记出现在图表最右端

    3. 累积百分比曲线

      • 曲线从左到右逐渐上升

      • 在”食品烟酒”类别后达到第一个显著高点

      • 最终累积达到100%

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="red")

4.3 利用ggiraphExtra包ggSpine()

library(dplyr)
df1 <- df %>%
  group_by(Survived, Class) %>%
  summarise(perCent = sum(perCent), .groups = "drop")

library(ggplot2)

ggplot(df1, aes(x = Survived, y = perCent, fill = Class)) +
  geom_col(position = "fill", width = 0.8, color = "grey50") +
  scale_fill_brewer(palette = "Reds", direction = 1) +  # reverse=TRUE对应direction=-1
  geom_text(
    aes(label = paste0(perCent, "%")),
    position = position_fill(vjust = 0.5),
    size = 3, color = "white"
  ) +
  labs(x = "是否幸存", y = "百分比 (%)") +
  theme_minimal()

4.4 介绍图形特点和信息

  • 特点

  • 表格形式展示

    • 数据以两列百分比表格形式呈现

    • 左侧标注”Class”,下方有”No”和”Yes”标签

    • 百分比数值精确到小数点后一位

  • 数据结构

    • 第一组百分比(8.2%, 11.2%, 35.4%, 45.2%)可能对应不同舱位等级

    • 第二组百分比(28.6%, 16.6%, 25.0%, 29.8%)可能对应不同生存状态或其他分类

    信息

  • 舱位等级分布

    • 第一组数据可能表示:

      • 1st class: 8.2%

      • 2nd class: 11.2%

      • 3rd class: 35.4%

      • Crew: 45.2%

  • 生存状态分布

    • 第二组数据可能表示:

      • 某种分类1: 28.6%

      • 某种分类2: 16.6%

      • 某种分类3: 25.0%

      • 某种分类4: 29.8%

  • 底部标签

    • “No”和”Yes”可能对应生存状态(未幸存/幸存)或其他二元分类

5 树状图和旭日图

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

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

datatable(df,rownames = FALSE)

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

# 使用dplyr进行计数
library(dplyr)

df_agg <- df %>%
  group_by(Class, Sex, Age, Survived) %>%
  summarise(Freq = n(), .groups = "drop")  # 计算每组的观测数

# 然后使用df_agg绘图
treemap(df_agg, 
        index = c("Class", "Sex", "Age", "Survived"), 
        vSize = "Freq",
        vColor = "Survived", 
        type = "categorical", 
        palette = c("#FF0000", "#00FF00"),
        title = "性别—网购原因—满意度",
        fontsize.title = 14, 
        algorithm = "pivotSize", 
        overlap.labels = 0.5)

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

  • 通过d3r::d3_nest将数据框转化为层次数据“d3.js”作为绘图输入
library(sunburstR)
library(d3r)
library(dplyr)

data(Titanic)
df <- as.data.frame(Titanic)

# 准备数据:将分类变量转换为字符并合并路径
df_sunburst <- df %>%
  mutate(
    path = paste(Class, Sex, Age, Survived, sep = "-"),
    count = Freq
  ) %>%
  select(path, count)

# 查看前几行数据
head(df_sunburst)
                 path count
1   1st-Male-Child-No     0
2   2nd-Male-Child-No     0
3   3rd-Male-Child-No    35
4  Crew-Male-Child-No     0
5 1st-Female-Child-No     0
6 2nd-Female-Child-No     0
sunburst(
  data = df_sunburst,
  colors = list(
    range = c("#1f77b4", "#ff7f0e", "#2ca02c", "#d62728"),
    domain = c("1st", "2nd", "3rd", "Crew")
  ),
  legend = list(w = 200, h = 20, r = 3, s = 3),
  width = "100%",
  height = 500
)
Legend

5.3 介绍图形特点和信息

特点

  1. 多维度分类

    • 包含了乘客等级(1st, 2nd, 3rd, Crew)

    • 性别分类(Female, Male)

    • 年龄分类(Adult, Child)

    • 生存状态(No, Yes)

  2. 图例组织

    • 图例项按类别垂直排列

    • 不同类别混合排列(未分组显示)

    • 缺少颜色或形状的具体说明(仅有文字标签)

      信息

      1. 数据维度

        • 包含4个主要分类维度:

          • 舱位等级(4类)

          • 性别(2类)

          • 年龄(2类)

          • 生存结果(2类)

      2. 数据完整性

        • 覆盖了泰坦尼克号数据集的主要分类变量

        • 缺少连续变量(如年龄值、票价等)的图例

      3. 可视化暗示

        • 图例项数量(10项)表明可视化可能使用颜色/形状编码多个变量

        • 生存状态(No/Yes)的存在暗示图表可能包含生存分析

6 热图和南丁格尔玫瑰图

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

6.1 数据准备

# 数据准备:计算每个Class和Survived组合的频数
titanic_dot <- as.data.frame(Titanic) %>%
  group_by(Class, Survived) %>%
  summarise(Freq = sum(Freq), .groups = 'drop')

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

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

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

7 饼环图

绘制Class和 Sex的饼环图。

7.1 数据准备

data("Titanic")
titanic_df <- as.data.frame(Titanic)

# 按 Class 和 Sex 聚合频数
doughnut_data <- titanic_df %>%
  group_by(Class, Sex) %>%
  summarise(Freq = sum(Freq), .groups = 'drop')

# 查看数据
head(doughnut_data)
# A tibble: 6 × 3
  Class Sex     Freq
  <fct> <fct>  <dbl>
1 1st   Male     180
2 1st   Female   145
3 2nd   Male     179
4 2nd   Female   106
5 3rd   Male     510
6 3rd   Female   196

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

library(ggiraphExtra)

p1<-ggPieDonut(data=titanic_df,aes(pies=Class,donuts=Sex),
  title="(a) 网购原因为饼图,满意度为环形图")
p2<-ggPieDonut(data=titanic_df,aes(pies=Sex,donuts=Class),
  title="(b) 满意度为饼图,性别为环形图")
grid.arrange(p1,p2,ncol=2)

7.3 介绍图形特点和信息

  • 特点

    1. 组合图表设计

      • 图表(a)使用饼图展示网购原因,环形图展示满意度

      • 图表(b)使用饼图展示满意度,环形图展示性别分布

    2. 多层级数据展示

      • 通过饼图和环形图的组合,同时呈现了两个维度的数据分布

      • 百分比数据直接标注在图表上(如12.5%, 25%, 50%等)

    3. 数据分组

      • 数据按性别(Female/Male)和乘客等级(1st, 2nd, 3rd, Crew)进行分组

      • 各组的比例关系清晰可见

信息

  1. 性别分布

    • 男性(Male)和女性(Female)的比例在不同分组中有所变化

    • 某些分组中男性占50%,女性占50%,而其他分组比例不等

  2. 乘客等级分布

    • 包含了1st(一等舱)、2nd(二等舱)、3rd(三等舱)和Crew(船员)四个等级

    • 各等级在不同分组中的比例从12.5%到25%不等

  3. 百分比信息

    • 所有分组的百分比总和为100%

    • 数值多为12.5%的倍数(12.5%, 25%, 50%),表明数据可能经过标准化处理或来自特定样本