第三章 类别数据可视化

Author

kaka

1 解释原始数据

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

2 条形图

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

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

  • 你可以通过修改数据或者修改刻度标签将图中性别和生还的类别标签改为中文,请给出代码完成修改。
# 图(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")+# 绘制条形图
  scale_x_discrete(labels=c("1st"="一等舱","2nd"="二等舱","3rd"="三等舱"))+ # 将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=5,y=500,label="百分比(%)",angle=90,size=3.5)+
   annotate("text",x=5,y=650,label="累积百分比曲线",size=3.5)   # 添加注释文本

3.3 介绍图形特点和信息

4 脊形图

绘制Class和 Survived 的脊形图。

4.1 数据准备

df<- data |> select(Class, Survived,Freq) %>%
  summarise(人数 = sum(Freq), .by = c(Class,Survived)) %>%  
  mutate(百分比=人数*100/sum(人数),百分比=round(百分比,1),.by="Class")

datatable(df,rownames = FALSE)

4.2 利用geom_col() 作图

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

4.3 利用ggiraphExtra包ggSpine()

ggSpine(data=df,aes(x=Class,y=百分比,fill=Survived),stat = 'identity',
  palette="Reds",labelsize=3,reverse=TRUE)  # 反转调色板颜色

4.4 介绍图形特点和信息

  • 比例关系图(脊形图)显示的为各乘客舱位的幸存比例,可以看出乘客的幸存比例随着舱位的等级而逐级递减,即一等座乘客幸存比例最高,船员的幸存比例最低。

5 树状图和旭日图

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

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

df<-data%>%
  rename(人数=Freq) # 将Freq命名为频数

datatable(df,rownames = FALSE)
# 图(a)分层顺序:Class—Sex—Age-Survived
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”作为绘图输入
df_tree<-d3_nest(df,value_cols="人数")             # 将数据框转换为“d3.js”层次结构
datatable(df,rownames = FALSE)
sunburst(data=df_tree,           # 绘制旭日图
   valueField="人数",    # 计算大小字段的字符为vSize
   count=TRUE,                   # 在解释中包括计数和总数
   sumNodes=TRUE)                # 默认总和节点=TRUE
Legend

5.3 介绍图形特点和信息

6 热图和南丁格尔玫瑰图

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

6.1 数据准备

df<-data%>%
  summarise(人数=sum(Freq),.by=c(Class,Survived)) 
  
# 图(a)Class和Survived的点阵图
palette<-rev(brewer.pal(11,"RdYlGn"))       # 设置调色板
ggballoonplot(df,x="Class",y="Survived",   # 设置图形的x轴和y轴
   shape=21,                    # 设置形状,默认21,可选22,23,24,25
   size="人数",fill="人数",                 # 设置点的大小和填充颜色变量
   size.range = c(7,15),                    # 设置最小点和最大点的范围
   rotate.x.text=FALSE,                     # x轴文本标签不旋转
   ggtheme=scale_fill_gradientn(colors=palette))+  # 设置渐变颜色
   theme(axis.text.y=element_text(angle=90))+      # y轴标签旋转90度
   ggtitle("(a)  Class和Survived的点阵图")

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

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

df <- data %>%
  group_by(Class, Survived) %>%
  summarise(人数 = sum(Freq), .groups = "drop")
ggHeatmap(df,aes(x=Class,y=Survived,fill=人数),          # 绘制矩形热图
   addlabel=TRUE,                                      # 添加数值标签
   palette="Reds")+                                    # 使用红色调色板
   ggtitle("(a1) 矩形热图")                            # 添加标题

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

df <- df %>%
  group_by(Class) %>%
  arrange(Survived) %>%  # 确保Survived按顺序排列
  mutate(ypos = 人数 - cumsum(人数) / 20) # 计算标签的垂直位置  

# 定义标签角度和调色板
myangle <- seq(-20, -340, length.out = 8) 
palette <- brewer.pal(n = 2, "Set3")       # 根据Survived类别数选择颜色数

# 绘制玫瑰图
p <- ggplot(df, aes(x = Class, y = 人数, fill = Survived)) + 
  geom_col(width = 1, color = "grey20", position = "stack") +  # 堆叠条形图
  geom_text(aes(y = ypos, label = 人数),  # 添加数值标签
            size = 3.5,                   # 标签字体大小
            color = "black",              # 标签颜色(与背景对比)
            show.legend = FALSE) +        # 不显示图例中的文本标签
  coord_polar(theta = "x", start = 0) +    # 极坐标转换
  scale_fill_manual(values = palette) +    # 手动指定填充颜色
  theme(axis.text.x = element_text(size = 10, angle = myangle),
    legend.position = "right") +
  labs(y = "人数", title = "乘客生存情况玫瑰图")
print(p)

6.4 介绍图形特点和信息

7 饼环图

绘制Class和 Sex的饼环图。

7.1 数据准备

# 按Class和Sex分组汇总人数
df <- data %>%
  group_by(Class, Sex) %>%
  summarise(人数 = sum(Freq), .groups = "drop") %>%
  mutate(Class = factor(Class, levels = c("1st", "2nd", "3rd", "Crew")),
  Sex = factor(Sex, levels = c("Male", "Female")))

datatable(df,rownames = FALSE)

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

# 绘制饼环图
ggPieDonut(data = df,
  aes(pies = Class, donuts = Sex, count = 人数), 
  title = "(b) Class为饼图,Sex为环形图") 

7.3 介绍图形特点和信息

  • 内部饼图显示舱位等级(Class)的比例,外环显示每个舱位内性别(Sex)的分布。