我正在尝试可视化 PCA 结果,我想要一个象限图 (fviz_pca_var) 直观地显示各组,然后使用一个条形图显示贡献的实际值 (fviz_contrib)
理想情况下,我希望 fviz_contrib 条形图与我用于识别 fviz_pca_var 图中的簇的颜色相匹配。当我尝试通过“填充”或“颜色”参数执行此操作时,出现错误:
Caused by error in `if (fill %in% names(data)) ...
! the condition has length > 1`:
这是我用来获取集群组的代码:
var <- get_pca_var(data_no_na.std.pc)
set.seed(123)
res.km <- kmeans(var$coord, centers = 3, nstart = 25)
grp <- as.factor(res.km$cluster)
grp 对象是我的分组——它看起来像一个具有三个级别的因子列表,其中我的所有变量都分配为 1,2 或 3。
创建绘图本身的代码是;
fviz_contrib(data_no_na.std.pc, choice="var", axes = 1, top=50, fill=grp,
color="black") +
scale_fill_manual(value=c("#481567FF", "#E7B800", "#20A387FF"),
breaks=grp)
结果将是常规的 fviz_contrib 条形图,但条形图根据我将该变量分配给 (1,2,3) 的组显示不同的颜色。我尝试了解决方案here,但是当我尝试基于 grp 对象填充时,它不起作用,并且我尝试将 grp 作为它自己的元素附加到 data_no_na.std.pc 对象中并使用它,但是它也不起作用(我收到“未知颜色名称”错误):
data_no_na.std.pc$grp <- grp
fviz_contrib(data_no_na.std.pc, choice="var", axes = 1, top=50, fill="grp",
color="black")
有什么想法吗?这看起来应该很简单......
对于任何有兴趣的人,我想出了如何做到这一点。我分解了 fviz_contrib 函数本身(如果需要,您可以将其重新转换为函数,但我只需运行一次,因此我将其保留为多行代码),我没有使用 ggpubr,而是使用了 ggplot:
library(factoextra)
library(ggplot2)
#Calculate the contrib and make new dataframe
dd <- facto_summarize(data.std.pc, element = "var", result =
"contrib",
axes = 1:2)
contrib <- dd$contrib
theo_contrib <- 100/length(contrib)
names(contrib) <- rownames(dd)
df <- data.frame(name = factor(names(contrib), levels = names(contrib)),
contrib = contrib, stringsAsFactors = TRUE)
grp1 <- data.frame(grp)
grp1 <- tibble::rownames_to_column(grp1, "name")
df1 <- left_join(df, grp1, by="name")
# Calculate the dotted line
axes = 1:2
eig <- get_eigenvalue(data_no_na.std.pc)[axes, 1]
theo_contrib <- sum(theo_contrib * eig)/sum(eig)
# Assign colors to the correct groups and make plot
grp_cols <- c(1="#481567FF", 2="#E7B800", 3="#20A387FF")
ggplot(df1, aes(x=reorder(name, -contrib), y=contrib, fill=grp)) +
geom_bar(stat="identity") +
geom_hline(yintercept = theo_contrib, linetype = 2, color = "black") +
theme(axis.text.x=element_text(angle=45,hjust=0.5,vjust=0.5,
size=11)) +
scale_fill_discrete(labels = scales::parse_format()) +
scale_x_discrete(labels = ggplot2:::parse_safe) + # I had subscripts in the labels, you don't need to include this unless you too have subscripts
scale_fill_manual(values=grp_cols) +
theme(axis.title.x=element_blank(),
panel.background = element_rect(fill = "white", colour =
"grey50")) +
labs(y = element_text("Contribution (%)"),
title="Contribution of variables to PC1 & PC2")+
guides(fill=guide_legend(title="Cluster"))