diff --git a/R/PLSSEMWrapper.R b/R/PLSSEMWrapper.R index a6033f3..7de7669 100644 --- a/R/PLSSEMWrapper.R +++ b/R/PLSSEMWrapper.R @@ -24,7 +24,7 @@ PLSSEM <- function( benchmark = "none", bootstrapSamples = 200, ciLevel = 0.95, - compositeCorrelationDisattenuated = TRUE, + consistentPartialLeastSquares = TRUE, convergenceCriterion = "absoluteDifference", correctionFactor = "squaredEuclidean", correlationMatrix = "pearson", @@ -50,8 +50,7 @@ PLSSEM <- function( robustMethod = "bootstrap", seed = 1, setSeed = FALSE, - structuralModelIgnored = FALSE, - weightingApproach = "PLS-PM") { + structuralModelIgnored = FALSE) { defaultArgCalls <- formals(jaspSem::PLSSEM) defaultArgs <- lapply(defaultArgCalls, eval) @@ -62,7 +61,7 @@ PLSSEM <- function( options[["data"]] <- NULL options[["version"]] <- NULL - optionsWithFormula <- c("convergenceCriterion", "correctionFactor", "group", "handlingOfFlippedSigns", "innerWeightingScheme", "models", "weightingApproach") + optionsWithFormula <- c("convergenceCriterion", "correctionFactor", "group", "handlingOfFlippedSigns", "innerWeightingScheme", "models") for (name in optionsWithFormula) { if ((name %in% optionsWithFormula) && inherits(options[[name]], "formula")) options[[name]] = jaspBase::jaspFormula(options[[name]], data) } diff --git a/R/plssem.R b/R/plssem.R index f422baf..384783f 100644 --- a/R/plssem.R +++ b/R/plssem.R @@ -41,6 +41,8 @@ PLSSEMInternal <- function(jaspResults, dataset, options, ...) { .semMardiasCoefficient(modelContainer, dataset, options, ready) .plsSemReliabilities(modelContainer, dataset, options, ready) .plsSemCor(modelContainer, options, ready) + + .plsAddConstructScores(jaspResults, modelContainer, options, ready) } .plsSemPrepOpts <- function(options) { @@ -149,15 +151,17 @@ checkCSemModel <- function(model, availableVars) { .plsSemModelContainer <- function(jaspResults) { + if (!is.null(jaspResults[["modelContainer"]])) { modelContainer <- jaspResults[["modelContainer"]] } else { modelContainer <- createJaspContainer() - modelContainer$dependOn(c("weightingApproach", "correlationMatrix", "convergenceCriterion", - "estimateStructural", "group", "correctionFactor", "compositeCorrelationDisattenuated", - "structuralModelIgnored", "innerWeightingScheme", "errorCalculationMethod", "robustMethod", "bootstrapSamples", "ciLevel", - "setSeed", "seed", "handlingOfInadmissibles", "Data", "handlingOfFlippedSigns", "endogenousIndicatorPrediction", - "kFolds", "repetitions", "benchmark", "predictedScore")) + modelContainer$dependOn(c("syntax", "convergenceCriterion", + "estimateStructural", "group", "consistentPartialLeastSquares", + "structuralModelIgnored", "innerWeightingScheme", "errorCalculationMethod", + "robustMethod", "bootstrapSamples", "ciLevel", + "setSeed", "seed", "handlingOfInadmissibles", "endogenousIndicatorPrediction", + "kFolds", "repetitions", "benchmark", "predictedScore", "models")) jaspResults[["modelContainer"]] <- modelContainer } @@ -233,16 +237,12 @@ checkCSemModel <- function(model, availableVars) { } # resample fit <- try(cSEM::resamplecSEMResults(.object = fit, - .R = options[["bootstrapSamples"]], - .user_funs = tickFunction, - .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"]])) + .R = options[["bootstrapSamples"]], + .user_funs = tickFunction, + .resample_method = options[["robustMethod"]], + .handle_inadmissibles = options[["handlingOfInadmissibles"]], + .sign_change_option = "none", + .seed = if (options[["setSeed"]]) options[["seed"]])) if (isTryError(fit)) { @@ -278,8 +278,8 @@ checkCSemModel <- function(model, availableVars) { cSemOpts <- list() # model features - cSemOpts[[".approach_weights"]] <- options[["weightingApproach"]] - cSemOpts[[".approach_cor_robust"]] <- if (options[["correlationMatrix"]] == "pearson") "none" else options[["correlationMatrix"]] + cSemOpts[[".approach_weights"]] <- "PLS-PM" + cSemOpts[[".approach_cor_robust"]] <- "none" cSemOpts[[".approach_nl"]] <- options[["approachNonLinear"]] cSemOpts[[".conv_criterion"]] <- switch(options[["convergenceCriterion"]], "absoluteDifference" = "diff_absolute", @@ -290,16 +290,9 @@ checkCSemModel <- function(model, availableVars) { cSemOpts[[".PLS_ignore_structural_model"]] <- options[["structuralModelIgnored"]] cSemOpts[[".PLS_weight_scheme_inner"]] <- options[["innerWeightingScheme"]] - if (options[["compositeCorrelationDisattenuated"]]) { + if (options[["consistentPartialLeastSquares"]]) { cSemOpts[".disattenuate"] <- TRUE - cSemOpts[".PLS_approach_cf"] <- switch(options[["correctionFactor"]], - "squaredEuclidean" = "dist_squared_euclid", - "weightedEuclidean" = "dist_euclid_weighted", - "fisherTransformed" = "fisher_transformed", - "arithmeticMean" = "mean_arithmetic", - "geometricMean" = "mean_geometric", - "harmonicMean" = "mean_harmonic", - "geometricHarmonicMean" = "geo_of_harmonic") + cSemOpts[".PLS_approach_cf"] <- "dist_squared_euclid" } else { cSemOpts[".disattenuate"] <- FALSE @@ -1059,19 +1052,19 @@ checkCSemModel <- function(model, availableVars) { predictcont <- createJaspContainer(name, initCollapsed = TRUE) } - #Error messages + # Error messages if (options[["benchmark"]] != "none" && options[["benchmark"]] != "all") { benchmarks <- options[["benchmark"]] } else if (options[["benchmark"]] == "all") { benchmarks <- c("lm", "PLS-PM", "GSCA", "PCA", "MAXVAR") - benchmarks <- benchmarks[benchmarks != options[["weightingApproach"]]] + benchmarks <- benchmarks[benchmarks != "PLS-PM"] } else { benchmarks <- NULL } - if (options[["benchmark"]] != "none" && options[["benchmark"]] != "all" && benchmarks == options[["weightingApproach"]]) { + if (options[["benchmark"]] != "none" && options[["benchmark"]] != "all" && benchmarks == "PLS-PM") { errormsg <- gettextf("The target model uses the same weighting approach as the benchmark model, please choose another benchmark.") modelContainer$setError(errormsg) modelContainer$dependOn("benchmark") @@ -1961,6 +1954,72 @@ checkCSemModel <- function(model, availableVars) { return() } + +.plsAddConstructScores <- function(jaspResults, modelContainer, options, ready) { + + if (!ready || + !is.null(jaspResults[["addedScoresContainer"]]) || + modelContainer$getError() || + !options[["addConstructScores"]]) + { + return() + } + + container <- createJaspContainer() + container$dependOn(optionsFromObject = modelContainer, options = "addConstructScores") + jaspResults[["addedScoresContainer"]] <- container + + models <- modelContainer[["models"]][["object"]] + results <- modelContainer[["results"]][["object"]] + + modelNames <- sapply(models, function(x) x[["name"]]) + modelNames <- gsub(" ", "_", modelNames) + allNamesR <- c() + # loop over the models + for (i in seq_len(length(results))) { + scores <- cSEM::getConstructScores(results[[i]])$Construct_scores + + # then loop over the scores + scoreNames <- colnames(scores) + for (ii in seq_len(ncol(scores))) { + + colNameR <- paste0(modelNames[i], "_", scoreNames[ii]) + + if (jaspBase:::columnExists(colNameR) && !jaspBase:::columnIsMine(colNameR)) { + .quitAnalysis(gettextf("Column '%s' name already exists in the dataset", colNameR)) + } + + container[[colNameR]] <- jaspBase::createJaspColumn(colNameR) + container[[colNameR]]$setScale(scores[, ii]) + + # save the names to keep track of all names + allNamesR <- c(allNamesR, colNameR) + } + } + + jaspResults[["addedScoresContainer"]] <- container + + # check if there are previous colNames that are not needed anymore and delete the cols + oldNames <- jaspResults[["createdColumnNames"]][["object"]] + newNames <- allNamesR + if (!is.null(oldNames)) { + noMatch <- which(!(oldNames %in% newNames)) + if (length(noMatch) > 0) { + for (iii in 1:length(noMatch)) { + jaspBase:::columnDelete(oldNames[noMatch[iii]]) + } + } + } + + # save the created col names + jaspResults[["createdColumnNames"]] <- createJaspState(allNamesR) + + + return() + +} + + .plsSEMVIFhelper <- function(fit){ # Make VIFs into a matrix # Restructure the VIFs into a table. @@ -1969,10 +2028,10 @@ checkCSemModel <- function(model, availableVars) { idx <- which(VIFspath$VIF!=0,arr.ind = T) if(nrow(idx)!=0){ - VIFDf <- data.frame(Relation=paste(rownames(VIFspath$VIF)[idx[,'row']],'~',colnames(VIFspath$VIF)[idx[,'col']]), - vif=VIFspath$VIF[cbind(rownames(VIFspath$VIF)[idx[,'row']],colnames(VIFspath$VIF)[idx[,'col']])]) + VIFDf <- data.frame(Relation=paste(rownames(VIFspath$VIF)[idx[,'row']],'~',colnames(VIFspath$VIF)[idx[,'col']]), + vif=VIFspath$VIF[cbind(rownames(VIFspath$VIF)[idx[,'row']],colnames(VIFspath$VIF)[idx[,'col']])]) - VIFvector <-setNames(VIFDf$vif, VIFDf$Relation) + VIFvector <-setNames(VIFDf$vif, VIFDf$Relation) } else{ VIFvector <- NULL } @@ -1988,12 +2047,12 @@ checkCSemModel <- function(model, availableVars) { if(!is.null(VIFsweights)&sum(VIFsweights)!=0){ - idx <- which(VIFsweights!=0,arr.ind = T) + idx <- which(VIFsweights!=0,arr.ind = T) - VIFBDf <- data.frame(Relation=paste(rownames(VIFsweights)[idx[,'row']],'<~',colnames(VIFsweights)[idx[,'col']]), - vif=VIFsweights[cbind(rownames(VIFsweights)[idx[,'row']],colnames(VIFsweights)[idx[,'col']])]) + VIFBDf <- data.frame(Relation=paste(rownames(VIFsweights)[idx[,'row']],'<~',colnames(VIFsweights)[idx[,'col']]), + vif=VIFsweights[cbind(rownames(VIFsweights)[idx[,'row']],colnames(VIFsweights)[idx[,'col']])]) - VIFBvector <-setNames(VIFBDf$vif, VIFBDf$Relation) + VIFBvector <-setNames(VIFBDf$vif, VIFBDf$Relation) } else{ VIFBvector <- NULL @@ -2001,4 +2060,3 @@ checkCSemModel <- function(model, availableVars) { return(VIFBvector) } - diff --git a/inst/help/PLSSEM.md b/inst/help/PLSSEM.md index a1995d0..500f0e7 100644 --- a/inst/help/PLSSEM.md +++ b/inst/help/PLSSEM.md @@ -1,8 +1,101 @@ -Partial Least Squares structural equation modeling -============ +# Partial Least Squares Structural Equation Modeling (PLS-SEM) in JASP -Perform partial least squares structural equation modeling (PLS-SEM) using `cSEM` (Rademaker & Schuberth, 2020). Go to https://cran.r-project.org/web/packages/cSEM/cSEM.pdf for package information and examples. See also Henseler (2021) for more tutorials using cSEM. +This document explains how to perform Partial Least Squares Structural Equation Modeling (PLS-SEM) in JASP using the various options provided in the user interface. +## 1. Model Setup +--- +In the **Model** section, you can specify the structural model by selecting the appropriate grouping variable and setting the syntax for the model. + +- **Grouping Variable**: You can select the grouping variable for multi-group analysis. The grouping variable is optional and can be left empty if not required. + +## 2. Estimation Options +--- +In the **Estimation** section, the following options are available: + +- **Consistent Partial Least Squares**: Enables the option to use consistent PLS-SEM, which provides consistency in estimations for reflective constructs. + +- **Inner Weighting Scheme**: Choose from the following options to calculate inner weights: + - Path + - Centroid + - Factorial + +- **Bias-Corrected Bootstrap**: Activate this option for bias-corrected bootstrapping, which refines the confidence intervals for the estimates. + +- **Bootstrap Resampling**: You can adjust the number of bootstrap samples for more precise interval estimations. The default value is set to 5,000. + +- **Missing Data Handling**: Options for managing missing data, including pairwise or listwise deletion, are available. + +## 3. Output Options +--- +The **Output** section allows you to customize the types of output you want to generate: + +- **Path Coefficients**: Display the estimated path coefficients. +- **Weights and Loadings**: Shows both the indicator weights and loadings, offering insights into how well the indicators measure their corresponding latent variables. +- **Goodness-of-Fit Measures**: Presents different goodness-of-fit measures like SRMR or NFI. +- **Reliability Measures**: Enables output of reliability measures such as Cronbach's alpha or composite reliability for the constructs. + +Additional correlation measures include: +- **Observed and Implied Indicator Correlations** +- **Observed and Implied Construct Correlations** + +You can also add **construct scores** to the dataset for further analysis. + +## 4. Prediction +--- +The **Prediction** section includes options for predicting endogenous indicator scores using cross-validation: + +- **Cross-Validation k-Folds**: Choose the number of k-folds for cross-validation, with a default value of 10. +- **Repetitions**: Specify the number of repetitions, with a default value of 10. + +You can also select a benchmark to compare predictions against: +- **None** +- **Linear Model (LM)** +- **PLS-PM** +- **GSCA** +- **PCA** +- **MAXVAR** +- **All** + +## 5. Output and Interpretation +--- + +### 5.1 Path Coefficients +The **path coefficients** represent the strength and direction of the relationships between the constructs. These coefficients are similar to regression weights and help in understanding the impact of one latent variable on another. You can also view the **t-values** and **p-values** to assess the significance of these paths. + +### 5.2 Indicator Loadings and Weights +This section shows the **loadings** of each indicator on its associated construct, which indicates how well each observed variable measures the latent construct. Loadings close to 1 indicate a strong relationship between the indicator and its construct. **Weights** are presented in the case of formative constructs, showing the relative importance of each indicator. + +### 5.3 Model Fit Indices +JASP provides several goodness-of-fit measures to evaluate how well the model fits the data: +- **SRMR (Standardized Root Mean Square Residual)**: A measure of model fit, where lower values (generally below 0.08) indicate a better fit. +- **NFI (Normed Fit Index)**: Ranges from 0 to 1, with higher values representing a better fit. + +### 5.4 Reliability Measures +Reliability measures assess the internal consistency of the latent constructs: +- **Cronbach’s Alpha**: A commonly used reliability coefficient; values above 0.7 generally indicate acceptable reliability. +- **Composite Reliability (CR)**: A measure of internal consistency similar to Cronbach’s Alpha but considers different factor loadings. +- **Average Variance Extracted (AVE)**: Represents the amount of variance captured by a construct in relation to the variance due to measurement error. AVE values above 0.5 are generally considered acceptable. + +### 5.5 R-Squared (R²) +The R-squared value represents the proportion of variance in the endogenous constructs explained by the model. Higher values indicate better explanatory power. An R-squared value close to 0.7 is considered substantial, while values around 0.3 are moderate. + +### 5.6 Cross-Validated Prediction +If the cross-validation option is selected, the results will include predicted scores for the endogenous indicators. The k-fold cross-validation helps in assessing the predictive power of the model. You can compare the model’s predictions with benchmarks like linear regression or PLS-PM. + +### 5.7 Construct Scores +You can include the estimated construct scores in the dataset for further analysis. These scores represent the latent variables in the model and can be used for additional analyses outside of SEM. + +### 5.8 Bootstrapping Results +If bootstrapping is used, the output includes **bootstrap confidence intervals** for the path coefficients, loadings, and weights. These intervals help in understanding the stability of the parameter estimates. + +### 5.9 Prediction Benchmarks +If benchmarks are selected, you can compare the PLS-SEM model with: +- **Linear Model** (LM) +- **Principal Component Analysis** (PCA) +- **Generalized Structured Component Analysis** (GSCA) +- **MAXVAR** (Maximum Variance method) + +These benchmarks help in evaluating how well your PLS-SEM model predicts the endogenous variables compared to simpler methods. References ------- diff --git a/inst/qml/PLSSEM.qml b/inst/qml/PLSSEM.qml index 4f92eda..003b180 100644 --- a/inst/qml/PLSSEM.qml +++ b/inst/qml/PLSSEM.qml @@ -45,31 +45,6 @@ Form Group { - CheckBox - { - enabled: approachWeigths.currentValue == "PLS-PM" && approachInner.currentValue != "path" - name: "structuralModelIgnored" - label: qsTr("Ignore structural model") - } - - CheckBox - { - name: "compositeCorrelationDisattenuated"; label: qsTr("Disattenuate composite correlations"); checked: true - DropDown - { - name: "correctionFactor" - label: qsTr("Approach correction factors") - values: [ - { value: "squaredEuclidean", label: qsTr("Squared Euclidean distance") }, - { value: "weightedEuclidean", label: qsTr("Weighted Euclidean distance") }, - { value: "fisherTransformed", label: qsTr("Fisher transformed") }, - { value: "arithmeticMean", label: qsTr("Arithmetic mean") }, - { value: "geometricMean", label: qsTr("Geometric mean") }, - { value: "harmonicMean", label: qsTr("Harmonic mean") }, - { value: "geometricHarmonicMean", label: qsTr("Geometric-harmonic mean") } - ] - } - } DropDown { @@ -86,11 +61,57 @@ Form { title: qsTr("Estimation") + Group + { + CheckBox + { + name: "consistentPartialLeastSquares"; label: qsTr("Consistent partial least squares"); checked: true + } + DropDown + { + name: "innerWeightingScheme" + label: qsTr("Inner weighting scheme") + id: approachInner + values: [ + { value: "path", label: qsTr("Path") }, + { value: "centroid", label: qsTr("Centroid") }, + { value: "factorial", label: qsTr("Factorial") } + ] + } + + CheckBox + { + enabled: approachInner.currentValue != "path" + name: "structuralModelIgnored" + label: qsTr("Ignore structural model") + } + + DropDown + { + name: "convergenceCriterion" + label: qsTr("Convergence criterion") + values: [ + { value: "absoluteDifference", label: qsTr("Absolute difference") }, + { value: "squaredDifference", label: qsTr("Squared difference") }, + { value: "relativeDifference", label: qsTr("Relative difference") } + ] + } + + DoubleField + { + name: "tolerance" + label: qsTr("Tolerance") + fieldWidth: 60 + defaultValue: 1e-5 + min: 0 + } + } + Group { + title: qsTr("Error calculation method") RadioButtonGroup { - title: qsTr("Error calculation method") name: "errorCalculationMethod" id: errorCalcMethod RadioButton { value: "none"; label: qsTr("None"); checked: true } @@ -124,89 +145,20 @@ Form enabled: errorCalcMethod.value == "robust" } } - - - } - - SetSeed {} - } - - Group - { - DropDown - { - name: "weightingApproach" - label: qsTr("Weighting approach") - id: approachWeigths - values: - [ - { label: qsTr("PLS-PM"), value: "PLS-PM" }, - { label: qsTr("GSCA"), value: "GSCA" }, - { label: qsTr("SUMCORR"), value: "SUMCORR" }, - { label: qsTr("MAXVAR"), value: "MAXVAR" }, - { label: qsTr("SSQCORR"), value: "SSQCORR" }, - { label: qsTr("MINVAR"), value: "MINVAR" }, - { label: qsTr("GENVAR"), value: "GENVAR" }, - { label: qsTr("PCA"), value: "PCA" }, - { label: qsTr("Unit"), value: "unit" }, - { label: qsTr("Bartlett"), value: "bartlett" }, - { label: qsTr("Regression"), value: "regression" } - ] - } - - DropDown - { - enabled: approachWeigths.currentValue == "PLS-PM" - name: "innerWeightingScheme" - label: qsTr("Inner weighting scheme") - id: approachInner - values: [ - { value: "path", label: qsTr("Path") }, - { value: "centroid", label: qsTr("Centroid") }, - { value: "factorial", label: qsTr("Factorial") } - ] } - - DropDown - { - name: "convergenceCriterion" - label: qsTr("Convergence criterion") - values: [ - { value: "absoluteDifference", label: qsTr("Absolute difference") }, - { value: "squaredDifference", label: qsTr("Squared difference") }, - { value: "relativeDifference", label: qsTr("Relative difference") } - ] - } - - RadioButtonGroup - { - title: qsTr("Correlation matrix") - name: "correlationMatrix" - RadioButton { value: "pearson" ; label: qsTr("Pearson"); checked: true } - RadioButton { value: "spearman" ; label: qsTr("Spearman") } - } - RadioButtonGroup { + visible: errorCalcMethod.value != "none" title: qsTr("Handling of inadmissibles") name: "handlingOfInadmissibles" RadioButton { value: "replace"; label: qsTr("Replace") ; checked: true } RadioButton { value: "ignore"; label: qsTr("Ignore") } RadioButton { value: "drop"; label: qsTr("Drop") } } - - DropDown - { - name: "handlingOfFlippedSigns" - label: qsTr("Handling of flipped signs") - values: [ - { value: "none", label: qsTr("None") }, - { value: "individual", label: qsTr("Individual") }, - { value: "individualReestimation", label: qsTr("Individual re-estimation") }, - { value: "constructReestimation", label: qsTr("Construct re-estimation") } - ] - } + SetSeed {} } + + } Section @@ -215,7 +167,7 @@ Form Group { - CheckBox { name: "rSquared"; label: qsTr("R-squared") } + CheckBox { name: "rSquared"; label: qsTr("R-squared") } CheckBox { name: "additionalFitMeasures"; label: qsTr("Additional fit measures") } CheckBox { name: "mardiasCoefficient"; label: qsTr("Mardia's coefficient") } CheckBox { name: "reliabilityMeasures"; label: qsTr("Reliability measures") } @@ -223,11 +175,17 @@ Form Group { - CheckBox { name: "observedIndicatorCorrelation"; label: qsTr("Observed indicator correlations") } + CheckBox { name: "observedIndicatorCorrelation"; label: qsTr("Observed indicator correlations") } CheckBox { name: "impliedIndicatorCorrelation"; label: qsTr("Implied indicator correlations") } CheckBox { name: "observedConstructCorrelation"; label: qsTr("Observed construct correlations") } CheckBox { name: "impliedConstructCorrelation"; label: qsTr("Implied construct correlations") } } + + CheckBox + { + name: "addConstructScores" + text: qsTr("Add construct scores to data") + } } Section diff --git a/renv.lock b/renv.lock index 0b927b3..0b13a54 100644 --- a/renv.lock +++ b/renv.lock @@ -100,9 +100,9 @@ }, "OpenMx": { "Package": "OpenMx", - "Version": "2.21.11", + "Version": "2.21.12", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "BH", "MASS", @@ -118,7 +118,7 @@ "parallel", "rpf" ], - "Hash": "6362da44e762ec951a34fcb6bce60cac" + "Hash": "885d2c35062c7e167061e73eaf8fbe87" }, "R6": { "Package": "R6", @@ -166,9 +166,9 @@ }, "RcppArmadillo": { "Package": "RcppArmadillo", - "Version": "14.0.0-1", + "Version": "14.0.2-1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "Rcpp", @@ -176,11 +176,11 @@ "stats", "utils" ], - "Hash": "a711769be34214addf7805278b72d56b" + "Hash": "edff747eebfb8f2e18eed194e000caa1" }, "RcppEigen": { "Package": "RcppEigen", - "Version": "0.3.4.0.0", + "Version": "0.3.4.0.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -189,21 +189,21 @@ "stats", "utils" ], - "Hash": "df49e3306f232ec28f1604e36a202847" + "Hash": "4ac8e423216b8b70cb9653d1b3f71eb9" }, "RcppParallel": { "Package": "RcppParallel", - "Version": "5.1.8", + "Version": "5.1.9", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "21c1466a17de6b1f5f4bc0569868775e" + "Hash": "f38a72a419b91faac0ce5d9eee04c120" }, "Rdpack": { "Package": "Rdpack", - "Version": "2.6", + "Version": "2.6.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -213,7 +213,7 @@ "tools", "utils" ], - "Hash": "3e1384ada5d3948b392e98b11434d972" + "Hash": "24a964d2cf75ad25d7b843856c8d4c93" }, "SEMsens": { "Package": "SEMsens", @@ -269,7 +269,7 @@ }, "abind": { "Package": "abind", - "Version": "1.4-5", + "Version": "1.4-8", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -277,18 +277,18 @@ "methods", "utils" ], - "Hash": "4f57884290cc75ab22f4af9e9d4ca862" + "Hash": "2288423bb0f20a457800d7fc47f6aa54" }, "admisc": { "Package": "admisc", - "Version": "0.35", + "Version": "0.36", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "methods" ], - "Hash": "1b042d902955174bbc9c4bea64c595d4" + "Hash": "e19202c52a440288aed7cfdd1907224a" }, "alabama": { "Package": "alabama", @@ -303,7 +303,7 @@ }, "archive": { "Package": "archive", - "Version": "1.1.8", + "Version": "1.1.9", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -313,7 +313,7 @@ "rlang", "tibble" ], - "Hash": "3b80f17eac5780126e09aa05d369a625" + "Hash": "d26b62e131d4a8b65aba4e9554a4bf74" }, "arm": { "Package": "arm", @@ -338,13 +338,13 @@ }, "askpass": { "Package": "askpass", - "Version": "1.2.0", + "Version": "1.2.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "sys" ], - "Hash": "cad6cf7f1d5f6e906700b9d3e718c796" + "Hash": "c39f4155b3ceb1a9a2799d700fbd4b6a" }, "backports": { "Package": "backports", @@ -368,7 +368,7 @@ }, "boot": { "Package": "boot", - "Version": "1.3-30", + "Version": "1.3-31", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -376,7 +376,7 @@ "graphics", "stats" ], - "Hash": "96abeed416a286d4a0f52e550b612343" + "Hash": "de2a4646c18661d6a0a08ec67f40b7ed" }, "brio": { "Package": "brio", @@ -390,7 +390,7 @@ }, "bslib": { "Package": "bslib", - "Version": "0.7.0", + "Version": "0.8.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -408,7 +408,7 @@ "rlang", "sass" ], - "Hash": "8644cc53f43828f19133548195d7e59e" + "Hash": "b299c6741ca9746fb227debcb0f9fb6c" }, "cSEM": { "Package": "cSEM", @@ -479,7 +479,7 @@ }, "checkmate": { "Package": "checkmate", - "Version": "2.3.1", + "Version": "2.3.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -487,7 +487,7 @@ "backports", "utils" ], - "Hash": "c01cab1cb0f9125211a6fc99d540e315" + "Hash": "0e14e01ce07e7c88fd25de6d4260d26b" }, "cli": { "Package": "cli", @@ -537,7 +537,7 @@ }, "colorspace": { "Package": "colorspace", - "Version": "2.1-0", + "Version": "2.1-1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -547,7 +547,7 @@ "methods", "stats" ], - "Hash": "f20c47fd52fae58b4e377c37bb8c335b" + "Hash": "d954cb1c57e8d8b756165d7ba18aa55a" }, "combinat": { "Package": "combinat", @@ -556,13 +556,6 @@ "Repository": "RSPM", "Hash": "f0acb9dcb71a9cd9d5ae233c5035b1c5" }, - "commonmark": { - "Package": "commonmark", - "Version": "1.9.1", - "Source": "Repository", - "Repository": "CRAN", - "Hash": "5d8225445acb167abf7797de48b2ee3c" - }, "corpcor": { "Package": "corpcor", "Version": "1.6.10", @@ -576,13 +569,13 @@ }, "cpp11": { "Package": "cpp11", - "Version": "0.4.7", + "Version": "0.5.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "5a295d7d963cc5035284dcdbaf334f4e" + "Hash": "91570bba75d0c9d3f1040c835cee8fba" }, "crayon": { "Package": "crayon", @@ -596,21 +589,6 @@ ], "Hash": "859d96e65ef198fd43e82b9628d593ef" }, - "crul": { - "Package": "crul", - "Version": "1.5.0", - "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R6", - "curl", - "httpcode", - "jsonlite", - "mime", - "urltools" - ], - "Hash": "22e70c5046981d39b7bf7af74433e396" - }, "cubature": { "Package": "cubature", "Version": "2.1.1", @@ -623,24 +601,24 @@ }, "curl": { "Package": "curl", - "Version": "5.2.1", + "Version": "5.2.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "411ca2c03b1ce5f548345d2fc2685f7a" + "Hash": "d91263322a58af798f6cf3b13fd56dde" }, "data.table": { "Package": "data.table", - "Version": "1.15.4", + "Version": "1.16.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "methods" ], - "Hash": "8ee9ac56ef633d0c7cab8b2ca87d683e" + "Hash": "fb24e05d4a91d8b1c7ff8e284bde834a" }, "desc": { "Package": "desc", @@ -710,21 +688,20 @@ "Source": "Repository", "Repository": "CRAN", "Requirements": [ - "R", - "methods" + "R" ], - "Hash": "a1066cbc05caee9a4bf6d90f194ff4da" + "Hash": "6b567375113ceb7d9f800de4dd42218e" }, "expm": { "Package": "expm", - "Version": "0.999-9", + "Version": "1.0-0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "Matrix", "methods" ], - "Hash": "a9cfdee9645dd6b09ba8d4b9a9befa77" + "Hash": "a44b2810f36c1cda5d52eee6ec96cafa" }, "fansi": { "Package": "fansi", @@ -754,7 +731,7 @@ }, "fdrtool": { "Package": "fdrtool", - "Version": "1.2.17", + "Version": "1.2.18", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -763,7 +740,7 @@ "graphics", "stats" ], - "Hash": "9feeb4e7a484e663a52d7de89135591a" + "Hash": "d2a06fbed1234e31c6a872aebbf30057" }, "fontBitstreamVera": { "Package": "fontBitstreamVera", @@ -851,7 +828,7 @@ }, "future": { "Package": "future", - "Version": "1.33.2", + "Version": "1.34.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -862,7 +839,7 @@ "parallelly", "utils" ], - "Hash": "fd7b1d69d16d0d114e4fa82db68f184c" + "Hash": "475771e3edb711591476be387c9a8c2e" }, "future.apply": { "Package": "future.apply", @@ -880,20 +857,18 @@ }, "gdtools": { "Package": "gdtools", - "Version": "0.3.7", + "Version": "0.4.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "Rcpp", - "curl", "fontquiver", - "gfonts", "htmltools", "systemfonts", "tools" ], - "Hash": "b53e23731a5946448ad888efca14d2df" + "Hash": "e8e09897fee8d96f6bb02bf841177d20" }, "generics": { "Package": "generics", @@ -906,23 +881,6 @@ ], "Hash": "15e9634c0fcd294799e9b2e929ed1b86" }, - "gfonts": { - "Package": "gfonts", - "Version": "0.2.0", - "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "R", - "crayon", - "crul", - "glue", - "htmltools", - "jsonlite", - "shiny", - "utils" - ], - "Hash": "a535d76cf92645364997a8751396d63b" - }, "ggplot2": { "Package": "ggplot2", "Version": "3.5.1", @@ -968,14 +926,14 @@ }, "glue": { "Package": "glue", - "Version": "1.7.0", + "Version": "1.8.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "methods" ], - "Hash": "e0b3a53876554bd45879e596cdb10a52" + "Hash": "5899f1eaa825580172bb56c08266f37c" }, "gridExtra": { "Package": "gridExtra", @@ -1090,28 +1048,6 @@ ], "Hash": "04291cc45198225444a397606810ac37" }, - "httpcode": { - "Package": "httpcode", - "Version": "0.3.0", - "Source": "Repository", - "Repository": "CRAN", - "Hash": "13641a1c6d2cc98801b76764078e17ea" - }, - "httpuv": { - "Package": "httpuv", - "Version": "1.6.15", - "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "R", - "R6", - "Rcpp", - "later", - "promises", - "utils" - ], - "Hash": "d55aa087c47a63ead0f6fc10f8fa1ee0" - }, "httr": { "Package": "httr", "Version": "1.4.7", @@ -1166,12 +1102,10 @@ "Version": "0.19.0", "Source": "GitHub", "RemoteType": "github", - "RemoteHost": "api.github.com", "RemoteUsername": "jasp-stats", "RemoteRepo": "jaspBase", - "RemoteRef": "HEAD", - "RemoteSha": "7de02c442478e028fe2036e3b906059bf504c13e", - "Remotes": "jasp-stats/jaspGraphs", + "RemoteSha": "e57cdd1d3bca19ab4d6859ef74862f5b9896cec9", + "RemoteHost": "api.github.com", "Requirements": [ "R6", "Rcpp", @@ -1200,18 +1134,17 @@ "systemfonts", "withr" ], - "Hash": "03e59b2f848a0798aaf630285f46b200" + "Hash": "9481bbd3b8c125a1400e0130a227e01e" }, "jaspGraphs": { "Package": "jaspGraphs", "Version": "0.19.0", "Source": "GitHub", "RemoteType": "github", - "RemoteHost": "api.github.com", "RemoteUsername": "jasp-stats", "RemoteRepo": "jaspGraphs", - "RemoteRef": "HEAD", - "RemoteSha": "e439c080e3841e0719c00ce35c376b34c833b546", + "RemoteSha": "b2e1799265a0741b49a1ca356f96448091dd8db0", + "RemoteHost": "api.github.com", "Requirements": [ "R6", "RColorBrewer", @@ -1224,18 +1157,17 @@ "scales", "viridisLite" ], - "Hash": "5b5c345a74cb82c9036fb80f9a57f3c0" + "Hash": "53801a573d11d2ce3971f404cb469769" }, "jaspTools": { "Package": "jaspTools", "Version": "0.19.0", "Source": "GitHub", "RemoteType": "github", - "RemoteHost": "api.github.com", - "RemoteRepo": "jaspTools", "RemoteUsername": "jasp-stats", - "RemoteRef": "HEAD", - "RemoteSha": "6caf5dd91f1469f4357cd6dc78b3600711e871ea", + "RemoteRepo": "jaspTools", + "RemoteSha": "877076408a4d3ff432348a8c2672f235a91610d8", + "RemoteHost": "api.github.com", "Requirements": [ "archive", "data.table", @@ -1250,7 +1182,7 @@ "testthat", "vdiffr" ], - "Hash": "94acf486de071058fbaa9c562ab91d76" + "Hash": "ffa480855ade26367eb5f097b75a20ae" }, "jpeg": { "Package": "jpeg", @@ -1274,13 +1206,13 @@ }, "jsonlite": { "Package": "jsonlite", - "Version": "1.8.8", + "Version": "1.8.9", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "methods" ], - "Hash": "e1b9c55281c5adc4dd113652d9e26768" + "Hash": "4e993b65c2c3ffbffce7bb3e2c6f832b" }, "knitr": { "Package": "knitr", @@ -1327,17 +1259,6 @@ ], "Hash": "b64ec208ac5bc1852b285f665d6368b3" }, - "later": { - "Package": "later", - "Version": "1.3.2", - "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "Rcpp", - "rlang" - ], - "Hash": "a3e051d405326b8b0012377434c62b37" - }, "lattice": { "Package": "lattice", "Version": "0.22-6", @@ -1355,7 +1276,7 @@ }, "lavaan": { "Package": "lavaan", - "Version": "0.6-18", + "Version": "0.6-19", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1371,7 +1292,7 @@ "stats4", "utils" ], - "Hash": "8cc22350004769221cf2468d41c7e389" + "Hash": "78573997f3acd282f34c626ffb6a906d" }, "lifecycle": { "Package": "lifecycle", @@ -1444,13 +1365,13 @@ }, "matrixStats": { "Package": "matrixStats", - "Version": "1.3.0", + "Version": "1.4.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "4b3ea27a19d669c0405b38134d89a9d1" + "Hash": "8885ffb1f46e820dede6b2ca9442abca" }, "matrixcalc": { "Package": "matrixcalc", @@ -1516,13 +1437,13 @@ }, "minqa": { "Package": "minqa", - "Version": "1.2.7", + "Version": "1.2.8", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "Rcpp" ], - "Hash": "aba060ef3c097b26a4d304ea39d87f32" + "Hash": "785ef8e22389d4a7634c6c944f2dc07d" }, "mnormt": { "Package": "mnormt", @@ -1568,14 +1489,14 @@ }, "mvtnorm": { "Package": "mvtnorm", - "Version": "1.2-5", + "Version": "1.3-1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "stats" ], - "Hash": "4d1891e59ac7a12b4e7e8a69349125f1" + "Hash": "77c61d51ce0f36e3c1a76e6b295aab31" }, "nleqslv": { "Package": "nleqslv", @@ -1586,9 +1507,9 @@ }, "nlme": { "Package": "nlme", - "Version": "3.1-165", + "Version": "3.1-166", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "graphics", @@ -1596,7 +1517,7 @@ "stats", "utils" ], - "Hash": "2769a88be217841b1f33ed469675c3cc" + "Hash": "ccbb8846be320b627e6aa2b4616a2ded" }, "nloptr": { "Package": "nloptr", @@ -1648,19 +1569,19 @@ }, "openssl": { "Package": "openssl", - "Version": "2.2.1", + "Version": "2.2.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "askpass" ], - "Hash": "c62edf62de70cadf40553e10c739049d" + "Hash": "d413e0fef796c9401a4419485f709ca1" }, "openxlsx": { "Package": "openxlsx", - "Version": "4.2.6.1", + "Version": "4.2.7.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "Rcpp", @@ -1671,11 +1592,11 @@ "utils", "zip" ], - "Hash": "bd8fbd2904be3ce8fdf529a4f74a0c29" + "Hash": "14304e44a0f90fa2d0f905472333c561" }, "parallelly": { "Package": "parallelly", - "Version": "1.37.1", + "Version": "1.38.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1683,7 +1604,7 @@ "tools", "utils" ], - "Hash": "5410df8d22bd36e616f2a2343dbb328c" + "Hash": "6e8b139c1904f5e9e14c69db64453bbe" }, "pbapply": { "Package": "pbapply", @@ -1835,32 +1756,16 @@ ], "Hash": "ac50c4ffa8f6a46580dd4d7813add3c4" }, - "promises": { - "Package": "promises", - "Version": "1.3.0", - "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "R6", - "Rcpp", - "fastmap", - "later", - "magrittr", - "rlang", - "stats" - ], - "Hash": "434cd5388a3979e74be5c219bcd6e77d" - }, "ps": { "Package": "ps", - "Version": "1.7.7", + "Version": "1.8.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "utils" ], - "Hash": "878b467580097e9c383acbb16adab57a" + "Hash": "4b9c8485b0c7eecdf0a9ba5132a45576" }, "psych": { "Package": "psych", @@ -1949,14 +1854,14 @@ }, "ragg": { "Package": "ragg", - "Version": "1.3.2", + "Version": "1.3.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "systemfonts", "textshaping" ], - "Hash": "e3087db406e079a8a2fd87f413918ed3" + "Hash": "0595fe5e47357111f29ad19101c7d271" }, "rappdirs": { "Package": "rappdirs", @@ -1970,7 +1875,7 @@ }, "rbibutils": { "Package": "rbibutils", - "Version": "2.2.16", + "Version": "2.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1978,7 +1883,7 @@ "tools", "utils" ], - "Hash": "8c06968e0a5b0209c5f34239b1302336" + "Hash": "dfc034a172fd88fc66b1a703894c4185" }, "rematch2": { "Package": "rematch2", @@ -2006,13 +1911,10 @@ }, "renv": { "Package": "renv", - "Version": "1.0.7", - "Source": "Repository", + "Version": "1.0.10", + "OS_type": null, "Repository": "CRAN", - "Requirements": [ - "utils" - ], - "Hash": "397b7b2a265bc5a7a06852524dabae20" + "Source": "Repository" }, "reshape2": { "Package": "reshape2", @@ -2035,7 +1937,7 @@ "Requirements": [ "R" ], - "Hash": "ff387cabd34002e7e50d2becacb0be76" + "Hash": "7a04e9eff95857dbf557b4e5f0b3d1a8" }, "rlang": { "Package": "rlang", @@ -2050,7 +1952,7 @@ }, "rmarkdown": { "Package": "rmarkdown", - "Version": "2.27", + "Version": "2.28", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -2069,7 +1971,7 @@ "xfun", "yaml" ], - "Hash": "27f9502e1cdbfa195f94e03b0f517484" + "Hash": "062470668513dcda416927085ee9bdc7" }, "rockchalk": { "Package": "rockchalk", @@ -2135,7 +2037,7 @@ }, "rvg": { "Package": "rvg", - "Version": "0.3.3", + "Version": "0.3.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -2147,7 +2049,7 @@ "rlang", "xml2" ], - "Hash": "8f7a79f622774ff95d60b74e486d99ba" + "Hash": "84feb96f75452bfbb4b7858e36bea2c5" }, "sass": { "Package": "sass", @@ -2185,9 +2087,9 @@ }, "sem": { "Package": "sem", - "Version": "3.1-15", + "Version": "3.1-16", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "MASS", "R", @@ -2196,7 +2098,7 @@ "stats", "utils" ], - "Hash": "5805daf371dd32f5e5fb4debe0191fd7" + "Hash": "780e2fbf377bcd8365788eacaea36170" }, "semPlot": { "Package": "semPlot", @@ -2236,49 +2138,6 @@ ], "Hash": "9374d79226103541b8293009f81da90f" }, - "shiny": { - "Package": "shiny", - "Version": "1.8.1.1", - "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "R", - "R6", - "bslib", - "cachem", - "commonmark", - "crayon", - "fastmap", - "fontawesome", - "glue", - "grDevices", - "htmltools", - "httpuv", - "jsonlite", - "later", - "lifecycle", - "methods", - "mime", - "promises", - "rlang", - "sourcetools", - "tools", - "utils", - "withr", - "xtable" - ], - "Hash": "54b26646816af9960a4c64d8ceec75d6" - }, - "sourcetools": { - "Package": "sourcetools", - "Version": "0.1.7-1", - "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "R" - ], - "Hash": "5f5a7629f956619d519205ec475fe647" - }, "spacefillr": { "Package": "spacefillr", "Version": "0.3.3", @@ -2346,10 +2205,10 @@ }, "sys": { "Package": "sys", - "Version": "3.4.2", + "Version": "3.4.3", "Source": "Repository", "Repository": "CRAN", - "Hash": "3a1be13d68d47a8cd0bfd74739ca1555" + "Hash": "de342ebfebdbf40477d0758d05426646" }, "systemfonts": { "Package": "systemfonts", @@ -2465,36 +2324,13 @@ }, "tinytex": { "Package": "tinytex", - "Version": "0.52", - "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "xfun" - ], - "Hash": "cfbad971a71f0e27cec22e544a08bc3b" - }, - "triebeard": { - "Package": "triebeard", - "Version": "0.4.1", - "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "Rcpp" - ], - "Hash": "642507a148b0dd9b5620177e0a044413" - }, - "urltools": { - "Package": "urltools", - "Version": "1.7.3", + "Version": "0.53", "Source": "Repository", "Repository": "CRAN", "Requirements": [ - "R", - "Rcpp", - "methods", - "triebeard" + "xfun" ], - "Hash": "e86a704261a105f4703f653e05defa3e" + "Hash": "9db859e8aabbb474293dde3097839420" }, "utf8": { "Package": "utf8", @@ -2508,13 +2344,13 @@ }, "uuid": { "Package": "uuid", - "Version": "1.2-0", + "Version": "1.2-1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "303c19bfd970bece872f93a824e323d9" + "Hash": "34e965e62a41fcafb1ca60e9b142085b" }, "vctrs": { "Package": "vctrs", @@ -2574,21 +2410,20 @@ }, "waldo": { "Package": "waldo", - "Version": "0.5.2", + "Version": "0.5.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "cli", "diffobj", - "fansi", "glue", "methods", "rematch2", "rlang", "tibble" ], - "Hash": "c7d3fd6d29ab077cbac8f0e2751449e6" + "Hash": "16aa934a49658677d8041df9017329b9" }, "withr": { "Package": "withr", @@ -2604,15 +2439,16 @@ }, "xfun": { "Package": "xfun", - "Version": "0.46", + "Version": "0.48", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ + "R", "grDevices", "stats", "tools" ], - "Hash": "00ce32f398db0415dde61abfef11300c" + "Hash": "89e455b87c84e227eb7f60a1b4e5fe1f" }, "xml2": { "Package": "xml2", diff --git a/renv/activate.R b/renv/activate.R index d13f993..c19fc3e 100644 --- a/renv/activate.R +++ b/renv/activate.R @@ -2,7 +2,7 @@ local({ # the requested version of renv - version <- "1.0.7" + version <- "1.0.10" attr(version, "sha") <- NULL # the project directory @@ -98,6 +98,66 @@ local({ unloadNamespace("renv") # load bootstrap tools + ansify <- function(text) { + if (renv_ansify_enabled()) + renv_ansify_enhanced(text) + else + renv_ansify_default(text) + } + + renv_ansify_enabled <- function() { + + override <- Sys.getenv("RENV_ANSIFY_ENABLED", unset = NA) + if (!is.na(override)) + return(as.logical(override)) + + pane <- Sys.getenv("RSTUDIO_CHILD_PROCESS_PANE", unset = NA) + if (identical(pane, "build")) + return(FALSE) + + testthat <- Sys.getenv("TESTTHAT", unset = "false") + if (tolower(testthat) %in% "true") + return(FALSE) + + iderun <- Sys.getenv("R_CLI_HAS_HYPERLINK_IDE_RUN", unset = "false") + if (tolower(iderun) %in% "false") + return(FALSE) + + TRUE + + } + + renv_ansify_default <- function(text) { + text + } + + renv_ansify_enhanced <- function(text) { + + # R help links + pattern <- "`\\?(renv::(?:[^`])+)`" + replacement <- "`\033]8;;ide:help:\\1\a?\\1\033]8;;\a`" + text <- gsub(pattern, replacement, text, perl = TRUE) + + # runnable code + pattern <- "`(renv::(?:[^`])+)`" + replacement <- "`\033]8;;ide:run:\\1\a\\1\033]8;;\a`" + text <- gsub(pattern, replacement, text, perl = TRUE) + + # return ansified text + text + + } + + renv_ansify_init <- function() { + + envir <- renv_envir_self() + if (renv_ansify_enabled()) + assign("ansify", renv_ansify_enhanced, envir = envir) + else + assign("ansify", renv_ansify_default, envir = envir) + + } + `%||%` <- function(x, y) { if (is.null(x)) y else x } @@ -142,7 +202,10 @@ local({ # compute common indent indent <- regexpr("[^[:space:]]", lines) common <- min(setdiff(indent, -1L)) - leave - paste(substring(lines, common), collapse = "\n") + text <- paste(substring(lines, common), collapse = "\n") + + # substitute in ANSI links for executable renv code + ansify(text) } @@ -306,7 +369,11 @@ local({ ) if ("headers" %in% names(formals(utils::download.file))) - args$headers <- renv_bootstrap_download_custom_headers(url) + { + headers <- renv_bootstrap_download_custom_headers(url) + if (length(headers) && is.character(headers)) + args$headers <- headers + } do.call(utils::download.file, args) @@ -385,10 +452,22 @@ local({ for (type in types) { for (repos in renv_bootstrap_repos()) { + # build arguments for utils::available.packages() call + args <- list(type = type, repos = repos) + + # add custom headers if available -- note that + # utils::available.packages() will pass this to download.file() + if ("headers" %in% names(formals(utils::download.file))) + { + headers <- renv_bootstrap_download_custom_headers(url) + if (length(headers) && is.character(headers)) + args$headers <- headers + } + # retrieve package database db <- tryCatch( as.data.frame( - utils::available.packages(type = type, repos = repos), + do.call(utils::available.packages, args), stringsAsFactors = FALSE ), error = identity @@ -470,6 +549,14 @@ local({ } + renv_bootstrap_github_token <- function() { + for (envvar in c("GITHUB_TOKEN", "GITHUB_PAT", "GH_TOKEN")) { + envval <- Sys.getenv(envvar, unset = NA) + if (!is.na(envval)) + return(envval) + } + } + renv_bootstrap_download_github <- function(version) { enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE") @@ -477,16 +564,16 @@ local({ return(FALSE) # prepare download options - pat <- Sys.getenv("GITHUB_PAT") - if (nzchar(Sys.which("curl")) && nzchar(pat)) { + token <- renv_bootstrap_github_token() + if (nzchar(Sys.which("curl")) && nzchar(token)) { fmt <- "--location --fail --header \"Authorization: token %s\"" - extra <- sprintf(fmt, pat) + extra <- sprintf(fmt, token) saved <- options("download.file.method", "download.file.extra") options(download.file.method = "curl", download.file.extra = extra) on.exit(do.call(base::options, saved), add = TRUE) - } else if (nzchar(Sys.which("wget")) && nzchar(pat)) { + } else if (nzchar(Sys.which("wget")) && nzchar(token)) { fmt <- "--header=\"Authorization: token %s\"" - extra <- sprintf(fmt, pat) + extra <- sprintf(fmt, token) saved <- options("download.file.method", "download.file.extra") options(download.file.method = "wget", download.file.extra = extra) on.exit(do.call(base::options, saved), add = TRUE) diff --git a/tests/testthat/test-plssem.R b/tests/testthat/test-plssem.R index 3b5f078..7e0a0b8 100644 --- a/tests/testthat/test-plssem.R +++ b/tests/testthat/test-plssem.R @@ -1,6 +1,7 @@ context("PLS-SEM") -# basic PLS SEM works + + options <- jaspTools::analysisOptions("PLSSEM") model <- " ind60 =~ x1 + x2 + x3 @@ -13,8 +14,6 @@ options$models <- list(list(name = "Model1", syntax = list(model = model, column options$group <- "" options$innerWeightingScheme <- "path" options$convergenceCriterion <- "absoluteDifference" -options$correctionFactor <- "squaredEuclidean" -options$handlingOfFlippedSigns <- "none" results <- jaspTools::runAnalysis("PLSSEM", "poldem_grouped.csv", options) @@ -40,13 +39,36 @@ test_that("Loadings table results match", { }) -test_that("Regression Coefficients table results match", { - table <- results[["results"]][["modelContainer"]][["collection"]][["modelContainer_params"]][["collection"]][["modelContainer_params_path"]][["data"]] - jaspTools::expect_equal_tables(table, - list(0.438843974833827, 0.238518982057254, "dem60", "ind60", "", 0.158644372913763, - 0.898128069469413, "dem65", "ind60", 1.23851898205725, 0.908670674402449, - 29.4646949739788, "dem65", "dem60", 1.23851898205725)) -}) + options <- jaspTools::analysisOptions("PLSSEM") + model1 = " + ind60 =~ x1 + x2 + x3 + dem60 =~ y1 + y2 + y3 + y4 + dem65 =~ y5 + y6 + y7 + y8 + dem60 ~ ind60 + dem65 ~ dem60 + " + model2 = " + ind60 =~ x1 + x2 + x3 + dem60 =~ y1 + y2 + y3 + y4 + dem65 =~ y5 + y6 + y7 + y8 + dem60 ~ ind60 + dem65 ~ ind60 + dem60 + " + options$models <- list(list(name = "Model1", syntax = list(model = model1, columns = c("x1", "x2", "x3", "y1", "y2", "y3", "y4", "y5", "y6", "y7", "y8"))), + list(name = "Model2", syntax = list(model = model2, columns = c("x1", "x2", "x3", "y1", "y2", "y3", "y4", "y5", "y6", "y7", "y8")))) + options$group <- "group" + options$innerWeightingScheme <- "path" + options$convergenceCriterion <- "absoluteDifference" + options$additionalFitMeasures <- TRUE + options$rSquared <- TRUE + options$mardiasCoefficient <- TRUE + options$reliabilityMeasures <- TRUE + options$impliedConstructCorrelation <- TRUE + options$impliedIndicatorCorrelation <- TRUE + options$observedConstructCorrelation <- TRUE + options$observedIndicatorCorrelation <- TRUE + options$innerWeightingScheme <- "centroid" + options$structuralModelIgnored <- TRUE test_that("Total effects table results match", { table <- results[["results"]][["modelContainer"]][["collection"]][["modelContainer_params"]][["collection"]][["modelContainer_params_total"]][["data"]] @@ -89,7 +111,6 @@ options$models <- list(list(name = "Model1", syntax = list(model = model1, colum options$group <- "group" options$innerWeightingScheme <- "path" options$convergenceCriterion <- "absoluteDifference" -options$correctionFactor <- "squaredEuclidean" options$additionalFitMeasures <- TRUE options$rSquared <- TRUE options$mardiasCoefficient <- TRUE @@ -333,12 +354,24 @@ test_that("1 table results match", { 1, 0.706803134908571, "dem65")) }) -test_that("2 table results match", { - table <- results[["results"]][["modelContainer"]][["collection"]][["modelContainer_cors"]][["collection"]][["modelContainer_cors_Model2"]][["collection"]][["modelContainer_cors_Model2_observedCon"]][["collection"]][["modelContainer_cors_Model2_observedCon_2"]][["data"]] - jaspTools::expect_equal_tables(table, - list("", "", 1, "ind60", 1, "", 0.319599163621636, "dem60", 0.996650485797297, - 1, 0.402495202076674, "dem65")) -}) + options <- jaspTools::analysisOptions("PLSSEM") + model <- " + ind60 =~ x1 + x2 + x3 + dem60 =~ y1 + y2 + y3 + y4 + dem65 =~ y5 + y6 + y7 + y8 + dem60 ~ ind60 + dem65 ~ ind60 + dem60 + " + options$models <- list(list(name = "Model1", syntax = list(model = model, columns = c("x1", "x2", "x3", "y1", "y2", "y3", "y4", "y5", "y6", "y7", "y8")))) + options$group <- "" + options$innerWeightingScheme <- "path" + options$convergenceCriterion <- "absoluteDifference" + options$setSeed <- TRUE + options$seed <- 123 + options$errorCalculationMethod <- "robust" + options$robustMethod <- "bootstrap" + options$bootstrapSamples <- 200 + options$handlingOfInadmissibles <- "ignore" test_that("1 table results match", { table <- results[["results"]][["modelContainer"]][["collection"]][["modelContainer_cors"]][["collection"]][["modelContainer_cors_Model2"]][["collection"]][["modelContainer_cors_Model2_observedInd"]][["collection"]][["modelContainer_cors_Model2_observedInd_1"]][["data"]] @@ -568,7 +601,6 @@ options$models <- list(list(name = "Model1", syntax = list(model = model, column options$group <- "" options$innerWeightingScheme <- "path" options$convergenceCriterion <- "absoluteDifference" -options$correctionFactor <- "squaredEuclidean" options$setSeed <- TRUE options$seed <- 123 options$errorCalculationMethod <- "robust" @@ -686,25 +718,23 @@ model <- " QUAL <~ qual1 + qual2 + qual3 + qual4 + qual5 VAL <~ val1 + val2 + val3 - # Reflective measurement model - SAT =~ sat1 + sat2 + sat3 + sat4 - LOY =~ loy1 + loy2 + loy3 + loy4 - " -options$models <- list(list(name = "Model1", syntax = list(model = model, columns = c("imag1", "imag2", "imag3", - "expe1", "expe2", "expe3", - "qual1", "qual2", "qual3", "qual4", "qual5", - "val1", "val2", "val3", - "sat1", "sat2", "sat3", "sat4", - "loy1", "loy2", "loy3", "loy4")))) -options$group <- "" -options$innerWeightingScheme <- "path" -options$convergenceCriterion <- "absoluteDifference" -options$correctionFactor <- "squaredEuclidean" -options$handlingOfFlippedSigns <- "none" -options$additionalFitMeasures <- TRUE -options$rSquared <- TRUE -options$mardiasCoefficient <- TRUE -options$reliabilityMeasures <- TRUE + # Reflective measurement model + SAT =~ sat1 + sat2 + sat3 + sat4 + LOY =~ loy1 + loy2 + loy3 + loy4 + " + options$models <- list(list(name = "Model1", syntax = list(model = model, columns = c("imag1", "imag2", "imag3", + "expe1", "expe2", "expe3", + "qual1", "qual2", "qual3", "qual4", "qual5", + "val1", "val2", "val3", + "sat1", "sat2", "sat3", "sat4", + "loy1", "loy2", "loy3", "loy4")))) + options$group <- "" + options$innerWeightingScheme <- "path" + options$convergenceCriterion <- "absoluteDifference" + options$additionalFitMeasures <- TRUE + options$rSquared <- TRUE + options$mardiasCoefficient <- TRUE + options$reliabilityMeasures <- TRUE results <- jaspTools::runAnalysis("PLSSEM", cSEM::satisfaction, options)