第三章 类别数据可视化

Author

221527114柯金余

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

  • 你可以通过修改数据或者修改刻度标签将图中性别和生还的类别标签改为中文,请给出代码完成修改。
library(ggplot2)
library(gridExtra)

# 假设原始数据框df结构如下:
# 性别(Male/Female),生还(Yes/No),人数
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 介绍图形特点和信息

  • 男性人数比女性多,男性死亡人数远远多于女性,男性生还人数与女性差不多。总的来说,男性死亡率高于女性。

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

3.3 介绍图形特点和信息

  • “Crew”,“3rd”,“1st”,“2nd”这四个因子中,Crew占比最高,其次是三等舱和一等舱,二等舱占比最低。

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=df1,aes(x=Survived,y=percent,fill=Class),stat = "identity",
  palette="Blues",labelsize=3,reverse=TRUE)  # 反转调色板颜色

4.4 介绍图形特点和信息

  • 头等舱乘客的生还率较高,而三等舱、crew船员舱的生还率较低。虽然crew船员舱组生存人数多,但它的死亡人数也多,所以生还率低。

5 树状图和旭日图

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

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

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

datatable(df,rownames = FALSE)
# 图(a)分层顺序:性别—网购原因—满意度
# 将"频数"列转换为数值型
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_tree,           # 绘制旭日图
   valueField="Survived",    # 计算大小字段的字符为vSize
   count=TRUE,                   # 在解释中包括计数和总数
   sumNodes=TRUE)                # 默认总和节点=TRUE
Legend

5.3 介绍图形特点和信息

6 热图和南丁格尔玫瑰图

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

6.1 数据准备

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

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

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

library(ggiraphExtra)

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) 极坐标热图")
p3<-ggHeatmap(data,aes(x=Class,y=Survived,fill=Freq),
   addlabel=TRUE,palette="Blues")+                     # 使用蓝色调色板
   ggtitle("(b1) 矩形热图")
p4<-ggHeatmap(data,aes(x=Class,y=Survived,fill=Freq),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|>summarise(n=sum(Freq),.by = c("Class","Survived"))
datatable(df)
ggRose(df,aes(x=Class,y=n,fill=Survived),
stat="identity",palette="Reds",reverse=TRUE)+ylab("人数")+
  guides(fill=guide_legend(nrow=2,title=NULL))+  # 图例排成2行,去掉图例标题
  theme(legend.position="bottom")+
  theme(plot.title=element_text(size=10))+       # 设置标题字体大小
  theme(axis.text.x=element_text(size=8,color="red3"))

ggtitle("(a)  x 轴为舱位类型")
$title
[1] "(a)  x 轴为舱位类型"

attr(,"class")
[1] "labels"

6.4 介绍图形特点和信息

  • 群体分布

    船员(Crew):人数较多,但生存率较低。

    头等舱(1st):人数较少,但“Yes”部分可能显著,说明生存率较高。

    三等舱(3rd):人数较多,但“No”部分占比较大,生存率可能最低。

7 饼环图

绘制Class和 Sex的饼环图。

7.1 数据准备

df<-data|>summarise(n=sum(Freq),.by = c("Class","Sex"))
datatable(df)
df
  Class    Sex   n
1   1st   Male 180
2   2nd   Male 179
3   3rd   Male 510
4  Crew   Male 862
5   1st Female 145
6   2nd Female 106
7   3rd Female 196
8  Crew Female  23

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

library(ggiraphExtra)
p1<-ggPieDonut(data=df,aes(pies=Class,donuts=Sex,count=n),
  title="(a) class为饼图,sex为环形图")
p1

7.3 介绍图形特点和信息

zzzz

  • 船员(Crew):占比最高(40.2%),符合泰坦尼克号船员人数较多的实际情况。

  • 三等舱(3rd):次高(32.1%),说明低票价乘客数量庞大。

  • 头等舱(1st):14.8%,二等舱(2nd):12.9%,占比显著低于船员和三等舱。

  • 7.3.0.1 性别分布(外层环形图)

    • 男性(Male)

      • 在船员中占比极高(23.2% + 8.1% = 31.3%),符合历史记录(船员多为男性)。

      • 在乘客中,三等舱男性占比最高(39.2%)。

    • 女性(Female)

      • 占比普遍较低,头等舱女性相对较多(8.9% vs 1% in Crew),反映“妇孺优先”的救援原则。

7.3.0.2 结论

  • 阶级差异:头等舱乘客(尤其是女性)占比虽小,但实际生存率可能更高(图形未直接展示,需结合生存数据)。

  • 性别失衡:船员和低舱位男性占主导,女性集中在高舱位。