## ── 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 数据集(鸢尾花数据集)是统计学和机器学习领域最经典的案例数据集之一,由英国统计学家 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
类的花通常较小,花瓣短而宽,与其他两类差异明显;versicolor
和 virginica
在部分特征上有重叠,分类难度更高。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.
图形观察
整体模式:
Setosa品种(红色)在所有指标上与其他两个品种明显分离
Versicolor和Virginica有一定重叠但在花瓣尺寸上存在差异
特征关系:
花瓣长度和宽度呈现正相关趋势
花萼宽度在Setosa中表现突出
数据重塑技巧:
平行坐标图需要将宽数据转为长格式,gather()/pivot_longer()是关键
为每条观察添加唯一ID(id)是连接各维度点的关键
可视化优化:
同时使用线条和点增强了图形可读性
图例位置和格式调整避免了遮挡数据
轴标签旋转解决了长标签重叠问题
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.loc和mar:需反复调试以避免图形元素重叠。
局限性:
变量顺序影响图形解读(建议按相关性或逻辑排序)。
大数据集时易产生视觉混乱(可抽样或聚合后绘制)。
改进方向:
添加标题和轴注释(如main="鸢尾花特征星形图")。
使用颜色区分物种(如col=rainbow(3)[data$Species])。
结合其他图表(如箱线图)补充统计信息。
aplpack::faces 函数,作Species
三个类别的脸谱图Species
作为矩阵的行名;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)可能更夸张或抽象。物种区分:
setosa、versicolor、virginica)的脸谱应有明显差异,尤其是setosa(通常花萼较宽、花瓣较短)与其他两个物种不同。factoextra::fviz_dend
函数,对标准化后数据作图;Species
作为矩阵的行名;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.
图形观察
聚类效果分析:
Setosa分离明显:红色分支(通常对应Setosa)与其他两类完全分离,这与原始Species分类一致,表明Setosa的花型特征与其他两种鸢尾花差异显著。
Versicolor和Virginica部分重叠:绿色和蓝色分支(对应Versicolor和Virginica)在树状图中有交叉,说明这两个物种在某些样本上特征相似,可能源于花瓣尺寸的连续变异。
矩形框标记:三个彩色矩形框清晰标出了聚类边界,但Virginica的矩形框可能覆盖了部分本应属于Versicolor的样本。
与原始分类对比:
table(cutree(hc, k=3), data$Species)可量化分类差异,预期Setosa的准确率接近100%,而Versicolor和Virginica可能存在约10-15%的误分。圆形布局优势:
数据预处理关键步骤:
标准化必要性:scale(mat)消除了不同特征(如花萼长度和花瓣宽度)的量纲差异,避免数值较大的特征主导距离计算。
行名设置技巧:rownames(mat) <- data[,5]将Species信息保留为行名,使得最终图形能直接显示样本类别,增强可解释性。
聚类方法选择:
Ward.D2算法的适用性:该方法最小化簇内方差,适合欧氏距离,能产生平衡的簇。对于鸢尾花这种类别大小相近的数据表现良好。
距离度量:欧氏距离直观反映多维空间中的样本差异,但对异常值敏感。若数据存在离群点,可尝试曼哈顿距离(method = "manhattan")。
采用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
三个类别在主成分空间中的分布呈现明显区隔
第一主成分(x轴)方向上的分离度最为显著
部分样本点位于聚类边界区域,可能是潜在异常值
每个聚类的椭圆轮廓反映了数据的分布密度
椭圆大小和方向显示了各类别的离散程度和相关特征
紧凑的椭圆表示内部样本特征高度一致
位于聚类边界或重叠区域的点值得关注
远离所属聚类中心的样本可能需要进一步检查
标准化步骤确保各特征具有相同量纲
合理的行名设置便于后续结果追踪
选择合适的聚类数量和初始化参数
多次运行确保结果稳定性
主成分降维有效展示高维数据
椭圆轮廓增强聚类边界识别
异常点突出标记便于观察
轮廓系数提供量化评估标准
与原始类别对比验证聚类效果
采用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在花瓣特征上的低值区域(深橙色)与其他两类的高值区域(亮黄色)形成鲜明对比
颜色渐变中每个色阶差异肉眼可辨,避免了原始方案中相邻值颜色跳跃不明显的问题
行聚类树清晰显示三个主要分支,对应三个物种
列聚类树中,花瓣长度和宽度首先合并,印证了这两个特征的高度相关性
花萼特征的聚类位置反映了其独立性
通过scale="row",每行特征值被压缩到相同范围,避免了个别大数值特征(如花萼宽度)主导颜色分布
未标准化时(错误示范),整个热力图会被1-2个特征”染成”单一颜色带