jhorzek / lessSEM

lessSEM estimates sparse structural equation models.
https://jhorzek.github.io/lessSEM/
GNU General Public License v2.0
7 stars 1 forks source link

Adding labels to plot #376

Open hendriklohse opened 4 months ago

hendriklohse commented 4 months ago

As far as I know, it is not possible to add labels to the plot functions and display them in the legend. For instance, there is no color argument in c(x = "regularizedSEM", y = "missing"). However, not knowing which line is which makes the plot not very useful. Is is possible to add this feature?

Thanks!

jhorzek commented 4 months ago

Good point! I will check how I can best implement this. The main issue is that there will be overlapping labels and I don't want to add the ggrepel package as another dependency for now. In the meantime, you can use either plotly or adapt the plot post-hoc with ggrepel:

library(lessSEM)
library(ggrepel)
library(plotly)
# Identical to regsem, lessSEM builds on the lavaan
# package for model specification. The first step
# therefore is to implement the model in lavaan.

dataset <- simulateExampleData()

lavaanSyntax <- "
f =~ l1*y1 + l2*y2 + l3*y3 + l4*y4 + l5*y5 + 
     l6*y6 + l7*y7 + l8*y8 + l9*y9 + l10*y10 + 
     l11*y11 + l12*y12 + l13*y13 + l14*y14 + l15*y15
f ~~ 1*f
"

lavaanModel <- lavaan::sem(lavaanSyntax,
                           data = dataset,
                           meanstructure = TRUE,
                           std.lv = TRUE)

# Regularization:

lsem <- lasso(
  # pass the fitted lavaan model
  lavaanModel = lavaanModel,
  # names of the regularized parameters:
  regularized = paste0("l", 6:15),
  # in case of lasso and adaptive lasso, we can specify the number of lambda
  # values to use. lessSEM will automatically find lambda_max and fit
  # models for nLambda values between 0 and lambda_max. For the other
  # penalty functions, lambdas must be specified explicitly
  nLambdas = 50)

# use the plot-function to plot the regularized parameters:
plt <- plot(lsem)

# Option 1: Use plotly
plotly::ggplotly(plt)
# You can now hover over the lines to see the parameter names

# Option 2: Add labels with ggrepel:
plt + 
  geom_text_repel(data = plt$data |> 
                    filter(lambda == min(lambda)),
                  aes(x = lambda,
                      y = value,
                      label = name))
hendriklohse commented 4 months ago

Thanks for the quick reply! I don't see the plotly plot but the ggrepel option works great! I added + geom_line(aes(colour = name)) to color the lines too.