Skip to content

Commit

Permalink
fix disattenuation bug and handle resampling options better (#176)
Browse files Browse the repository at this point in the history
* fix disattenuation bug

* fiy typo and handle resampling options better

* no qsTr for empty strings

Co-authored-by: Shun Wang <[email protected]>

---------

Co-authored-by: Shun Wang <[email protected]>
  • Loading branch information
juliuspfadt and shun2wang authored Sep 12, 2023
1 parent 25627c6 commit 9d9fece
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 22 deletions.
23 changes: 16 additions & 7 deletions R/plssem.R
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -213,33 +215,34 @@ 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",
"constructReestimation" = "construct_reestimate",
options[["handlingOfFlippedSigns"]]
),
.seed = if (options[["setSeed"]]) options[["seed"]]))


if (isTryError(fit)) {
err <- .extractErrorMessage(fit)

Expand Down Expand Up @@ -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",
Expand All @@ -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"]]

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -685,6 +693,7 @@ checkCSemModel <- function(model, availableVars) {
}
}
} else {

pe <- cSEM::infer(fit, .alpha = 1 - options[["ciLevel"]])
}

Expand Down
45 changes: 31 additions & 14 deletions inst/qml/PLSSEM.qml
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
}

Expand Down
3 changes: 2 additions & 1 deletion tests/testthat/test-plssem.R
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 9d9fece

Please sign in to comment.