【问题标题】:Change loadings (arrows) length in PCA plot using ggplot2/ggfortify?使用 ggplot2/ggfortify 更改 PCA 图中的载荷(箭头)长度?
【发布时间】:2016-06-25 17:54:01
【问题描述】:

我一直在努力重新调整 ggplot2/ggfortify PCA 中的载荷(箭头)长度。我已经四处寻找这个问题的答案,我发现的唯一信息要么编写新的 biplot 函数,要么参考其他完全不同的 PCA 包(ggbiplot,factoextra),这两者都没有解决我想回答的问题:

是否可以在 ggfortify 中缩放/更改 PCA 负载的大小?

下面是我必须使用股票 R 函数绘制 PCA 的代码,以及使用 autoplot/ggfortify 绘制 PCA 的代码。您会注意到,在库存 R 图中,我可以通过简单地乘以一个标量(此处为 *20)来缩放负载,这样我的箭头就不会在 PCA 图的中间狭窄。使用自动绘图...不是那么多。我错过了什么?如有必要,我会转到另一个包,但我真的很想更好地了解 ggfortify。

在我发现的其他网站上,图表轴限制似乎从未超过 +/- 2。我的图表变为 +/- 20,并且负载稳定地位于 0 附近,大概与具有较小轴的图表具有相同的比例。我仍然想使用 ggplot2 绘制 PCA,但如果 ggfortify 不这样做,那么我需要找到另一个包。

#load data geology rocks frame
georoc <- read.csv("http://people.ucsc.edu/~mclapham/earth125/data/georoc.csv")

#load libraries
library(ggplot2)
library(ggfortify)

geo.na <- na.omit(georoc) #remove NA values
geo_matrix <- as.matrix(geo.na[,3:29]) #create matrix of continuous data in data frame
pca.res <- prcomp(geo_matrix, scale = T) #perform PCA using correlation matrix (scale = T)
summary(pca.res) #return summary of PCA

#plotting in stock R
plot(pca.res$x, col = c("salmon","olivedrab","cadetblue3","purple")[geo.na$rock.type], pch = 16, cex = 0.2)
#make legend
legend("topleft", c("Andesite","Basalt","Dacite","Rhyolite"), 
       col = c("salmon","olivedrab","cadetblue3","purple"), pch = 16, bty = "n")
#add loadings and text
arrows(0, 0, pca.res$rotation[,1]*20, pca.res$rotation[,2]*20, length = 0.1)
text(pca.res$rotation[,1]*22, pca.res$rotation[,2]*22, rownames(pca.res$rotation), cex = 0.7)

#plotting PCA
autoplot(pca.res, data = geo.na, colour = "rock.type", #plot results, name using original data frame
         loadings = T, loadings.colour =  "black", loadings.label = T,
         loadings.label.colour = "black")

数据来自我正在学习的课程的在线文件,所以如果你安装了 ggplot2 和 ggfortify 包,你可以复制它。下图。

R plot of what I want ggplot to look like

What ggplot actually looks like

编辑: 在下面添加可重现的代码。

iris.res <- 
  iris %>% 
  select(Sepal.Length:Petal.Width) %>% 
  as.matrix(.) %>% 
  prcomp(., scale = F)

autoplot(iris.res, data = iris, size = 4, col = "Species", shape = "Species", 
         x = 1, y = 2, #components 1 and 2
         loadings = T, loadings.colour = "grey50", loadings.label = T, 
         loadings.label.colour = "grey50", loadings.label.repel = T) + #loadings are arrows
  geom_vline(xintercept = 0, lty = 2) +
  geom_hline(yintercept = 0, lty = 2) +
  theme(aspect.ratio = 1) +
  theme_bw()

【问题讨论】:

  • 您指向 csv 的链接不存在,因此我无法复制它。但是,通过查看您的结果,您的文本标签似乎非常混乱,所以我建议安装 ggrepel 包,然后再次运行您的代码。
  • 另外,您可以在autoplot 中传递其他参数,这些参数将在ggfortify 中传递给ggbiplot。看看?ggbiplot 看看你是否能找到你需要的任何参数,例如loadings.label.size.
  • 对链接感到抱歉,似乎粗略的已更改,URL 也是如此。感谢您的提示!
  • @YuanTang 您好,感谢您的提示!但是,仍然没有解决方案可以使用ggfortify 更改加载的箭头大小和线宽。
  • @pengchy 答案可能是否定的。自动绘图有一个缩放功能,但它通过一个选定的因子来缩放整个绘图,而不仅仅是箭头提示。

标签: r ggplot2 pca ggfortify


【解决方案1】:

这个答案可能在 OP 需要它很久之后,但我提供它是因为我一直在努力解决同样的问题,也许我可以节省其他人同样的努力。

# Load data
iris <- data.frame(iris)

# Do PCA
PCA <- prcomp(iris[,1:4])

# Extract PC axes for plotting
PCAvalues <- data.frame(Species = iris$Species, PCA$x)

# Extract loadings of the variables
PCAloadings <- data.frame(Variables = rownames(PCA$rotation), PCA$rotation)

    # Plot
ggplot(PCAvalues, aes(x = PC1, y = PC2, colour = Species)) +
  geom_segment(data = PCAloadings, aes(x = 0, y = 0, xend = (PC1*5),
     yend = (PC2*5)), arrow = arrow(length = unit(1/2, "picas")),
     color = "black") +
  geom_point(size = 3) +
  annotate("text", x = (PCAloadings$PC1*5), y = (PCAloadings$PC2*5),
     label = PCAloadings$Variables)

为了增加箭头长度,在geom_segment 调用中将xendyend 的载荷相乘。通过一些尝试和努力,可以计算出要使用的数字。

要将标签放置在正确的位置,请将 PC 轴乘以 annotate 调用中的相同值。

【讨论】:

  • 好提示。最后,我选择将 PCA 保留在基础图中。不是我喜欢的绘图方法,但结果证明效果很好(特别是对于 NMDS)。不过,我会将其归档以备将来使用。
猜你喜欢
  • 1970-01-01
  • 2022-12-12
  • 2022-12-10
  • 2015-05-13
  • 1970-01-01
  • 2015-07-28
  • 2020-12-26
  • 2019-03-09
  • 2021-06-11
相关资源
最近更新 更多