rsemplot

Setting different colors for specific items in semPlots


I want to set a different color for items Q3 and Q9 (for example) to highlight these items as in the following figure:

enter image description here

Is there any trick to make that happens. I have tried to learn and done trial and error for the past few weeks but no luck.

The following are the data and my codes:

library(lavaan)
library(semPlot)

baseData<- c(1,2,3,4,5) # categories
s <- 500 # sample size
set.seed(11)
catdata <- data.frame(
  Q1 = sample(baseData, size = s, replace = TRUE),
  Q2 = sample(baseData, size = s, replace = TRUE),
  Q3 = sample(baseData, size = s, replace = TRUE),
  Q4 = sample(baseData, size = s, replace = TRUE),
  Q5 = sample(baseData, size = s, replace = TRUE),
  Q6 = sample(baseData, size = s, replace = TRUE),
  Q7 = sample(baseData, size = s, replace = TRUE),
  Q8 = sample(baseData, size = s, replace = TRUE),
  Q9 = sample(baseData, size = s, replace = TRUE),
  Q10 = sample(baseData, size = s, replace = TRUE),
  Q11 = sample(baseData, size = s, replace = TRUE),
  Q12 = sample(baseData, size = s, replace = TRUE),
  Q13 = sample(baseData, size = s, replace = TRUE),
  Q14 = sample(baseData, size = s, replace = TRUE),
  Q15 = sample(baseData, size = s, replace = TRUE)
  )

my_model <- '
Factor 1 =~ Q1 + Q2 + Q3 + Q4 + Q5
Factor 2 =~ Q6 + Q7 + Q8 + Q9 + Q10
Factor 3 =~ Q11 + Q12 + Q13 + Q14 + Q15
'

model_fit <- cfa(my_model, data = catdata)

plot <- semPaths(model_fit, whatLabels="std", layout="circle2", style = "lisrel", 
                        curve = 2, rotation = 3, shapeLat = "ellipse", shapeMan = "circle", sizeMan = 6,
                        nCharNodes = 0, intercepts = FALSE, residuals = FALSE,  exoCov = TRUE, edge.label.cex = 0.75, nDigits = 2, edge.label.color = "black")

Solution

  • Make sure to use get_edges() from the tidySEM package, not ggraph:

    edges <- tidySEM::get_edges(model_fit)
    edge_color <- ifelse(edges$to %in% c("Q3", "Q9") & edges$arrow == "last",
      "orange", "black")
    
    plot <- semPaths(model_fit, whatLabels="std", layout="circle2", 
      style = "lisrel", curve = 2, rotation = 3, shapeLat = "ellipse", 
      shapeMan = "circle", sizeMan = 6, nCharNodes = 0, intercepts = FALSE,
      residuals = FALSE,  exoCov = TRUE, edge.label.cex = 0.75, nDigits = 2,
      edge.label.color = "black", edge.color = edge_color)