0

I'm using the autoplot function in R (from the ggfortify package) to plot the first two components of a PCA, like this, using the iris dataset as an example:

data<-iris
data_dims<-(data[, 1:4])
data$Species<-as.factor(data$Species)
plot1<-autoplot(prcomp(data_dims, center = TRUE, scale = TRUE), data = data, colour = 'Species', frame = TRUE)

However, I'm wondering if anyone could help me to plot the rotated solution instead? I know to get the rotated solution like this:

pcompanalysis<-prcomp(data, center = TRUE, scale = TRUE)

pcompanalysis_rot <- varimax(pcompanalysis$rotation)

However, I'm unsure how to then use this rotated solution in the autoplot() function?

Edit: Examples are now using the iris dataset to allow reproduction.

Dave
  • 232
  • 1
  • 2
  • 14
  • Please see [here](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) for how to make this a question that folks can more easily help with, including how to post a sample of your data – camille Apr 30 '18 at 18:10
  • Thanks for pointing this out, the examples now use the iris dataset and are reproducible. – Dave Apr 30 '18 at 18:24

1 Answers1

2

Here is a possibile solution:

library(ggfortify)
library(pracma)

# Generate a dataset
set.seed(1234) 
n <- 20
p <- 25
ncomp <- 2
data_dims <- matrix(rnorm(n*p),nrow=n)
data <- data.frame(data_dims, Species=cut(runif(n), breaks=4))

# Perform PCA and calculate varimax rotated scores
pca.obj <- prcomp(data_dims, center=T, scale=T)
rawLoadings <- pca.obj$rotation[,1:ncomp] %*% diag(pca.obj$sdev, ncomp, ncomp)
varimax.obj <- varimax(rawLoadings)
rotatedLoadings <- varimax.obj$loadings

# Create a prcomp object with varimax rotated scores
pca_obj <- list(sdev=pca.obj$sdev, rotation=t(varimax.obj$rotmat), 
              center=NULL, scale=NULL, x=scale(pca.obj$x[,1:ncomp]))
name.pcs <- paste0("PC",1:ncomp)
dimnames(pca_obj$rotation) <- list(name.pcs,name.pcs)
dimnames(pca_obj$x) <- list(rownames(data_dims),name.pcs)
class(pca_obj) <- "prcomp"

plot1 <- autoplot(pca_obj, data=data, colour='Species', 
                  frame=TRUE, variance_percentage=F)
plot1

For more details see here.

enter image description here

Marco Sandri
  • 23,289
  • 7
  • 54
  • 58
  • I've been trying to scale this up to my actualy data (with 25 rating dimensions), but am getting the following error. Error in as.matrix(apply(pca_dims, 2, scale)) %*% varimax.rot : non-conformable arguments Wondering if you might be able to point me in the right direction? – Dave May 01 '18 at 01:24
  • I really appreciate you going through the trouble! Your code works with the sample data you generated; however, it still gives the same error with my data. However, I realized that the two matrices have a different number of columns when running the code on my data (data_dims has the expected 25; varimax.rot has only 20). Any idea on how to solve this, or why it is emerging? – Dave May 01 '18 at 18:06
  • I tried only taking the first twenty columns for the purpose of multiplication–is that a potential way to deal with that? See here: https://pastebin.com/HVsM1s5v However, I now get the following error: Error in scale.default(data, center = FALSE, scale = 1/scale) : length of 'scale' must equal the number of columns of 'x' – Dave May 01 '18 at 18:10
  • Ah gotcha! Thanks again for all of the help! – Dave May 01 '18 at 20:26
  • Thanks Marco! Just to double check, I've notied that the plot looks the same before and after rotation, is this to be expected? If not, I've pasted my attempt to adopt your code to my dataset, maybe I went wrong somewhere? https://pastebin.com/hLrZeJL5 – Dave May 01 '18 at 23:41