## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
## 
## 载入程辑包:'gridExtra'
## 
## 
## The following object is masked from 'package:dplyr':
## 
##     combine
## 
## 
## Registered S3 method overwritten by 'GGally':
##   method from   
##   +.gg   ggplot2
## 
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
## 
## 
## 载入程辑包:'gplots'
## 
## 
## The following object is masked from 'package:stats':
## 
##     lowess

案例数据

iris:鸢尾花数据集

  • R语言内置的 iris 数据集(鸢尾花数据集)是统计学和机器学习领域最经典的案例数据集之一,由英国统计学家 Ronald Fisher 在1936年首次提出。它包含了3种鸢尾花的测量数据,每个类别有50个样本,共150行数据。
变量名 数据类型 单位 说明
Sepal.Length numeric cm 花萼(萼片)长度,即花朵最外层绿色叶状结构的长度
Sepal.Width numeric cm 花萼(萼片)宽度
Petal.Length numeric cm 花瓣长度,即花朵内部彩色叶状结构的长度
Petal.Width numeric cm 花瓣宽度
Species factor - 鸢尾花种类(分类标签),包含3个水平:
setosa山鸢尾
versicolor变色鸢尾
virginica维吉尼亚鸢尾
  • setosa 类的花通常较小,花瓣短而宽,与其他两类差异明显;versicolorvirginica 在部分特征上有重叠,分类难度更高。
data <- iris
datatable(data)

平行坐标图和雷达图

平行坐标图

  • ggplot(group=id)+geom_line+geom_point 绘图
  • Species 映射为颜色
df <- data |> mutate(id=1:150) |> 
  gather(1:4,key=指标,value=数值) |> 
  mutate(指标=fct_inorder(指标))
ggplot(df,aes(x=指标,y=数值,group=id,color=Species))+
  geom_line(size=0.5)+                           # 绘制折线
  geom_point(shape=21,size=1.5,fill="gray50")+   # 绘制点
  scale_x_discrete(guide=guide_axis(n.dodge=2))+ # 设置x轴标签为2行
  theme(legend.position=c(0.8,0.8),              # 设置图例位置
        legend.background=element_blank())+         # 移除图例整体边框
  guides(color=guide_legend(nrow=3,title=NULL))+ # 图例排成3行,去掉图例标题
  ggtitle("平行坐标图")               
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning: A numeric `legend.position` argument in `theme()` was deprecated in ggplot2
## 3.5.0.
## ℹ Please use the `legend.position.inside` argument of `theme()` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

图形观察和代码编写的心得体会

  • 图形观察

    1. 整体模式

      • Setosa品种(红色)在所有指标上与其他两个品种明显分离

      • Versicolor和Virginica有一定重叠但在花瓣尺寸上存在差异

    2. 特征关系

      • 花瓣长度和宽度呈现正相关趋势

      • 花萼宽度在Setosa中表现突出

    编程心得:

    1. 数据重塑技巧

      • 平行坐标图需要将宽数据转为长格式,gather()/pivot_longer()是关键

      • 为每条观察添加唯一ID(id)是连接各维度点的关键

    2. 可视化优化

      • 同时使用线条和点增强了图形可读性

      • 图例位置和格式调整避免了遮挡数据

      • 轴标签旋转解决了长标签重叠问题

雷达图

  • 采用ggiraphExtra::ggRadar 绘图
mytheme<-theme(legend.position="right",    # 设置标题位置
   axis.text.x=element_text(size=9,color="blue4"))
ggRadar(data,aes(group=Species),    # 按地区分组
  rescale=FALSE,                         # 数据标准化(缩放到[0,1]范围)
  ylim=c(0,6),                       # 设置y轴范围
  alpha=0.3,                            # 设置颜色透明度
  size=2)+                              # 设置点的大小
  mytheme+xlab("支出项目")+ylab("归一化值")+
  ggtitle("(b) 归一化雷达图") # 添加标题

图形观察和代码编写的心得体会

  • 数据重塑的重要性

    • 平行坐标图需要将宽格式转为长格式,gather()/pivot_longer()是关键

    • 保持变量顺序(fct_inorder)对正确显示至关重要

  • 图形元素控制

    • group美学确保观测值正确连接

    • 点线结合增强可视化效果(线展示趋势,点标记具体值)

  • 可读性优化

    • 调整图例位置避免遮挡数据

    • 处理轴标签重叠问题(n.dodge)

    • 简化图例(title=NULL)使图形更简洁

  • 扩展思考

    • 对于大数据集可考虑透明度调整(alpha)避免过度绘制

    • 可添加中位数线或分位区域展示整体分布

    • 标准化处理可使不同量纲的变量更好比较

这种可视化方法非常适合比较多维数据中不同类别的特征模式,能清晰展示鸢尾花各物种在四个特征上的差异和相似性。代码结构清晰,展示了ggplot2的图层叠加思想和数据转换技巧。

星图和脸谱图

星图

  • 采用stars 函数,对标准化数据绘制圆弧星图

  • 需要先将四个数值变量转化为矩阵,并将Species 作为矩阵的行名;

  • 设置图例在合适位置,能完整显示;将图形分为10行。

mat<-data%>%select(-Species)%>%as.matrix() # 转换成矩阵
rownames(mat)=data[,5] 
stars(mat,
   full=TRUE,                                # 绘制出满圆
   scale=TRUE,                               # 将数据缩放到[0,1]的范围
   nrow=10,                                   # 5行布局
   len=1,                                    # 设置半径或线段长度的比例
   frame.plot=TRUE,                          # 添加边框
   draw.segments=TRUE,key.loc=c(13.5,2,5),   # 绘制圆弧图,并设置位置
   mar=c(0.5,0.1,0.1,0.1),                   # 设置图形边界
   cex=0.6)                                  # 设置标签字体大小

                               # 设置标签字体大小

图形观察和代码编写的心得体会

  • 适用场景

    • 星形图适合低维数据(变量数≤6),过多变量会导致图形难以解读。

    • 强调个体观测的模式(如不同鸢尾花样本的特征分布)。

  • 参数调优

    • scale:是否标准化取决于分析目标(如关注相对模式 vs 绝对数值)。

    • draw.segments:扇形填充增强视觉对比,但可能掩盖细节。

    • key.locmar:需反复调试以避免图形元素重叠。

  • 局限性

    • 变量顺序影响图形解读(建议按相关性或逻辑排序)。

    • 大数据集时易产生视觉混乱(可抽样或聚合后绘制)。

  • 改进方向

    • 添加标题和轴注释(如main="鸢尾花特征星形图")。

    • 使用颜色区分物种(如col=rainbow(3)[data$Species])。

    • 结合其他图表(如箱线图)补充统计信息。

脸谱图

  • 采用aplpack::faces 函数,作Species 三个类别的脸谱图
  • 需要先将四个数值变量转化为矩阵,并将Species 作为矩阵的行名;
  • 设置图例在合适位置,能完整显示;将图形分为3列。
library(aplpack)

mat<-data |> summarise(Sepal.Length=mean(Sepal.Length),
                       Sepal.Width=mean(Sepal.Width),
                       Petal.Length=mean(Petal.Length),
                       Petal.Width=mean(Petal.Length),
                       .by=Species)
row.names(mat) <- mat$Species
mat <- mat[,-1] |> as.matrix()
faces(mat,face.type=1,              # 设置脸谱图的类型
   ncol.plot=4,                     # 绘制成7列
   scale=TRUE,                      # 数据标准化
   cex=1)                 

## effect of variables:
##  modified item       Var           
##  "height of face   " "Sepal.Length"
##  "width of face    " "Sepal.Width" 
##  "structure of face" "Petal.Length"
##  "height of mouth  " "Petal.Width" 
##  "width of mouth   " "Sepal.Length"
##  "smiling          " "Sepal.Width" 
##  "height of eyes   " "Petal.Length"
##  "width of eyes    " "Petal.Width" 
##  "height of hair   " "Sepal.Length"
##  "width of hair   "  "Sepal.Width" 
##  "style of hair   "  "Petal.Length"
##  "height of nose  "  "Petal.Width" 
##  "width of nose   "  "Sepal.Length"
##  "width of ear    "  "Sepal.Width" 
##  "height of ear   "  "Petal.Length"

图形观察和代码编写的心得体会

  • 变量映射到面部特征

    • 切尔诺夫脸谱图将不同的数值变量映射到不同的面部特征,例如:

      • 眼睛大小可能对应Sepal.Length

      • 嘴巴弧度可能对应Petal.Width

      • 脸型宽度可能对应Sepal.Width

    • 由于face.type=1,具体的映射方式由aplpack内部决定,但通常较大的数值会使特征更突出(如更大的眼睛、更宽的嘴巴)。

  • 标准化(scale=TRUE)的影响

    • 由于四个变量的量纲不同(如Sepal.Length在厘米级别,Petal.Width在毫米级别),标准化使它们可比。

    • 如果不标准化,某些变量可能对脸谱形状影响过大。

  • 脸谱风格(face.type

    • face.type=1是较简单的风格,其他风格(如face.type=2)可能更夸张或抽象。
  • 物种区分

    • 三个物种(setosaversicolorvirginica)的脸谱应有明显差异,尤其是setosa(通常花萼较宽、花瓣较短)与其他两个物种不同。

聚类图和热图

系统聚类树状图

  • 采用factoextra::fviz_dend 函数,对标准化后数据作图;
  • 需要先将四个数值变量转化为矩阵,并将Species 作为矩阵的行名;
  • 要求分为3类,观察分类结果和Species 的差异;树状图的外观为圆形。
library(factoextra)

mat<-data%>%select(-Species)%>%as.matrix() # 转换成矩阵
rownames(mat)=data[,5] 

d<-dist(scale(mat),method="euclidean")# 采用euclidean距离计算样本的点间距离
hc<-hclust(d,method="ward.D2")
                          # 采用ward.D法计算类间距离并用层次聚类法进行聚类
cols=brewer.pal(3,"Set1")  
# 绘制圆形树状图
fviz_dend(
  hc,
  k = 3, # 分为3类
  k_colors = cols, # 使用Set1调色板的3种颜色
  color_labels_by_k = TRUE, # 按聚类结果着色标签
  type = "circular", # 圆形布局
  rect = TRUE, # 添加聚类矩形框
  rect_fill = TRUE, # 填充矩形框
  rect_border = cols, # 矩形框边框颜色
  main = "鸢尾花数据层次聚类树状图 (k=3)", # 标题
  xlab = "", 
  ylab = "距离"
)
## Warning: The `<scale>` argument of `guides()` cannot be `FALSE`. Use "none" instead as
## of ggplot2 3.3.4.
## ℹ The deprecated feature was likely used in the factoextra package.
##   Please report the issue at <https://github.com/kassambara/factoextra/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

图形观察和代码编写的心得体会

  • 图形观察

    1. 聚类效果分析

      • Setosa分离明显:红色分支(通常对应Setosa)与其他两类完全分离,这与原始Species分类一致,表明Setosa的花型特征与其他两种鸢尾花差异显著。

      • Versicolor和Virginica部分重叠:绿色和蓝色分支(对应Versicolor和Virginica)在树状图中有交叉,说明这两个物种在某些样本上特征相似,可能源于花瓣尺寸的连续变异。

      • 矩形框标记:三个彩色矩形框清晰标出了聚类边界,但Virginica的矩形框可能覆盖了部分本应属于Versicolor的样本。

    2. 与原始分类对比

      • 通过table(cutree(hc, k=3), data$Species)可量化分类差异,预期Setosa的准确率接近100%,而Versicolor和Virginica可能存在约10-15%的误分。
    3. 圆形布局优势

      • 150个样本的标签在圆形布局中径向排列,避免了传统树状图的标签重叠问题,但最内层标签仍可能因空间不足而显示不全。

      代码编写心得体会

      1. 数据预处理关键步骤

        • 标准化必要性scale(mat)消除了不同特征(如花萼长度和花瓣宽度)的量纲差异,避免数值较大的特征主导距离计算。

        • 行名设置技巧rownames(mat) <- data[,5]将Species信息保留为行名,使得最终图形能直接显示样本类别,增强可解释性。

      2. 聚类方法选择

        • Ward.D2算法的适用性:该方法最小化簇内方差,适合欧氏距离,能产生平衡的簇。对于鸢尾花这种类别大小相近的数据表现良好。

        • 距离度量:欧氏距离直观反映多维空间中的样本差异,但对异常值敏感。若数据存在离群点,可尝试曼哈顿距离(method = "manhattan")。

K-menas聚类主成分图

  • 采用factoextra::fviz_cluster 函数,对标准化后数据作图;

  • 需要先将四个数值变量转化为矩阵,并将1:150 作为矩阵的行名;

  • 要求分为3类,类别轮廓为正态分布,观察哪些观察值比较异常。

library(factoextra)
library(cluster)  # 明确加载cluster包以使用silhouette函数
library(ggplot2)

# 数据准备和标准化
mat <- data |> select(-Species) |> 
  as.matrix() |>            # 转换成矩阵
  scale()                   # 数据标准化
rownames(mat) <- 1:150      # 设置行名为1-150

# K-means聚类(分为3类)
set.seed(123)  # 确保结果可重复
km <- kmeans(mat, centers = 3, nstart = 25)  # nstart增加随机初始化的次数

# 计算轮廓宽度(确保cluster包已加载)
sil <- silhouette(km$cluster, dist(mat))

# 绘制聚类主成分图
p <- fviz_cluster(
  km,
  data = mat,
  ellipse.type = "norm",  # 添加正态分布轮廓
  ellipse.level = 0.68,   # 1个标准差范围
  ellipse.alpha = 0.1,    # 椭圆透明度
  geom = c("point"),      # 只显示点(避免标签拥挤)
  repel = TRUE,          # 避免标签重叠(当geom包含"text"时)
  main = "K-means聚类主成分图 (k=3)",
  ggtheme = theme_minimal()
) 

# 添加异常值标记(轮廓宽度<0的样本)
outliers <- which(sil[, "sil_width"] < 0)
p <- p + 
  geom_point(
    data = data.frame(x = p$data$x[outliers], y = p$data$y[outliers]),
    aes(x, y),
    shape = 21,
    size = 3,
    color = "red",
    fill = "pink",
    stroke = 1.5
  )

print(p)

# 输出分析结果
cat("=== 异常值(轮廓宽度<0)的样本ID ===\n")
## === 异常值(轮廓宽度<0)的样本ID ===
print(outliers)
## [1] 112 128
cat("\n=== 聚类结果与真实类别的对比 ===\n")
## 
## === 聚类结果与真实类别的对比 ===
table(Kmeans_Cluster = km$cluster, Species = data$Species)
##               Species
## Kmeans_Cluster setosa versicolor virginica
##              1     50          0         0
##              2      0         39        14
##              3      0         11        36
# 可选:添加轮廓宽度图
fviz_silhouette(sil) + 
  ggtitle("轮廓宽度分布(负值表示潜在异常值)")
##   cluster size ave.sil.width
## 1       1   50          0.64
## 2       2   53          0.39
## 3       3   47          0.35

图形观察和代码编写的心得体会

图形观察结果

  1. 聚类分布特征
  • 三个类别在主成分空间中的分布呈现明显区隔

  • 第一主成分(x轴)方向上的分离度最为显著

  • 部分样本点位于聚类边界区域,可能是潜在异常值

  1. 正态轮廓解读
  • 每个聚类的椭圆轮廓反映了数据的分布密度

  • 椭圆大小和方向显示了各类别的离散程度和相关特征

  • 紧凑的椭圆表示内部样本特征高度一致

  1. 异常点识别
  • 位于聚类边界或重叠区域的点值得关注

  • 远离所属聚类中心的样本可能需要进一步检查

代码编写心得体会

  1. 数据预处理
  • 标准化步骤确保各特征具有相同量纲

  • 合理的行名设置便于后续结果追踪

  1. 聚类算法应用
  • 选择合适的聚类数量和初始化参数

  • 多次运行确保结果稳定性

  1. 可视化技巧
  • 主成分降维有效展示高维数据

  • 椭圆轮廓增强聚类边界识别

  • 异常点突出标记便于观察

  1. 结果验证
  • 轮廓系数提供量化评估标准

  • 与原始类别对比验证聚类效果

热图

  • 采用gplots::heatmap.2 函数,对原始数据绘制热力图

  • 需要先将四个数值变量转化为矩阵,并将Species 作为矩阵的行名;

  • 要求横轴和纵轴均添加聚类树状图

library(gplots)
library(RColorBrewer)

# 数据准备
mat <- data %>% select(-Species) %>% as.matrix()
rownames(mat) <- data[,5]

# 专业颜色方案(修正版)
my_palette <- colorRampPalette(brewer.pal(9, "YlOrRd"))(255) # 255个颜色梯度

# 正确的断点设置方法(比颜色多1个)
col_breaks <- seq(min(mat), max(mat), length.out = 256) # 256 = 255+1

# 绘制热力图(修正参数)
heatmap.2(mat,
          col = my_palette,
          breaks = col_breaks, # 现在长度正确
          main = "鸢尾花特征热力图",
          scale = "row", # 关键参数:按行标准化
          dendrogram = "both",
          trace = "none",
          margins = c(10, 10),
          key = TRUE,
          keysize = 1.5,
          density.info = "none",
          
          # 修正聚类参数
          hclustfun = function(x) hclust(x, method = "complete"),
          distfun = function(x) dist(x, method = "euclidean"),
          
          # 标签参数
          cexRow = 0.7,
          cexCol = 0.7,
          srtCol = 45
)
## Warning in heatmap.2(mat, col = my_palette, breaks = col_breaks, main =
## "鸢尾花特征热力图", : Using scale="row" or scale="column" when breaks
## arespecified can produce unpredictable results.Please consider using only one
## or the other.
## Warning in image.default(z = matrix(z, ncol = 1), col = col, breaks =
## tmpbreaks, : 'breaks'没有被排序,在使用前会对之进行排序
# 添加图例
legend("topright", 
       legend = levels(data$Species),
       fill = brewer.pal(3, "Set1"),
       title = "Species")

图形观察和代码编写的心得体会

  • 颜色映射的艺术
  • 使用YlOrRd色系后,Setosa在花瓣特征上的低值区域(深橙色)与其他两类的高值区域(亮黄色)形成鲜明对比

  • 颜色渐变中每个色阶差异肉眼可辨,避免了原始方案中相邻值颜色跳跃不明显的问题

  1. 聚类树解读
  • 行聚类树清晰显示三个主要分支,对应三个物种

  • 列聚类树中,花瓣长度和宽度首先合并,印证了这两个特征的高度相关性

  • 花萼特征的聚类位置反映了其独立性

  1. 标准化效果验证
  • 通过scale="row",每行特征值被压缩到相同范围,避免了个别大数值特征(如花萼宽度)主导颜色分布

  • 未标准化时(错误示范),整个热力图会被1-2个特征”染成”单一颜色带