semPlot icon indicating copy to clipboard operation
semPlot copied to clipboard

`semPaths(..., DoNotPlot = TRUE)` Produces an Error in Multigroup Models

Open jorgesinval opened this issue 1 year ago • 3 comments

When I use multigroup models, I encounter this strange error:

library(lavaan)
#> This is lavaan 0.6-19
#> lavaan is FREE software! Please report any bugs.
library(semPlot)

model <- "visual  =~ x1 + x2 + x3
              textual =~ x4 + x5 + x6
              speed   =~ x7 + x8 + x9 "
fit <- cfa(model = model, data = HolzingerSwineford1939, group = "school")

plots_cfa <- semPaths(object = fit,
                      thresholds = F,
                      whatLabels = "std",
                      intercepts = F,
                      exoCov = T,
                      style = "ram",
                      curvePivot=TRUE,
                      edge.color="black",
                      DoNotPlot = T) #can't use TRUE, otherwise produces an error '
#> Error in title(gr, col.main = title.color, adj = title.adj, outer = TRUE, : plot.new has not been called yet

If I use DoNotPlot = FALSE, it works. However, I do not want to plot immediately because I plan to modify the diagrams (using semptools) before plotting them. My solution in an R Markdown file was to use the chunk option fig.keep = "none".

Created on 2024-12-16 with reprex v2.1.1

jorgesinval avatar Dec 16 '24 04:12 jorgesinval

I found a workaround. Not an ideal solution but it works for the current version of semPlot.

Add title = FALSE when calling semPaths(). If title is needed, add the title manually when plotting it, using title(). Note that the top margin needs to be increased to accommodate the title when calling semPaths().

library(lavaan)
#> This is lavaan 0.6-19
#> lavaan is FREE software! Please report any bugs.
library(semPlot)

model <- "visual  =~ x1 + x2 + x3
              textual =~ x4 + x5 + x6
              speed   =~ x7 + x8 + x9 "
fit <- cfa(model = model, data = HolzingerSwineford1939, group = "school")

plots_cfa <- semPaths(object = fit,
                      thresholds = F,
                      whatLabels = "std",
                      intercepts = F,
                      exoCov = T,
                      style = "ram",
                      curvePivot=TRUE,
                      edge.color="black",
                      title = FALSE,
                      mar = c(3, 3, 10, 3),
                      DoNotPlot = T)
plot(plots_cfa[[1]])
title("Group 1")

plot(plots_cfa[[2]])
title("Group 2")

Created on 2024-12-17 with reprex v2.1.1

The error occurred because if title is set when calling semPaths(), title() will be called:

https://github.com/SachaEpskamp/semPlot/blob/da8fcf47e61f7ed202d12f2cc01e2a9666bed6f5/R/semPaths.R#L1690-L1695

This will result in an error when the output is not plotted (DoNotPlot = TRUE).

If the model is a multigroup model, title will be created internally even if title is not set when calling semPaths(), hence the error.

I found that this error will also occur for a single-group model when title is set and DoNotPlot = TRUE, though due to a different line of the code:

library(lavaan)
#> This is lavaan 0.6-19
#> lavaan is FREE software! Please report any bugs.
library(semPlot)

model <- "visual  =~ x1 + x2 + x3
              textual =~ x4 + x5 + x6
              speed   =~ x7 + x8 + x9 "
fit <- cfa(model = model, data = HolzingerSwineford1939)

plots_cfa <- semPaths(object = fit,
                      thresholds = F,
                      whatLabels = "std",
                      intercepts = F,
                      exoCov = T,
                      style = "ram",
                      curvePivot=TRUE,
                      edge.color="black",
                      title = "Test Title",
                      DoNotPlot = T)
#> Error in if (title) Mar[3] <- Mar[3] + 2: argument is not interpretable as logical

Created on 2024-12-17 with reprex v2.1.1

This error can also be solved tentatively by adding the title later, as in the case of multigroup models.

sfcheung avatar Dec 17 '24 13:12 sfcheung

Excellent solution! Thanks!

jorgesinval avatar Dec 19 '24 20:12 jorgesinval

title = FALSE fixed the problem! I believe this should be the default behaviour when donotplot is true

albertostefanelli avatar Jul 05 '25 14:07 albertostefanelli