ecmerkle/blavaan

problem with translation from lavaan to MCMC syntax

littlehifive opened this issue · 3 comments

Hi Ed, @bgoodri suggested that I come to you again for this question:

See the simulated dataset (test.csv) and a minimal example below for a pretty complex model that we are trying. We got this error message when trying to run the chunk below. The lavaan model syntax seems to be okay since it runs with lavaan::sem().

blavaan NOTE: ordinal models are new, please report bugs!
https://github.com/ecmerkle/blavaan/issues

[1] "Error in if (lamsign[l2, 1] == 1) l2 <- lamsign[l2, 2] : \n  argument is of length zero\n"
attr(,"class")
[1] "try-error"
attr(,"condition")
<simpleError in if (lamsign[l2, 1] == 1) l2 <- lamsign[l2, 2]: argument is of length zero>
Error in blavaan(model_all_1, data = test, ordered = c("PSRA1
[test.csv](https://github.com/ecmerkle/blavaan/files/8751283/test.csv)
_1", "PSRA2_1",  : 
  blavaan ERROR: problem with translation from lavaan to MCMC syntax.
model_all_1 <- '
    # CFA
    PSRA_1 =~ fl1*PSRA1_1 + fl2*PSRA2_1 + fl3*PSRA3_1 + fl4*PSRA4_1 + fl5*PSRA5_1 + fl6*PSRA6_1 + fl7*PSRA7_1 + fl8*PSRA8_1 + fl9*PSRA9_1 + fl10*PSRA10_1 + fl11*PSRA11_1 + fl12*PSRA12_1 + fl13*PSRA13_1
    
    PSRA_2 =~ fl1*PSRA1_2 + fl2*PSRA2_2 + fl3*PSRA3_2 + fl4*PSRA4_2 + fl5*PSRA5_2 + fl6*PSRA6_2 + fl7*PSRA7_2 + fl8*PSRA8_2 + fl9*PSRA9_2 + fl10*PSRA10_2 + fl11*PSRA11_2 + fl12*PSRA12_2 + fl13*PSRA13_2
    
    PSRA_3 =~ fl1*PSRA1_3 + fl2*PSRA2_3 + fl3*PSRA3_3 + fl4*PSRA4_3 + fl5*PSRA5_3 + fl6*PSRA6_3 + fl7*PSRA7_3 + fl8*PSRA8_3 + fl9*PSRA9_3 + fl10*PSRA10_3 + fl11*PSRA11_3 + fl12*PSRA12_3 + fl13*PSRA13_3
    
    # thresholds

PSRA1_1|a1*t1 + a2*t2 + a3*t3
PSRA1_2|a1*t1 + a2*t2 + a3*t3
PSRA1_3|a1*t1 + a2*t2 + a3*t3

PSRA2_1|b1*t1 + b2*t2 + b3*t3
PSRA2_2|b1*t1 + b2*t2 + b3*t3
PSRA2_3|b1*t1 + b2*t2 + b3*t3

PSRA3_1|c1*t1 + c2*t2 + c3*t3
PSRA3_2|c1*t1 + c2*t2 + c3*t3
PSRA3_3|c1*t1 + c2*t2 + c3*t3

PSRA4_1|d1*t1 + d2*t2 + d3*t3
PSRA4_2|d1*t1 + d2*t2 + d3*t3
PSRA4_3|d1*t1 + d2*t2 + d3*t3

PSRA5_1|e1*t1 + e2*t2 + e3*t3
PSRA5_2|e1*t1 + e2*t2 + e3*t3
PSRA5_3|e1*t1 + e2*t2 + e3*t3

PSRA6_1|f1*t1 + f2*t2 + f3*t3
PSRA6_2|f1*t1 + f2*t2 + f3*t3
PSRA6_3|f1*t1 + f2*t2 + f3*t3

PSRA7_1|g1*t1 + g2*t2 + g3*t3
PSRA7_2|g1*t1 + g2*t2 + g3*t3
PSRA7_3|g1*t1 + g2*t2 + g3*t3

PSRA8_1|h1*t1 + h2*t2 + h3*t3
PSRA8_2|h1*t1 + h2*t2 + h3*t3
PSRA8_3|h1*t1 + h2*t2 + h3*t3

PSRA9_1|i1*t1 + i2*t2 + i3*t3
PSRA9_2|i1*t1 + i2*t2 + i3*t3
PSRA9_3|i1*t1 + i2*t2 + i3*t3

PSRA10_1|j1*t1 + j2*t2 + j3*t3
PSRA10_2|j1*t1 + j2*t2 + j3*t3
PSRA10_3|j1*t1 + j2*t2 + j3*t3

PSRA11_1|k1*t1 + k2*t2 + k3*t3
PSRA11_2|k1*t1 + k2*t2 + k3*t3
PSRA11_3|k1*t1 + k2*t2 + k3*t3

PSRA12_1|l1*t1 + l2*t2 + l3*t3
PSRA12_2|l1*t1 + l2*t2 + l3*t3
PSRA12_3|l1*t1 + l2*t2 + l3*t3

PSRA13_1|m1*t1 + m2*t2 + m3*t3
PSRA13_2|m1*t1 + m2*t2 + m3*t3
PSRA13_3|m1*t1 + m2*t2 + m3*t3

  # CFA
  
  # measurement model
  EGRA_1 =~ VOC_1 + LTRC_1 + GRPH_1 + INV_1 + OPR_1 + RDCP_1
  GRPH_1 ~~ LTRC_1
  RDCP_1 ~~ VOC_1
  RDCP_1 ~~ OPR_1
  
    # measurement model
  EGRA_2 =~ VOC_2 + LTRC_2 + GRPH_2 + INV_2 + OPR_2 + RDCP_2
  GRPH_2 ~~ LTRC_2
  RDCP_2 ~~ VOC_2
  RDCP_2 ~~ OPR_2
  
    # measurement model
  EGRA_3 =~ VOC_3 + LTRC_3 + GRPH_3 + INV_3 + OPR_3 + RDCP_3
  GRPH_3 ~~ LTRC_3
  RDCP_3 ~~ VOC_3
  RDCP_3 ~~ OPR_3
 
# cross-lagged effects

    # region
    IC_2 ~ IC_1
    IC_3 ~ IC_1 + IC_2
    WM_2 ~ WM_1
    WM_3 ~ WM_1 + WM_2
    
    PSRA_2 ~ PSRA_1 + IC_1
    PSRA_3 ~ PSRA_1 + PSRA_2 + IC_2
    
    EGRA_2 ~ EGRA_1 + PSRA_1 + IC_1
    EGRA_3 ~ EGRA_1 + EGRA_2 + PSRA_2 + IC_2
    
# fully correlated at each wave
    EGRA_1 ~~ PSRA_1 + IC_1 + WM_1
    PSRA_1 ~~ IC_1 + WM_1
    IC_1 ~~ WM_1

    EGRA_2 ~~ PSRA_2 + IC_2 + WM_2
    PSRA_2 ~~ IC_2 + WM_2
    IC_2 ~~ WM_2

    EGRA_3 ~~ PSRA_3 + IC_3 + WM_3
    PSRA_3 ~~ IC_3 + WM_3
    IC_3 ~~ WM_3
'
mydp <- dpriors(tau = "normal(0, 0.5)",
                lambda = "normal(0, 2)",
                beta = "normal(0.5,0.2)",
                rho = "beta(1,1)",
                nu = "normal(0, 5)")

fit_all_1 <- bsem(model_all_1, data = test,
            ordered = c("PSRA1_1", "PSRA2_1", "PSRA3_1",
                        "PSRA4_1", "PSRA5_1", "PSRA6_1",
                        "PSRA7_1", "PSRA8_1", "PSRA10_1",
                        "PSRA11_1", "PSRA12_1", "PSRA13_1",
                        "PSRA1_2", "PSRA2_2", "PSRA3_2",
                        "PSRA4_2", "PSRA5_2", "PSRA6_2",
                        "PSRA7_2", "PSRA8_2", "PSRA10_2",
                        "PSRA11_2", "PSRA12_2", "PSRA13_2",
                        "PSRA1_3", "PSRA2_3", "PSRA3_3",
                        "PSRA4_3", "PSRA5_3", "PSRA6_3",
                        "PSRA7_3", "PSRA8_3", "PSRA10_3",
                        "PSRA11_3", "PSRA12_3", "PSRA13_3"
                        ),
           dp = mydp,
           std.lv=TRUE,
           seed = 1234)

Thanks for the report. I need to look at it more, but I am almost sure it is std.lv=TRUE causing the problem. If you can use std.lv=FALSE, that might be the easiest solution.

Some more detail: for std.lv=TRUE, we use the "flip the signs in generated quantities" approach described here. But if we flip the sign of a loading, then we also have to flip the signs of other parameters involving the corresponding latent variable. This can get complicated to code and to test, and I'm guessing there is a bug in there. I have sometimes thought that it would be easier to enforce the sign constraint with truncated priors, instead of this sign flipping (though truncated priors might cause problems for the sampler).

Thanks! The model runs when std.lv = F.

Thanks, this should be fixed by commit 34ad9e7.

I am hoping to speed up these ordinal models and have been reading all the truncated multivariate normal stuff recently (including Ben's Stan materials). Any ideas are welcome!