第三章 类别数据可视化

Author

221527135徐锦辉

1 解释原始数据

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

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列组合图形

  • 你可以通过修改数据或者修改刻度标签将图中性别和生还的类别标签改为中文,请给出代码完成修改。
# 图(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("男","女")
   )+
  scale_fill_discrete(
   "生还",
    labels=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) 垂直堆叠条形图")+
  scale_x_discrete(
   "性别",
    labels=c("男","女")
   )+
  scale_fill_discrete(
   "生还",
    labels=c("否","是")
   )

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

2.3 介绍图形特点和信息

使用并列的条形展示不同性别(男、女)的乘客人数。每个性别对应两个条形,女性乘客总人数(左侧条形)显著多于男性(右侧条形)。具体数值标注在条形上方(如女性 1964 人,男性 367 人)。

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("Crew","3rd","1st","2nd"))+ # 将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.3,y=700,label="百分比(%)",angle=90,size=3.5)+
   annotate("text",x=3.5,y=900,label="累积百分比曲线",size=3.5)# 添加注释文本

3.3 介绍图形特点和信息

使用条形图显示乘客舱位种类对应的人数,用折线图显示人数累计百分比并且合并到一张图里。从图中能看出crew舱位的人数最多,2nd舱位的人数最少

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.7,color='red')+scale_fill_brewer(palette = "Greens")

4.3 利用ggiraphExtra包ggSpine()

df1<-df %>% mutate(Class=factor(Class,levels=c('Crew','3rd','2nd','1st')))

ggSpine(df1,aes(x=Survived,y=percent,fill=Class),stat='identity',palette = "Blues",labelsize = 3,reverse = TRUE)  

4.4 介绍图形特点和信息

  • 这个脊形图中的百分比位于图里面,用矩形的大小表现百分比的多少。可以直观的看出Crew舱位的人数最多

5 树状图和旭日图

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

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

data
   Class    Sex   Age Survived Freq
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
7    3rd Female Child       No   17
8   Crew Female Child       No    0
9    1st   Male Adult       No  118
10   2nd   Male Adult       No  154
11   3rd   Male Adult       No  387
12  Crew   Male Adult       No  670
13   1st Female Adult       No    4
14   2nd Female Adult       No   13
15   3rd Female Adult       No   89
16  Crew Female Adult       No    3
17   1st   Male Child      Yes    5
18   2nd   Male Child      Yes   11
19   3rd   Male Child      Yes   13
20  Crew   Male Child      Yes    0
21   1st Female Child      Yes    1
22   2nd Female Child      Yes   13
23   3rd Female Child      Yes   14
24  Crew Female Child      Yes    0
25   1st   Male Adult      Yes   57
26   2nd   Male Adult      Yes   14
27   3rd   Male Adult      Yes   75
28  Crew   Male Adult      Yes  192
29   1st Female Adult      Yes  140
30   2nd Female Adult      Yes   80
31   3rd Female Adult      Yes   76
32  Crew Female Adult      Yes   20
df <- as.data.frame(data)  # 转换为数据框

datatable(df,rownames = FALSE)
treemap(df,index=c("Class", "Sex", "Age", "Survived"),  # 设置聚合索引的列名称
  vSize="Freq",                                  # 指定矩形大小的列名称
  #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,Freq)  # 根据需要调整列变量的位置
df_tree<-d3_nest(df,value_cols="Freq")             # 将数据框转换为“d3.js”层次结构
datatable(df,rownames = FALSE)
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)
datatable(df,rownames = FALSE)

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

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

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

p2<-ggHeatmap(data,aes(x=Class,y=Survived),polar=TRUE,
   addlabel=TRUE,palette="Reds")+                      # 绘制极坐标热图
   ggtitle("(a2) 极坐标热图")

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

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

p1 <- ggRose(
  data = df,
  aes(x = Class, y = Freq, fill = Survived),
  stat = "sum",  # 使用 Freq 求和,适合 Nightingale 玫瑰图
  addlabel = TRUE,  # 添加数值标签
  palette = "Reds"  # 红色调色板
) +
  labs(title = "Rose Diagram of Class vs Survived") +
  theme_minimal()

# 显示图形
print(p1)

6.4 介绍图形特点和信息

7 饼环图

绘制Class和 Sex的饼环图。

7.1 数据准备

df<-data%>%select(Class,Sex,Freq)
datatable(df,rownames = FALSE)

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

p1<-ggPieDonut(data=data,aes(pies=Class,donuts=Freq),
  title="(a)") 
p2<-ggPieDonut(data=data,aes(pies=Freq,donuts=Sex),
  title="(b)")
grid.arrange(p1,p2,ncol=2)

7.3 介绍图形特点和信息