Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed **and** Labeled loadings don't show up in the degrees of freedom. #208

Closed
Tracked by #212
nickhaf opened this issue Jul 1, 2024 · 4 comments · Fixed by #211
Closed
Tracked by #212

Fixed **and** Labeled loadings don't show up in the degrees of freedom. #208

nickhaf opened this issue Jul 1, 2024 · 4 comments · Fixed by #211
Labels
bug Something isn't working

Comments

@nickhaf
Copy link
Contributor

nickhaf commented Jul 1, 2024

I have a question regarding the degrees of freedom for fixed and labeled loadings. If a loading is labeled and fixed, the degrees of freedom are not updated compared to the fit with the loading unfixed. If the fixed loading is not labeled, there is no problem:

Just fixed, not labeled

using StructuralEquationModels, StenoGraphs
data = example_data("political_democracy")

observed_vars = [:x1, :x2, :x3, :y1, :y2, :y3, :y4, :y5, :y6, :y7, :y8]
latent_vars = [:ind60, :dem60, :dem65]

graph_2 = @StenoGraph begin

    # loadings
    ind60 → fixed(1)*x1 + fixed(0)*x2 + x3
    dem60 → fixed(1)*y1 + y2 + y3 + y4
    dem65 → fixed(1)*y5 + y6 + y7 + y8

    # latent regressions
    ind60 → dem60
    dem60 → dem65
    ind60 → dem65

    # variances
    _(observed_vars) ↔ _(observed_vars)
    _(latent_vars) ↔ _(latent_vars)

    # covariances
    y1 ↔ y5
    y2 ↔ y4 + y6
    y3 ↔ y7
    y8 ↔ y4 + y6

end

partable_2 = ParameterTable(
    latent_vars = latent_vars,
    observed_vars = observed_vars,
    graph = graph_2)

model_2 = Sem(
    specification = partable_2,
    data = data
)

df(model_2)

Fixed and labeled

graph_3 = @StenoGraph begin

    # loadings
    ind60 → fixed(1)*x1 + label(:loading_12)*fixed(0)*x2 + x3
    dem60 → fixed(1)*y1 + y2 + y3 + y4
    dem65 → fixed(1)*y5 + y6 + y7 + y8

    # latent regressions
    ind60 → dem60
    dem60 → dem65
    ind60 → dem65

    # variances
    _(observed_vars) ↔ _(observed_vars)
    _(latent_vars) ↔ _(latent_vars)

    # covariances
    y1 ↔ y5
    y2 ↔ y4 + y6
    y3 ↔ y7
    y8 ↔ y4 + y6

end

partable_3 = ParameterTable(
    latent_vars = latent_vars,
    observed_vars = observed_vars,
    graph = graph_3)

model_3 = Sem(
    specification = partable_3,
    data = data
)

df(model_3)

When fitting this model with sem_fit(model_2) I get a warning that I'm using a labeled constant. However, I can also extract the df before fitting the model, in which case I don't get the warning. In either case, I found this a bit counterintuitive, in lavaan both is possible:

Lavaan

library(lavaan)

## Not fixed: 
model <- '
  # measurement model
    ind60 =~ x1 + x2 + x3
    dem60 =~ y1 + y2 + y3 + y4
    dem65 =~ y5 + y6 + y7 + y8
  # regressions
    dem60 ~ ind60
    dem65 ~ ind60 + dem60
  # residual correlations
    y1 ~~ y5
    y2 ~~ y4 + y6
    y3 ~~ y7
    y4 ~~ y8
    y6 ~~ y8
'

fit_1 <- sem(model, data = PoliticalDemocracy)
fitMeasures(fit_1, "df")


## Fixed and labeled:
model <- '
  # measurement model
    ind60 =~ x1 + 0*testlabel*x2 + x3
    dem60 =~ y1 + y2 + y3 + y4
    dem65 =~ y5 + y6 + y7 + y8
  # regressions
    dem60 ~ ind60
    dem65 ~ ind60 + dem60
  # residual correlations
    y1 ~~ y5
    y2 ~~ y4 + y6
    y3 ~~ y7
    y4 ~~ y8
    y6 ~~ y8
'

fit_2 <- sem(model, data = PoliticalDemocracy)
fitMeasures(fit_2, "df")

@Maximilian-Stefan-Ernst
Copy link
Collaborator

Thanks a lot for raising this issue, I will have a look!

@Maximilian-Stefan-Ernst Maximilian-Stefan-Ernst added the bug Something isn't working label Jul 12, 2024
@Maximilian-Stefan-Ernst
Copy link
Collaborator

I'm not sure how to proceed - internally, we label all fixed parameters as :const and reserve that label for fixed parameters. So we could either allow for labeled fixed parameters, or throw an error on model construction. @nickhaf is there actually a use case for labeled & fixed parameters?

@nickhaf
Copy link
Contributor Author

nickhaf commented Jul 17, 2024

I played around with a "relaxed lasso" implementation when I noticed this issue. For this very niche application it might be helpful to be able to label and fix parameters, but even here it is definitely not necessary. So in my opinion throwing a clear error message would be enough for now.

@Maximilian-Stefan-Ernst Maximilian-Stefan-Ernst linked a pull request Aug 7, 2024 that will close this issue
@Maximilian-Stefan-Ernst
Copy link
Collaborator

This should be fixed in the next release. Thanks again for reporting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants