@@ -644,3 +644,131 @@ lavBootstrap <- function(fit, samples = 1000, standard = FALSE, typeStd = NULL,
644
644
return (fitinds )
645
645
}
646
646
647
+
648
+ # functions that used to be in jaspFactor, but with the new MNLFA analysis it is better to keep them here
649
+ .optionsToCFAMod <- function (options , dataset , cfaResult , base64 = TRUE ) {
650
+ gv <- options $ group
651
+ if (! base64 ) .v <- identity
652
+
653
+ vars <- options $ factors
654
+ latents <- cfaResult [[" spec" ]]$ latents
655
+ labels <- list ()
656
+ # add extra output here because the Htmt needs a model syntax without grouping labels
657
+ labels_simp <- list ()
658
+
659
+ fo <- gettext(" # Factors" )
660
+ fo_simp <- gettext(" # Factors" )
661
+ for (i in 1 : length(vars )) {
662
+ pre <- paste0(" \n " , latents [i ], " =~ " )
663
+ len <- length(vars [[i ]]$ indicators )
664
+ labelledvars <- character (len )
665
+ labels [[i ]] <- list ()
666
+ labelledvars_simp <- character (len )
667
+ labels_simp [[i ]] <- list ()
668
+ for (j in 1 : len ) {
669
+ if (nchar(options $ group ) == 0 || options $ invarianceTesting != " configural" ) {
670
+ labels [[i ]][[j ]] <- paste0(" lambda_" , i , " _" , j )
671
+ labelledvars [j ] <- paste0(" lambda_" , i , " _" , j , " *" , vars [[i ]]$ indicators [j ])
672
+ } else { # grouping variable present and configural invarianceTesting
673
+ # we need a vector with different labels per group for lavaan
674
+ n_levels <- length(unique(na.omit(dataset [[options $ group ]])))
675
+ tmp_labels <- paste0(" lambda_" , i , " _" , j , " _" , seq(n_levels ))
676
+ labels [[i ]][[j ]] <- tmp_labels
677
+ labelledvars [j ] <- paste0(" c(" , paste0(tmp_labels , collapse = " ," ), " )" , " *" , vars [[i ]]$ indicators [j ])
678
+ }
679
+ # give the simple model always since that is needed for the HTMT
680
+ labels_simp [[i ]][[j ]] <- paste0(" lambda_" , i , " _" , j )
681
+ labelledvars_simp [j ] <- paste0(" lambda_" , i , " _" , j , " *" , vars [[i ]]$ indicators [j ])
682
+ }
683
+ fo <- paste0(fo , pre , paste0(labelledvars , collapse = " + " ))
684
+ fo_simp <- paste0(fo_simp , pre , paste0(labelledvars_simp , collapse = " + " ))
685
+ }
686
+
687
+
688
+ if (! is.null(cfaResult [[" spec" ]]$ soIndics )) {
689
+ facs <- cfaResult [[" spec" ]]$ soIndics
690
+ lenvars <- length(vars )
691
+
692
+ so <- " # Second-order factor"
693
+ pre <- " \n SecondOrder =~ "
694
+ len <- length(facs )
695
+ labelledfacs <- character (len )
696
+ labels [[lenvars + 1 ]] <- list ()
697
+ for (j in 1 : len ) {
698
+ # the normal case, either no grouping or no configural invarianceTesting
699
+ if (nchar(options $ group ) == 0 || options $ invarianceTesting != " configural" ) {
700
+ labels [[lenvars + 1 ]][[j ]] <- paste0(" gamma_1_" , j )
701
+ labelledfacs [j ] <- paste0(" gamma_1_" , j , " *" , facs [j ])
702
+ } else { # grouping variable present and configural invarianceTesting
703
+ # we need a vector with different labels per group for lavaan
704
+ tmp_labels <- paste0(" gamma_1_" , j , " _" , seq(n_levels ))
705
+ labels [[lenvars + 1 ]][[j ]] <- tmp_labels
706
+ labelledfacs [j ] <- paste0(" c(" , paste0(tmp_labels , collapse = " ," ), " )" , " *" , facs [j ])
707
+ }
708
+
709
+ }
710
+
711
+ so <- paste0(so , pre , paste0(labelledfacs , collapse = " + " ))
712
+ } else {
713
+ so <- NULL
714
+ }
715
+
716
+ if (length(options $ residualsCovarying ) > 0 ) {
717
+ rc <- " # Residual Correlations"
718
+ for (rcv in options $ residualsCovarying ) {
719
+ if (length(rcv ) > 1 ) {
720
+ rc <- paste0(rc , " \n " , rcv [1 ], " ~~ " , rcv [2 ])
721
+ } else {
722
+ rc <- paste(rc , " " )
723
+ }
724
+ }
725
+ } else {
726
+ rc <- NULL
727
+ }
728
+
729
+
730
+ return (list (model = paste0(c(fo , so , rc ), collapse = " \n\n " ), simple_model = fo_simp ))
731
+ }
732
+
733
+
734
+ .cfaCalcSpecs <- function (dataset , options ) {
735
+ spec <- list ()
736
+ spec $ variables <- unlist(lapply(options $ factors , function (x ) x $ indicators ))
737
+ spec $ latents <- vapply(options $ factors , function (x ) x $ name , " names" )
738
+ if (length(options $ secondOrder ) > 0 ) {
739
+ spec $ soIndics <- .translateFactorNames(options $ secondOrder [[1 ]]$ indicators , options , back = TRUE )
740
+ }
741
+ if (options $ seType == " bootstrap" ) {
742
+ spec $ se <- " standard"
743
+ spec $ bootstrap <- TRUE
744
+ } else {
745
+ if (options $ seType == " robust" ) {
746
+ if (options [[" dataType" ]] == " varianceCovariance" ) {
747
+ .quitAnalysis(gettext(" Robust standard errors are not available for variance-covariance matrix input." ))
748
+ }
749
+ spec $ se <- " robust.sem"
750
+ } else {
751
+ spec $ se <- options $ seType
752
+ }
753
+ spec $ bootstrap <- FALSE
754
+ }
755
+ return (spec )
756
+ }
757
+
758
+ .translateFactorNames <- function (factor_name , options , back = FALSE ) {
759
+ # make dictionary
760
+ fac_names <- vapply(options $ factors , function (x ) x $ name , " name" )
761
+ fac_titles <- vapply(options $ factors , function (x ) x $ title , " title" )
762
+ sofac_names <- vapply(options $ secondOrder , function (x ) x $ name , " name" )
763
+ sofac_titles <- vapply(options $ secondOrder , function (x ) x $ title , " title" )
764
+ fnames <- c(fac_names , sofac_names )
765
+ ftitles <- c(fac_titles , sofac_titles )
766
+ # translate
767
+ if (back ) {
768
+ idx <- vapply(factor_name , function (n ) which(ftitles == n ), 0L , USE.NAMES = FALSE )
769
+ return (fnames [idx ])
770
+ } else {
771
+ idx <- vapply(factor_name , function (n ) which(fnames == n ), 0L , USE.NAMES = FALSE )
772
+ return (ftitles [idx ])
773
+ }
774
+ }
0 commit comments