r - 在进行 PCA 和聚类分析时保持与观察相关的变量分组的实用方法
问题描述
考虑这里创建的数据框data
:
set.seed(123)
data <- data.frame(State =rep(c("NY","MA","FL","GA"), each = 100),
Loc = rep(letters[1:20], each = 20),
ID = sample(600,400,replace = F),
var1 = rnorm(400),
var2 = rnorm(400),
var3 = rnorm(400),
var4 = rnorm(400),
var5 = rnorm(400))
var1:var5
是对从列表示的各种位置随机抽样的个体进行的测量,该Loc
列嵌套在较大的分组State
中。每个人都有一个唯一的ID
号码。请注意,这些ID
数字没有特定的顺序,因此如果没有相关的分组变量,测量就相对没有意义。我正在使用FactoMineR
andfactoextra
包进行 PCA 和聚类分析。假设我做了一个 PCA 并决定我要保留前 3 个主成分(我将坐标存储在一个名为的对象中ind.cords
:
library(FactoMineR)
library(factoextra)
pca<- PCA(data[,4:8], scale.unit = T, graph = F)
a <- get_pca_ind(pca)
ind.cords <- a$coord[,1:3]
接下来,我将完成确定最佳集群数量的初步步骤,我决定选择 5 个。我运行最终的 kmeans 来获得集群:
set.seed(123)
clustering <- kmeans(ind.cords, centers = 5, iter.max = 50, nstart = 25)
clustering
这是我遇到麻烦的地方:fviz_cluster()
使绘制集群变得容易:
fviz_cluster(clustering, geom = "point", data = ind.cords) + ggtitle("k = 5")
但我想使用两个分组变量来可视化哪些观察属于哪些集群。所以我需要将这些列用作标签。我可以回到我创建的位置ind.cords
并将State
Loc
, 和ID
列添加回它:ind.cords <- cbind(data[,1:3], ind.cors)
. 从这里我可以通过指定我想要对哪些列执行操作(例如,kmeans(ind.cords[,4:6]) 或者我可以创建一个名为的新对象,它只input
包含数字列(例如,input <- ind.cords[,4:6]
) ,但在任何一种情况下,我都无法弄清楚如何让fviz_
函数通过State
或标记观察结果Loc
. 有人可以演示一种实用的方法来做到这一点或解释如何重组我进行此分析的方式,以便我可以可视化哪些观察和组在哪些集群中?最终(除非有人对可视化具有许多组的集群有更好的建议)我相信如果使用彩色文本而不是分组变量(State
或Loc
)的点,并且在要显示的点周围绘制椭圆,则可视化集群会更容易它们属于什么集群,所以这就是我在图中所拍摄的。
解决方案
一种方法是仅在其上进行分层,因为我无法弄清楚在fviz_cluster()
. 您可以调整 alpha 以便您可以识别它们。示例geom_point()
set.seed(123)
data <- data.frame(State =rep(c("NY","MA","FL","GA"), each = 100),
Loc = rep(letters[1:20], each = 20),
ID = sample(600,400,replace = F),
var1 = rnorm(400),
var2 = rnorm(400),
var3 = rnorm(400),
var4 = rnorm(400),
var5 = rnorm(400))
library(FactoMineR)
library(factoextra)
pca <- PCA(data[,4:8], scale.unit = T, graph = F)
a <- get_pca_ind(pca)
ind.cords <- a$coord[,1:3]
ind.cords <- cbind(data[,1:3], ind.cords)
clustering <- kmeans(ind.cords[,4:6], centers = 5, iter.max = 50, nstart = 25)
fviz_cluster(clustering, geom = "point", data = ind.cords[,4:6], shape = 16) + ggtitle("k = 5") +
geom_point(aes(shape = ind.cords$State), alpha = 0.5)
您还可以使用geom_text()
:
fviz_cluster(clustering, geom = "point", data = ind.cords[,4:6], shape = 16) + ggtitle("k = 5") +
geom_text(aes(label = paste0(ind.cords$State, ":", ind.cords$Loc)), alpha = 0.5, size = 3, nudge_y = 0.1, show.legend = FALSE)
由reprex 包(v0.3.0)于 2020 年 6 月 8 日创建
编辑:设置geom = NULL
也有效,因此您可以通过以下方式抑制geom_point()
完成fviz_cluster()
:
fviz_cluster(clustering, geom = NULL, data = ind.cords[,4:6], shape = 16) + ggtitle("k = 5") +
geom_text(aes(label = paste0(ind.cords$State, ":", ind.cords$Loc)), size = 3, show.legend = FALSE)
编辑:集群的颜色也一样:
fviz_cluster(clustering, geom = NULL, data = ind.cords[,4:6]) +
ggtitle("k = 5") +
geom_text(aes(label = paste0(ind.cords$State, ":", ind.cords$Loc),
color = as.factor(clustering$cluster)),
size = 3, show.legend = FALSE)
推荐阅读
- ios - 存储传输服务备份 Google Firebase 存储
- graphviz - 使用 graphviz 可视化决策树:如何解决 FileNotFoundError?
- javascript - 错误是说:“list.appendChild 不是函数”
- java - 如何捕捉并修复 WebView 不使用 JS 显示 web 内容的原因
- xslt - XSLT 按属性在 xml 文件中出现的顺序列出属性
- c# - 使用没有 SQL Server 实例的数据库 (C#)
- python - 我对 openCV 卡尔曼滤波器的使用已关闭,但无法正常工作
- python - 如何使用我的本地 python 安装在远程服务器上运行本地脚本?
- javascript - 将鼠标悬停在子 ul 子菜单上时,li 菜单标题隐藏
- amazon-dynamodb - dynamodb 查询以选择与一组值匹配的所有项目