第三章 类别数据可视化

Author

221527242黄翊轩

1 解释原始数据

  • Titanic数据集是datasets包的配套案例数据,可以通过as.data.frame将其转化为数据框。解析数据包含哪些变量,如果是分类变量分别有哪些类别?
1 Class 1st, 2nd, 3rd, Crew
2 Sex Male, Female
3 Age Child, Adult
4 Survived No, Yes
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_fill_discrete(
     "生还",
     labels=c(
      "No"="否",
       "Yes"="是"
     )
  )+
  scale_x_discrete(
    "性别",
    labels=c(
      "Male"="男",
      "Female"="女"
    )
  )
  


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

3.3 介绍图形特点和信息

  • 图形显示船员舱人数最多,其次是一等舱,二等舱和三等舱人数差不多,都比较少。

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()

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

4.4 介绍图形特点和信息

  • 从图形中可以明显看出高舱位(一等舱)的生还率显著高于低舱位,三等舱的遇难人数最多

5 树状图和旭日图

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

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

data = as.data.frame(Titanic)
DT::datatable(data,rownames = FALSE)
# 图(a)分层顺序:Sex—Class—Age-Survived
treemap(data,index=c("Sex","Class","Age","Survived"),  # 设置聚合索引的列名称
  vSize="Freq",                                  # 指定矩形大小的列名称
  #fontsize.labels=9,                             # 设置标签字体大小
  position.legend="bottom",                      # 设置图例位置
  title="(a) 分层顺序:Sex—Class—Age-Survived")

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

  • 通过d3r::d3_nest将数据框转化为层次数据“d3.js”作为绘图输入
library(d3r)
df<-data%>%select(Sex,Class,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 数据准备

library(dplyr)
library(DT)

df <- as.data.frame(Titanic) %>%
  select(Class, Survived, Freq) %>%
  group_by(Class, Survived) %>%
  summarise(人数 = sum(Freq), .groups = "drop") %>%
  rename(乘客舱位 = Class, 生还情况 = Survived)

datatable(df, rownames = FALSE)

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

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

library(ggiraphExtra)
library(ggplot2)

p1 <- ggHeatmap(df, 
               aes(x = 乘客舱位, y = 生还情况, fill = 人数),
               color = "white") +
  scale_fill_gradient(low = "white", high = "red") +
  ggtitle("泰坦尼克号生还情况矩形热图") +
  theme_minimal()

p2 <- ggHeatmap(df,
               aes(x = 乘客舱位, y = 生还情况, fill = 人数),
               polar = TRUE) +
  scale_fill_gradient(low = "white", high = "blue") +
  ggtitle("泰坦尼克号生还情况极坐标热图") +
  theme_minimal()

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

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

library(dplyr)
library(tidyr)
library(ggplot2)
library(RColorBrewer)
library(ggrepel)

# 假设 data 是您的数据框,并且包含 Class, Survived 和 Freq 列

# 将 Class 转换为有序因子
f <- factor(data$Class, ordered = TRUE, levels = unique(data$Class))

# 构建新的数据框
df1 <- data.frame(Class = f, 生还 = data$Survived, 人数 = data$Freq)

# 使用 dplyr 重新构建数据框,并确保 Class 是有序因子
df1 <- data %>%
  select(Class, Survived, Freq) %>%
  rename(生还 = Survived, 人数 = Freq) %>%
  mutate(Class = factor(Class, ordered = TRUE, levels = unique(Class)))

# 检查 df1
print(df1)
   Class 生还 人数
1    1st   No    0
2    2nd   No    0
3    3rd   No   35
4   Crew   No    0
5    1st   No    0
6    2nd   No    0
7    3rd   No   17
8   Crew   No    0
9    1st   No  118
10   2nd   No  154
11   3rd   No  387
12  Crew   No  670
13   1st   No    4
14   2nd   No   13
15   3rd   No   89
16  Crew   No    3
17   1st  Yes    5
18   2nd  Yes   11
19   3rd  Yes   13
20  Crew  Yes    0
21   1st  Yes    1
22   2nd  Yes   13
23   3rd  Yes   14
24  Crew  Yes    0
25   1st  Yes   57
26   2nd  Yes   14
27   3rd  Yes   75
28  Crew  Yes  192
29   1st  Yes  140
30   2nd  Yes   80
31   3rd  Yes   76
32  Crew  Yes   20
# 设置标签角度为90度,使之垂直于坐标轴
myangle <- 90

# 设置颜色调色板
palette <- brewer.pal(8, "Set3")

# 绘制玫瑰图
p1 <- ggplot(df1, aes(x = 生还, y = 人数, fill = Class)) +           
  geom_col(width = 1, colour = "grey20") +  # 绘制条形图
  coord_polar(theta = "y") +  # 转化成极坐标图
  scale_fill_manual(values = palette) +  # 使用自定义颜色调色板
  theme(axis.text.x = element_text(size = 5, angle = myangle, hjust = 1)) +  # 设置坐标轴标签字体大小和角度
  ylab("人数") +  # 设置y轴标签
  ggtitle("(a) 按人数顺序排序")  # 设置图表标题
p1 <- p1 + geom_text_repel(aes(label = 人数), size = 2, color = "grey30", box.padding = 0.5, max.overlaps = Inf)
print(p1)

6.4 介绍图形特点和信息

  • 扇形是按照人数排列顺序,是根据人数从高到低排列。

7 饼环图

绘制Class和 Sex的饼环图。

7.1 数据准备

df<-data |> 
  select(Class,Sex,Freq) |> 
  summarise(n=sum(Freq),.by=Class,Sex) |> 
  rename(乘客舱位=Class,性别=Sex,人数=n ) |> 
  arrange(desc(人数)) |> 
  mutate(百分比 = 人数*100/sum(人数))
         
datatable(df,rownames = FALSE)

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

library(ggiraphExtra)

p1<-ggPieDonut(data=df,aes(pies=乘客舱位,donuts=性别),
  title="(a) 乘客舱位为饼图,性别为环形图")
p2<-ggPieDonut(data=df,aes(pies=性别,donuts=乘客舱位),
  title="(b) 性别为饼图,乘客舱位为环形图")
grid.arrange(p1,p2,ncol=2)

7.3 介绍图形特点和信息

  • 图形显示了三等舱男性遇难者群体最多,女性乘客在各舱位的生还人数都比较多。