diff --git a/R/plssem.R b/R/plssem.R index 6a3c05ea..8a0ee2c0 100644 --- a/R/plssem.R +++ b/R/plssem.R @@ -18,6 +18,7 @@ PLSSEMInternal <- function(jaspResults, dataset, options, ...) { jaspResults$addCitation("Rademaker ME, Schuberth F (2020). cSEM: Composite-Based Structural Equation Modeling. Package version: 0.4.0, https://m-e-rademaker.github.io/cSEM/.") + options <- .plsSemPrepOpts(options) # Read data, check if ready @@ -182,6 +183,7 @@ checkCSemModel <- function(model, availableVars) { cSemOpts <- .plsSemOptionsTocSemOptions(options, dataset) for (i in seq_along(results)) { + if (!is.null(results[[i]])) next # existing model is reused # create options @@ -213,26 +215,25 @@ checkCSemModel <- function(model, availableVars) { } # resample if robust/ bootstrap - if (options[["errorCalculationMethod"]] != "none") { + if (options[["errorCalculationMethod"]] == "robust") { - if(options[["errorCalculationMethod"]] == "bootstrap") { + if(options[["robustMethod"]] == "bootstrap") { startProgressbar(options[["bootstrapSamples"]], "Resampling") } else { startProgressbar(nrow(dataset), "Resampling") } - #argument .user_funs in cSEM::resamplecSEMResults only accepts a function with .object as input and a vector as output; c(0,0) does not have any other function + # argument .user_funs in cSEM::resamplecSEMResults only accepts a function with .object as input and a vector as output; c(0,0) does not have any other function tickFunction <- function(.object) { progressbarTick() return(c(0,0)) } - # resample fit <- try(cSEM::resamplecSEMResults(.object = fit, .R = options[["bootstrapSamples"]], .user_funs = tickFunction, - .resample_method = ifelse(options[["errorCalculationMethod"]] == "robust", "jackknife", options[["errorCalculationMethod"]]), + .resample_method = options[["robustMethod"]], .handle_inadmissibles = options[["handlingOfInadmissibles"]], .sign_change_option = switch(options[["handlingOfFlippedSigns"]], "individualReestimation" = "individual_reestimate", @@ -240,6 +241,8 @@ checkCSemModel <- function(model, availableVars) { options[["handlingOfFlippedSigns"]] ), .seed = if (options[["setSeed"]]) options[["seed"]])) + + if (isTryError(fit)) { err <- .extractErrorMessage(fit) @@ -285,7 +288,8 @@ checkCSemModel <- function(model, availableVars) { cSemOpts[[".PLS_ignore_structural_model"]] <- options[["structuralModelIgnored"]] cSemOpts[[".PLS_weight_scheme_inner"]] <- options[["innerWeightingScheme"]] - if (options[["compositeCorrelationDisattenuated"]]) + if (options[["compositeCorrelationDisattenuated"]]) { + cSemOpts[".disattenuate"] <- TRUE cSemOpts[".PLS_approach_cf"] <- switch(options[["correctionFactor"]], "squaredEuclidean" = "dist_squared_euclid", "weightedEuclidean" = "dist_euclid_weighted", @@ -295,6 +299,10 @@ checkCSemModel <- function(model, availableVars) { "harmonicMean" = "mean_harmonic", "geometricHarmonicMean" = "geo_of_harmonic") + } else { + cSemOpts[".disattenuate"] <- FALSE + } + if (options[["group"]] != "") cSemOpts[[".id"]] <- options[["group"]] @@ -547,7 +555,7 @@ checkCSemModel <- function(model, availableVars) { # Measurement model # create weights table - weightTab <- createJaspTable(title = gettext("Weigths")) + weightTab <- createJaspTable(title = gettext("Weights")) if (options[["group"]] != "") weightTab$addColumnInfo(name = "group", title = gettext("Group"), type = "string", combine = TRUE) @@ -685,6 +693,7 @@ checkCSemModel <- function(model, availableVars) { } } } else { + pe <- cSEM::infer(fit, .alpha = 1 - options[["ciLevel"]]) } diff --git a/inst/qml/PLSSEM.qml b/inst/qml/PLSSEM.qml index 6fad9609..37640d15 100644 --- a/inst/qml/PLSSEM.qml +++ b/inst/qml/PLSSEM.qml @@ -92,25 +92,42 @@ Form { title: qsTr("Error calculation method") name: "errorCalculationMethod" + id: errorCalcMethod RadioButton { value: "none"; label: qsTr("None"); checked: true } - RadioButton { value: "robust"; label: qsTr("Robust") } - RadioButton - { - value: "bootstrap"; label: qsTr("Bootstrap") - IntegerField + RadioButton + { + value: "robust"; + label: qsTr("Robust") + RadioButtonGroup + { + title: "" + name: "robustMethod" + RadioButton { + value: "bootstrap"; label: qsTr("Bootstrap"); checked: true + IntegerField + { + name: "bootstrapSamples" + label: qsTr("Samples") + fieldWidth: 60 + defaultValue: 200 + min: 1 + // enabled: errorCalcMethod.value == "robust" + } + } + RadioButton { value: "jackknife"; label: qsTr("Jackknife") } + } + + CIField { - name: "bootstrapSamples" - label: qsTr("Bootstrap samples") - fieldWidth: 60 - defaultValue: 200 - min: 1 + text: qsTr("Confidence intervals") + name: "ciLevel" + enabled: errorCalcMethod.value == "robust" } } + + } - CIField { - text: qsTr("Confidence intervals") - name: "ciLevel" - } + SetSeed {} } diff --git a/tests/testthat/test-plssem.R b/tests/testthat/test-plssem.R index bf24ef02..6e4f3ca4 100644 --- a/tests/testthat/test-plssem.R +++ b/tests/testthat/test-plssem.R @@ -286,7 +286,8 @@ test_that("Bootstrapping works", { options$correctionFactor <- "squaredEuclidean" options$setSeed <- TRUE options$seed <- 123 - options$errorCalculationMethod <- "bootstrap" + options$errorCalculationMethod <- "robust" + options$robustMethod <- "bootstrap" options$bootstrapSamples <- 200 options$handlingOfInadmissibles <- "ignore" options$handlingOfFlippedSigns <- "none"