Dependence of factor loadings on rotation method

Black points are initial unrotated loadings. Showing only the first two factors
show with app
  • server.R
  • ui.R
library(shiny)
library(GPArotation)
library(ggplot2)


shinyServer(function(input, output) {
   
  
  load(file="PT.values.Rdata")
    

  
  output$fact.plot <- renderPlot({
    
    formulaEFA <- formula("~creative + free + fun + adventures + different + good_time + 
    follow_rules + modest + safety")
    
    fa <- factanal(formulaEFA, factors=input$nfactors, data=PT.values, rotation = "none")
    fa2 <- factanal(formulaEFA, factors=input$nfactors, data=PT.values, rotation = input$rot.method )
    
    
    fa1.l <- as.data.frame(fa$loadings[,1:2])
    fa2.l <- as.data.frame(fa2$loadings[,1:2])
    
    #f1 - rotated axes coords
    x = matrix(c(0,1, 0, 0), ncol=2) %*% fa2$rotmat[1:2,1:2]
    x.coefs = coef(lm( x[,2]~x[,1]))
    
    #f2 - rotated axes coords
    y = matrix(c(0,0, 0, 1), ncol=2) %*% fa2$rotmat[1:2,1:2]
    y.coefs = coef(lm(y[,2] ~ y[,1]))
    
    
    gridExtra::grid.arrange(
      
      ggplot(fa1.l, aes(Factor1, Factor2))+geom_point()+
        geom_text(data=fa1.l[c("adventures", "safety"),], aes(label=c("adventures", "safety")), nudge_x = .05, nudge_y = -.05)+
        geom_point(data = fa2.l, fill="#FF4040", size = 3, shape=21)+
        geom_segment(aes(x=fa1.l$Factor1, y = fa1.l$Factor2, xend=fa2.l$Factor1, yend=fa2.l$Factor2), 
                     arrow = arrow(angle=10, length=unit(.3, "cm"), 
                                   type = "open", ends="last"), 
                     col="#FF4040")+
        geom_hline(yintercept=0)+
        geom_vline(xintercept=0, linetype = "dashed")+
        xlim(-.5,.7)+ylim(-.5,.7)+coord_equal()+ggtitle("Moving loadings"),
      
      
      ggplot(fa1.l, aes(Factor1, Factor2, label=rownames(fa1.l)))+geom_point()+
        geom_hline(yintercept=0)+
        geom_vline(xintercept=0, linetype = "dashed")+
        # geom_segment(x =  0, xend=x[2,1], y=0, yend=x[2,2], col="green", linetype = "solid")+
        # geom_segment(x =  0, xend=y[2,1], y=0, yend=y[2,2], col="green", linetype = "dashed")+
        geom_abline(intercept =  x.coefs[[1]], slope = x.coefs[[2]], col="red", linetype = "solid")+
        geom_abline(intercept =  y.coefs[[1]], slope = y.coefs[[2]], col="red", linetype = "dashed")+
        geom_text(data=fa1.l[c("adventures", "safety"),], aes(label=c("adventures", "safety")), nudge_x = .05, nudge_y = -.05)+
        xlim(-.5,.7)+ylim(-.5,.7)+coord_equal()+ggtitle("Moving axes"),
      ncol=2)
    
    
    
  })
  
  
  output$loadings.tab <- renderTable({
      
      formulaEFA <- formula("~creative + free + fun + adventures + different + good_time + 
    follow_rules + modest + safety")
      
      fa <- factanal(formulaEFA, factors=input$nfactors, data=PT.values, rotation = "none")
      fa2 <- factanal(formulaEFA, factors=input$nfactors, data=PT.values, rotation = input$rot.method )
      
      fa.load <- as.matrix(fa$loadings)
      dimnames(fa.load)[[2]] <- paste("Unrotated", dimnames(fa.load)[[2]])
      
      fa2.load <- as.matrix(fa2$loadings)
      dimnames(fa2.load)[[2]] <- paste("Rotated", dimnames(fa2.load)[[2]])
      
      cbind(fa.load,
            fa2.load) 
      
      
  }, rownames = T)
  

  
})











library(shiny)
shinyUI(fluidPage(
  
  # Application title
  titlePanel("Dependence of factor loadings on rotation method"),
  
  # Sidebar with a slider input for number of factors & rotation method 
  sidebarLayout(
    sidebarPanel(
       sliderInput("nfactors",
                   "Number of factors:",
                   min = 2,
                   max = 10,
                   value = 2),
       selectInput(inputId = "rot.method",
                   label = "Rotation method",
                   choices = c("Varimax", "geominQ", "infomaxT", "oblimin", "oblimax", "quartimax", "quartimin", "bentlerT", "infomaxT"),
                   selected = "Varimax"
                   ),
       HTML("Black points are initial unrotated loadings. Showing only the first two factors")
    ),
    
    # Show a plot of the computed loadings
    mainPanel(
      plotOutput("fact.plot"),
      tableOutput("loadings.tab")
       
    )
  )
))