Search code examples
rsemplot

Is it possible to change the length/position of arrows in semPaths?


I am trying to use semPlot::semPaths to make a plot of a bifactor model I ran in lavaan. The documentation for semPlot and qgraph is really great, so I've been able to figure out most of the specifications I want, but there's one thing I'm not sure is fixable. As you can see in the plot below, when a latent factor (e.g., "ext") is connected to a wide range of manifest variables, it becomes difficult to track which arrows/labels are associated with which manifest variables. (For example, it's hard to tell that the ext loading for adhd3 is .23.) It looks like the arrow is trying to connect to the center of the manifest variable labels, rather than the closest side. Is there any way to change this so it's a bit easier to read? Thank you so much!

The CFA plot output, a png file.

Here is the code I used (sorry it's clunky-- 1) I'm new to this and 2) the latent variables were automatically in weird places so I defined their positions manually):

full_bif_mod <- "ext =~ cd1 + cd2 + cd3 + cd4 + cd5 + cd6 + cd7 + cd8 + cd9 + cd10 + cd11 + cd12 + cd13 + cd14 + cd15 + cd16 + cd17 + aud1 + aud2 + aud3 + aud4 + aud5 + aud6 + aud7 + aud8 + aud9 + aud10 + adhd1 + adhd2 + adhd3
                cd =~ cd1 + cd2 + cd3 + cd4 + cd5 + cd6 + cd7 + cd8 + cd9 + cd10 + cd11 + cd12 + cd13 + cd14 + cd15 + cd16 + cd17
                aud =~ aud1 + aud2 + aud3 + aud4 + aud5 + aud6 + aud7 + aud8 + aud9 + aud10
                adhd =~ adhd1 + adhd2 + adhd3
                ext ~~ 0*adhd
                ext ~~ 0*cd
                ext ~~ 0*aud
                adhd ~~ 0*cd
                adhd ~~ 0*aud
                cd ~~ 0*aud
                  "
summary((full_bifactor <- cfa(full_bif_mod, std.lv=TRUE, data=dat)),fit.measures=TRUE, standardized = T)

 
x=c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30, 15, 9, 22, 29)
y=c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,-1,-1)
ly=matrix(c(y,x), ncol=2)
semPaths(full_bifactor, layout=ly, whatLabels="std", style="lisrel", nCharNodes=5, exoCov=FALSE, residuals=FALSE, label.scale=TRUE, sizeMan2=1.5, sizeMan=6,  asize=1, edge.color="black", edge.label.color="black", edge.label.position=.8, edge.label.margin=-.1, width=17, height=20, filetype="png",filename="cfa"
        )

Solution

  • This can be done using edge connect points in qgraph! See below:

    # Save plot to object:
    Plot <- semPaths(full_bifactor, layout=ly, 
             whatLabels="std", style="lisrel", nCharNodes=5, 
             exoCov=FALSE, residuals=FALSE, label.scale=TRUE, 
             sizeMan2=1.5, sizeMan=6,  asize=1, edge.color="black", 
             edge.label.color="black", edge.label.position=.8, edge.label.margin=-.1,
             width=17, height=20, filetype="png",filename="cfa"
    )
    
    # Add edge connect point to end point of edges (2nd column) for bifactor:
    Plot$graphAttributes$Edges$edgeConnectPoints[1:30,2] <- 0.5 * pi
    
    # Add edge connect point to end point of edges (2nd column) for other factors:
    Plot$graphAttributes$Edges$edgeConnectPoints[31:60,2] <- 1.5 * pi
    
    
    # Plot again:
    library("qgraph")
    plot(Plot)
    

    With simulated data: enter image description here