diff --git a/.Rbuildignore b/.Rbuildignore index c77838d7..c682cb40 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -8,3 +8,4 @@ ^tests/upgrades$ ^examples$ ^jasp_dev_work_dir$ +^\.claude$ diff --git a/DESCRIPTION b/DESCRIPTION index 8d797dc1..48e2edb7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: jaspReliability Type: Package Title: Reliability Module for JASP -Version: 0.96.4 -Date: 2025-09-25 +Version: 0.97.2 +Date: 2026-06-13 Author: JASP Team Website: https://github.com/jasp-stats/Reliability Maintainer: Julius M. Pfadt diff --git a/NAMESPACE b/NAMESPACE index 24c60671..226455ed 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,34 +1,7 @@ -# Generated by roxygen2: do not edit by hand - -export(blandAltman) +export(reliabilityUnidimensionalFrequentist) export(intraclassCorrelation) export(raterAgreement) +export(blandAltman) export(standardErrorOfMeasurement) -export(unidimensionalReliabilityBayesian) -export(unidimensionalReliabilityFrequentist) -importFrom(jaspBase,.quitAnalysis) -importFrom(jaspBase,.readDataSetToEnd) -importFrom(jaspBase,createJaspContainer) -importFrom(jaspBase,createJaspHtml) -importFrom(jaspBase,createJaspPlot) -importFrom(jaspBase,createJaspQmlSource) -importFrom(jaspBase,createJaspState) -importFrom(jaspBase,createJaspTable) -importFrom(jaspBase,progressbarTick) -importFrom(jaspBase,startProgressbar) -importFrom(stats,approxfun) -importFrom(stats,cor) -importFrom(stats,cov) -importFrom(stats,cov2cor) -importFrom(stats,density) -importFrom(stats,integrate) -importFrom(stats,median) -importFrom(stats,na.omit) -importFrom(stats,pnorm) -importFrom(stats,qchisq) -importFrom(stats,qnorm) -importFrom(stats,quantile) -importFrom(stats,rgamma) -importFrom(stats,rnorm) -importFrom(stats,sd) -importFrom(stats,var) +export(reliabilityUnidimensionalBayesian) +export(reliabilityMultidimensionalBayesian) diff --git a/R/reliabilityMultidimensionalBayesian.R b/R/reliabilityMultidimensionalBayesian.R new file mode 100644 index 00000000..1f200ce6 --- /dev/null +++ b/R/reliabilityMultidimensionalBayesian.R @@ -0,0 +1,605 @@ +#' @importFrom jaspBase createJaspContainer createJaspHtml createJaspPlot createJaspState createJaspTable +#' progressbarTick startProgressbar +#' @importFrom stats cor cov median complete.cases + +# Dependencies that invalidate the fitted model (and therefore everything downstream). +.multiDimBaseDependencies <- c( + "factors", "reverseScaledItems", "modelType", + "noSamples", "noBurnin", "noThin", "noChains", + "setSeed", "seed", "missingValues", "disableSampleSave", + "igShapeManifest", "igScaleManifest", "loadMeanManifest", + "igShapeLatent", "igScaleLatent", "loadMeanLatent", + "igShapeGFactor", "igScaleGFactor" +) + +#' @export +reliabilityMultidimensionalBayesian <- function(jaspResults, dataset, options) { + + allItems <- .multiDimGetItems(options) + ready <- .multiDimReady(options) + + # build a helper option list so the shared (unidimensional) helpers can be reused + optTmp <- options + optTmp[["variables"]] <- allItems + optTmp[["samples"]] <- options[["noSamples"]] + optTmp[["burnin"]] <- options[["noBurnin"]] + optTmp[["thinning"]] <- options[["noThin"]] + optTmp[["naAction"]] <- if (options[["missingValues"]] == "excludeCasesListwise") "listwise" else "pairwise" + + if (ready) { + dataset <- dataset[, allItems, drop = FALSE] + if (length(options[["reverseScaledItems"]]) > 0L) + dataset <- .reverseScoreItems(dataset, optTmp) + .checkErrors(dataset, optTmp, Bayes = TRUE) + } + + model <- .multiDimComputeModel(jaspResults, dataset, options, ready, allItems) + + .multiDimScaleTable(jaspResults, dataset, model, options, ready) + .multiDimItemTable(jaspResults, dataset, model, options, ready, allItems) + .multiDimProbabilityTable(jaspResults, model, options, ready) + .multiDimFitTable(jaspResults, dataset, model, options, ready) + .multiDimPosteriorPlot(jaspResults, model, options, ready) + .multiDimTracePlot(jaspResults, model, options, ready) + .multiDimPPCPlot(jaspResults, dataset, model, options, ready) + + return() +} + + +#### Helpers #### + +# all unique items across the factors form +.multiDimGetItems <- function(options) { + facs <- options[["factors"]] + items <- unlist(lapply(facs, function(f) unlist(f[["indicators"]])), use.names = FALSE) + return(unique(items)) +} + +# a multidimensional model needs at least two factors with at least two items each +.multiDimReady <- function(options) { + facs <- options[["factors"]] + if (length(facs) < 2) + return(FALSE) + nWithTwo <- sum(vapply(facs, function(f) length(unlist(f[["indicators"]])) >= 2L, logical(1))) + return(nWithTwo >= 2L) +} + +# build the lavaan-style group-factor model syntax used by Bayesrel::bomegas +.multiDimBuildModel <- function(options) { + facs <- options[["factors"]] + lines <- character(0) + fi <- 0L + for (i in seq_along(facs)) { + inds <- unlist(facs[[i]][["indicators"]]) + if (length(inds) == 0L) + next + fi <- fi + 1L + lines <- c(lines, sprintf("f%d =~ %s", fi, paste(inds, collapse = " + "))) + } + return(paste(lines, collapse = "\n")) +} + +.getStateContainerMD <- function(jaspResults) { + if (!is.null(jaspResults[["stateContainer"]])) + return(jaspResults[["stateContainer"]]) + + jaspResults[["stateContainer"]] <- createJaspContainer(dependencies = .multiDimBaseDependencies) + return(jaspResults[["stateContainer"]]) +} + +.multiDimPointEst <- function(chains, pointEstimate) { + .getPointEstFun(pointEstimate)(as.vector(chains)) +} + +.multiDimRhat <- function(chains) { + # chains is a [n.chains x n.samples] matrix + mcmcList <- coda::as.mcmc.list(lapply(seq_len(nrow(chains)), function(i) coda::mcmc(chains[i, ]))) + coda::gelman.diag(mcmcList, autoburnin = FALSE)[["psrf"]][1, 1] +} + + +#### Compute #### + +.multiDimComputeModel <- function(jaspResults, dataset, options, ready, allItems) { + + if (!is.null(.getStateContainerMD(jaspResults)[["modelObj"]]$object)) + return(.getStateContainerMD(jaspResults)[["modelObj"]]$object) + + model <- list(modelType = options[["modelType"]], k = length(allItems), items = allItems) + + if (!ready) + return(model) + + modelSyntax <- .multiDimBuildModel(options) + missing <- if (options[["missingValues"]] == "excludeCasesListwise") "listwise" else "impute" + + # the g-factor priors differ between models: the second-order/bi-factor models use an inverse-gamma on + # the g-factor variance (p0 = shape, R0 = scale), whereas the correlated model uses an inverse-Wishart + # on the latent correlation matrix (p0 = degrees of freedom, R0 = scale matrix). For the correlated + # case we expose only the df (latentCorDf, clamped to >= number of factors so the prior stays proper) + # and let Bayesrel build its default scale matrix. + correlated <- options[["modelType"]] == "correlated" + nFactors <- sum(vapply(options[["factors"]], function(f) length(unlist(f[["indicators"]])) > 0L, logical(1))) + p0 <- if (correlated) max(options[["latentCorDf"]], nFactors) else options[["igShapeGFactor"]] + R0 <- if (correlated) NA else options[["igScaleGFactor"]] + + jaspBase::.setSeedJASP(options) + startProgressbar(options[["noChains"]] * options[["noSamples"]]) + + fit <- try(Bayesrel::bomegas( + data = as.matrix(dataset), + model = modelSyntax, + model.type = options[["modelType"]], + n.iter = options[["noSamples"]], + n.burnin = options[["noBurnin"]], + n.chains = options[["noChains"]], + thin = options[["noThin"]], + interval = options[["credibleIntervalValue"]], + missing = missing, + a0 = options[["igShapeManifest"]], + b0 = options[["igScaleManifest"]], + l0 = options[["loadMeanManifest"]], + c0 = options[["igShapeLatent"]], + d0 = options[["igScaleLatent"]], + beta0 = options[["loadMeanLatent"]], + p0 = p0, + R0 = R0, + param.out = TRUE, + callback = progressbarTick, + disableMcmcCheck = TRUE # MCMC bounds are validated in .checkErrors + ), silent = TRUE) + + if (inherits(fit, "try-error")) { + model[["error"]] <- jaspBase::.extractErrorMessage(fit) + return(model) + } + + model[["fit"]] <- fit + + if (!options[["disableSampleSave"]]) { + stateContainer <- .getStateContainerMD(jaspResults) + stateContainer[["modelObj"]] <- createJaspState(model) + } + + return(model) +} + + +#### Tables #### + +.multiDimScaleTable <- function(jaspResults, dataset, model, options, ready) { + + if (!is.null(.getStateContainerMD(jaspResults)[["scaleTable"]]$object)) + return() + + scaleTable <- createJaspTable(gettext("Bayesian Scale Reliability Statistics")) + scaleTable$dependOn(options = c("scoresMethod", "credibleIntervalValue", "rHat")) + scaleTable$position <- 1 + + pointEstimate <- gettextf("Posterior %s", options[["pointEst"]]) + ci <- format(100 * options[["credibleIntervalValue"]], digits = 3, drop0trailing = TRUE) + + scaleTable$addColumnInfo(name = "coefficient", title = gettext("Coefficient"), type = "string") + scaleTable$addColumnInfo(name = "estimate", title = pointEstimate, type = "number") + scaleTable$addColumnInfo(name = "lower", title = gettext("Lower"), type = "number", overtitle = gettextf("%s%% CI", ci)) + scaleTable$addColumnInfo(name = "upper", title = gettext("Upper"), type = "number", overtitle = gettextf("%s%% CI", ci)) + if (options[["rHat"]]) + scaleTable$addColumnInfo(name = "rHat", title = gettext("R-hat"), type = "number") + + stateContainer <- .getStateContainerMD(jaspResults) + stateContainer[["scaleTable"]] <- scaleTable + + if (!ready) { + scaleTable$addFootnote(gettext("Please assign at least two factors with two items each.")) + return() + } + if (!is.null(model[["error"]])) { + scaleTable$setError(model[["error"]]) + return() + } + + fit <- model[["fit"]] + ciValue <- options[["credibleIntervalValue"]] + pointFun <- options[["pointEst"]] + correlated <- options[["modelType"]] == "correlated" + + rows <- list() + footnote <- "" + + addCoefRow <- function(label, chains) { + est <- .multiDimPointEst(chains, pointFun) + cred <- coda::HPDinterval(coda::mcmc(as.vector(chains)), prob = ciValue) + row <- list(coefficient = label, estimate = est, lower = cred[1], upper = cred[2]) + if (options[["rHat"]]) + row[["rHat"]] <- .multiDimRhat(chains) + row + } + addStatRow <- function(label, value) { + row <- list(coefficient = label, estimate = value, lower = NA_real_, upper = NA_real_) + if (options[["rHat"]]) + row[["rHat"]] <- NA_real_ + row + } + + # always display all coefficients; McDonald's omega_h exists only for the non-correlated models + rows[[length(rows) + 1L]] <- addCoefRow("McDonald's ωₜ", fit[["omega_t"]][["chains"]]) + + if (correlated) { + footnote <- gettext("McDonald's ωₕ is shown only for the second-order and bi-factor models, not the correlated-factors model.") + } else { + rows[[length(rows) + 1L]] <- addCoefRow("McDonald's ωₕ", fit[["omega_h"]][["chains"]]) + } + + pairwise <- options[["missingValues"]] != "excludeCasesListwise" + cc <- cor(dataset, use = if (pairwise) "pairwise.complete.obs" else "complete.obs") + rows[[length(rows) + 1L]] <- addStatRow(gettext("Average interitem correlation"), mean(cc[lower.tri(cc)])) + + scores <- if (options[["scoresMethod"]] == "sumScores") + rowSums(dataset, na.rm = TRUE) else rowMeans(dataset, na.rm = TRUE) + rows[[length(rows) + 1L]] <- addStatRow(gettext("Mean"), mean(scores)) + rows[[length(rows) + 1L]] <- addStatRow(gettext("SD"), sd(scores)) + + if (length(rows) > 0L) + scaleTable$setData(do.call(rbind.data.frame, c(rows, stringsAsFactors = FALSE))) + + if (footnote != "") + scaleTable$addFootnote(footnote) + + return() +} + + +.multiDimItemTable <- function(jaspResults, dataset, model, options, ready, allItems) { + + showOmegaT <- options[["itemDeletedOmegaT"]] + showOmegaH <- options[["itemDeletedOmegaH"]] && options[["modelType"]] != "correlated" + showRest <- options[["itemRestCor"]] + if (!(showOmegaT || showOmegaH || showRest) || + !is.null(.getStateContainerMD(jaspResults)[["itemTable"]]$object)) + return() + + itemTable <- createJaspTable(gettext("Bayesian Individual Item Reliability Statistics")) + itemTable$dependOn(options = c("itemDeletedOmegaT", "itemDeletedOmegaH", "itemRestCor", "pointEst")) + itemTable$position <- 2 + + itemTable$addColumnInfo(name = "item", title = gettext("Item"), type = "string") + if (showOmegaT) + itemTable$addColumnInfo(name = "omegaT", title = gettext("McDonald's ωₜ (if item dropped)"), type = "number") + if (showOmegaH) + itemTable$addColumnInfo(name = "omegaH", title = gettext("McDonald's ωₕ (if item dropped)"), type = "number") + if (showRest) + itemTable$addColumnInfo(name = "itemRestCor", title = gettext("Item-rest correlation"), type = "number") + + stateContainer <- .getStateContainerMD(jaspResults) + stateContainer[["itemTable"]] <- itemTable + + if (!ready) + return() + if (!is.null(model[["error"]])) { + itemTable$setError(model[["error"]]) + return() + } + + df <- data.frame(item = jaspBase::decodeColNames(allItems), stringsAsFactors = FALSE) + + footnote <- "" + if (showOmegaT || showOmegaH) { + del <- .multiDimItemDeletedOmega(jaspResults, dataset, options, ready, allItems) + if (showOmegaT) df$omegaT <- del[["omtDel"]] + if (showOmegaH) df$omegaH <- del[["omhDel"]] + if (anyNA(c(if (showOmegaT) del[["omtDel"]], if (showOmegaH) del[["omhDel"]]))) + footnote <- gettext("Empty cells indicate that dropping the item would leave a factor with fewer than two items.") + } + if (showRest) { + df$itemRestCor <- vapply(seq_along(allItems), function(i) { + rest <- rowSums(dataset[, -i, drop = FALSE], na.rm = TRUE) + cor(dataset[, i], rest, use = "pairwise.complete.obs") + }, numeric(1)) + } + + itemTable$setData(df) + + if (footnote != "") + itemTable$addFootnote(footnote) + if (length(options[["reverseScaledItems"]]) > 0L) + itemTable$addFootnote(.addFootnoteReverseScaledItems(options)) + + return() +} + + +# omega-if-item-deleted for multidimensional models: Bayesrel has no built-in support, so refit the +# full Gibbs sampler once per item with that item removed from its factor(s). Items whose removal would +# leave a factor with < 2 indicators are skipped (NA), since the reduced model would be under-identified. +.multiDimItemDeletedOmega <- function(jaspResults, dataset, options, ready, allItems) { + + sc <- .getStateContainerMD(jaspResults) + if (!is.null(sc[["itemDeletedObj"]]$object)) + return(sc[["itemDeletedObj"]]$object) + + k <- length(allItems) + omtDel <- rep(NA_real_, k) + omhDel <- rep(NA_real_, k) + correlated <- options[["modelType"]] == "correlated" + facs <- options[["factors"]] + missing <- if (options[["missingValues"]] == "excludeCasesListwise") "listwise" else "impute" + pointFun <- .getPointEstFun(options[["pointEst"]]) + + startProgressbar(k) + for (i in seq_len(k)) { + item <- allItems[i] + reduced <- lapply(facs, function(f) setdiff(unlist(f[["indicators"]]), item)) + sizes <- vapply(reduced, length, integer(1)) + if (any(sizes[sizes > 0L] < 2L)) { # would under-identify a factor + progressbarTick() + next + } + lines <- character(0); fi <- 0L + for (f in reduced) { + if (length(f) == 0L) next + fi <- fi + 1L + lines <- c(lines, sprintf("f%d =~ %s", fi, paste(f, collapse = " + "))) + } + p0 <- if (correlated) max(options[["latentCorDf"]], fi) else options[["igShapeGFactor"]] + R0 <- if (correlated) NA else options[["igScaleGFactor"]] + datRed <- as.matrix(dataset[, setdiff(allItems, item), drop = FALSE]) + + jaspBase::.setSeedJASP(options) + fitRed <- try(Bayesrel::bomegas( + data = datRed, model = paste(lines, collapse = "\n"), model.type = options[["modelType"]], + n.iter = options[["noSamples"]], n.burnin = options[["noBurnin"]], n.chains = options[["noChains"]], + thin = options[["noThin"]], interval = options[["credibleIntervalValue"]], missing = missing, + a0 = options[["igShapeManifest"]], b0 = options[["igScaleManifest"]], l0 = options[["loadMeanManifest"]], + c0 = options[["igShapeLatent"]], d0 = options[["igScaleLatent"]], beta0 = options[["loadMeanLatent"]], + p0 = p0, R0 = R0, param.out = FALSE, callback = function(){}, disableMcmcCheck = TRUE + ), silent = TRUE) + + if (!inherits(fitRed, "try-error")) { + omtDel[i] <- pointFun(as.vector(fitRed[["omega_t"]][["chains"]])) + if (!correlated) + omhDel[i] <- pointFun(as.vector(fitRed[["omega_h"]][["chains"]])) + } + progressbarTick() + } + + out <- list(omtDel = omtDel, omhDel = omhDel) + sc[["itemDeletedObj"]] <- createJaspState(out, dependencies = c("itemDeletedOmegaT", "itemDeletedOmegaH", "pointEst")) + return(out) +} + + +.multiDimProbabilityTable <- function(jaspResults, model, options, ready) { + + if (!options[["probTable"]] || !is.null(.getStateContainerMD(jaspResults)[["probabilityTable"]]$object)) + return() + + if (options[["probTableValueLow"]] > options[["probTableValueHigh"]]) { + low <- options[["probTableValueHigh"]] + high <- options[["probTableValueLow"]] + footnote <- gettext("The bounds you entered have been rearranged in increasing order to provide meaningful results.") + } else { + low <- options[["probTableValueLow"]] + high <- options[["probTableValueHigh"]] + footnote <- "" + } + + probabilityTable <- createJaspTable( + gettextf("Probability that Reliability Coefficient is Larger than %1$.2f and Smaller than %2$.2f", low, high)) + probabilityTable$dependOn(options = c("probTable", "probTableValueLow", "probTableValueHigh")) + probabilityTable$position <- 3 + probabilityTable$addColumnInfo(name = "coefficient", title = gettext("Coefficient"), type = "string") + probabilityTable$addColumnInfo(name = "posterior", title = gettext("Posterior"), type = "number", + overtitle = gettext("Probability")) + + stateContainer <- .getStateContainerMD(jaspResults) + stateContainer[["probabilityTable"]] <- probabilityTable + + if (!ready) + return() + if (!is.null(model[["error"]])) { + probabilityTable$setError(model[["error"]]) + return() + } + + fit <- model[["fit"]] + rows <- list() + probInRange <- function(chains) { + samp <- as.vector(chains) + mean(samp > low) - mean(samp > high) + } + rows[[length(rows) + 1L]] <- list(coefficient = "McDonald's ωₜ", posterior = probInRange(fit[["omega_t"]][["chains"]])) + if (options[["modelType"]] != "correlated") + rows[[length(rows) + 1L]] <- list(coefficient = "McDonald's ωₕ", posterior = probInRange(fit[["omega_h"]][["chains"]])) + + if (length(rows) > 0L) + probabilityTable$setData(do.call(rbind.data.frame, c(rows, stringsAsFactors = FALSE))) + + if (footnote != "") + probabilityTable$addFootnote(footnote) + + return() +} + + +.multiDimFitTable <- function(jaspResults, dataset, model, options, ready) { + + if (!options[["fitMeasures"]] || !is.null(.getStateContainerMD(jaspResults)[["fitTable"]]$object)) + return() + + fitTable <- createJaspTable(gettext("Fit Measures of the Factor Model")) + fitTable$dependOn(options = c("fitMeasures", "credibleIntervalValueFitMeasures", "fitCutoffSat")) + fitTable$position <- 4 + + fitTable$addColumnInfo(name = "estimate", title = gettext("Estimate"), type = "string") + fitTable$addColumnInfo(name = "lr", title = "B-LR", type = "number") + fitTable$addColumnInfo(name = "srmr", title = "B-SRMR", type = "number") + fitTable$addColumnInfo(name = "rmsea", title = "B-RMSEA", type = "number") + + stateContainer <- .getStateContainerMD(jaspResults) + stateContainer[["fitTable"]] <- fitTable + + if (!ready) + return() + if (!is.null(model[["error"]])) { + fitTable$setError(model[["error"]]) + return() + } + + ciFit <- options[["credibleIntervalValueFitMeasures"]] + fitOut <- try(Bayesrel::multiFit(model[["fit"]], data = as.matrix(dataset), ppc = FALSE, + cutoff = options[["fitCutoffSat"]], ci = ciFit), silent = TRUE) + if (inherits(fitOut, "try-error")) { + fitTable$setError(jaspBase::.extractErrorMessage(fitOut)) + return() + } + + srmrCi <- as.numeric(coda::HPDinterval(coda::mcmc(fitOut[["srmr_samp"]]), prob = ciFit)) + cred <- gettextf("%s%% CI", format(100 * ciFit, digits = 3, drop0trailing = TRUE)) + + df <- data.frame( + estimate = c(gettext("Point estimate"), gettextf("%s lower bound", cred), + gettextf("%s upper bound", cred), gettext("Relative to cutoff")), + lr = c(fitOut[["LR"]], NA_real_, NA_real_, NA_real_), + srmr = c(fitOut[["srmr_pointEst"]], srmrCi[1], srmrCi[2], NA_real_), + rmsea = c(fitOut[["rmsea_pointEst"]], fitOut[["rmsea_ci"]][1], fitOut[["rmsea_ci"]][2], fitOut[["p_rmsea"]]), + stringsAsFactors = FALSE + ) + fitTable$setData(df) + fitTable$addFootnote(gettextf("'Relative to cutoff' denotes the posterior probability that the B-RMSEA is smaller than the cutoff of %.2f.", + options[["fitCutoffSat"]])) + + return() +} + + +#### Plots #### + +.multiDimPosteriorPlot <- function(jaspResults, model, options, ready) { + + if (!options[["plotPosterior"]] || !is.null(.getStateContainerMD(jaspResults)[["posteriorPlots"]]$object)) + return() + + plotContainer <- createJaspContainer(gettext("Posterior Plots")) + plotContainer$dependOn(options = c("plotPosterior", "fixXRange", "dispPrior", "shadePlots", + "probTable", "probTableValueLow", "probTableValueHigh", + "credibleIntervalValue")) + plotContainer$position <- 6 + + if (!ready || !is.null(model[["error"]])) { + stateContainer <- .getStateContainerMD(jaspResults) + stateContainer[["posteriorPlots"]] <- plotContainer + return() + } + + fit <- model[["fit"]] + ciValue <- options[["credibleIntervalValue"]] + + if (options[["shadePlots"]] && options[["probTable"]]) { + low <- min(options[["probTableValueLow"]], options[["probTableValueHigh"]]) + high <- max(options[["probTableValueLow"]], options[["probTableValueHigh"]]) + shade <- c(low, high) + } else { + shade <- NULL + } + + coefs <- list() + coefs[["omegaT"]] <- list(chains = fit[["omega_t"]][["chains"]], label = "McDonald's ωₜ") + if (options[["modelType"]] != "correlated") + coefs[["omegaH"]] <- list(chains = fit[["omega_h"]][["chains"]], label = "McDonald's ωₕ") + + for (nm in names(coefs)) { + cred <- coda::HPDinterval(coda::mcmc(as.vector(coefs[[nm]][["chains"]])), prob = ciValue) + p <- .makeSinglePosteriorPlot(list(samp = coefs[[nm]][["chains"]]), cred, coefs[[nm]][["label"]], + options[["fixXRange"]], shade, priorTrue = FALSE, priorSample = NULL) + plotObj <- createJaspPlot(plot = p, title = coefs[[nm]][["label"]]) + plotContainer[[nm]] <- plotObj + } + + stateContainer <- .getStateContainerMD(jaspResults) + stateContainer[["posteriorPlots"]] <- plotContainer + + return() +} + + +.multiDimTracePlot <- function(jaspResults, model, options, ready) { + + if (!options[["tracePlot"]] || !is.null(.getStateContainerMD(jaspResults)[["tracePlots"]]$object)) + return() + + plotContainer <- createJaspContainer(gettext("Convergence Traceplot")) + plotContainer$dependOn(options = c("tracePlot")) + plotContainer$position <- 7 + + if (!ready || !is.null(model[["error"]])) { + stateContainer <- .getStateContainerMD(jaspResults) + stateContainer[["tracePlots"]] <- plotContainer + return() + } + + fit <- model[["fit"]] + coefs <- list() + coefs[["omegaT"]] <- list(chains = fit[["omega_t"]][["chains"]], label = "McDonald's ωₜ") + if (options[["modelType"]] != "correlated") + coefs[["omegaH"]] <- list(chains = fit[["omega_h"]][["chains"]], label = "McDonald's ωₕ") + + for (nm in names(coefs)) { + p <- .makeTracePlot(list(samp = coefs[[nm]][["chains"]]), coefs[[nm]][["label"]]) + plotObj <- createJaspPlot(plot = p, title = coefs[[nm]][["label"]], width = 400) + plotContainer[[nm]] <- plotObj + } + + stateContainer <- .getStateContainerMD(jaspResults) + stateContainer[["tracePlots"]] <- plotContainer + + return() +} + + +.multiDimPPCPlot <- function(jaspResults, dataset, model, options, ready) { + + if (!options[["dispPPC"]] || !is.null(.getStateContainerMD(jaspResults)[["ppcPlot"]]$object)) + return() + + plot <- createJaspPlot(title = gettext("Posterior Predictive Check"), width = 350) + plot$dependOn(options = "dispPPC") + plot$position <- 8 + + stateContainer <- .getStateContainerMD(jaspResults) + stateContainer[["ppcPlot"]] <- plot + + if (!ready || !is.null(model[["error"]])) + return() + + implCovs <- model[["fit"]][["implCovs"]] + pairwise <- options[["missingValues"]] != "excludeCasesListwise" + cdat <- cov(dataset, use = if (pairwise) "pairwise.complete.obs" else "complete.obs") + k <- ncol(cdat) + n <- nrow(dataset) + nsamp <- dim(implCovs)[1] + + eeImpl <- matrix(0, nsamp, k) + for (i in seq_len(nsamp)) { + dtmp <- MASS::mvrnorm(n, rep(0, k), implCovs[i, , ]) + eeImpl[i, ] <- eigen(cov(dtmp), only.values = TRUE)$values + } + + eframe <- data.frame(number = seq_len(k), eigen_value = eigen(cdat, only.values = TRUE)$values) + eframe$eigen_sim_low <- apply(eeImpl, 2, quantile, prob = .025) + eframe$eigen_sim_up <- apply(eeImpl, 2, quantile, prob = .975) + + yBreaks <- jaspGraphs::getPrettyAxisBreaks(c(0, max(eframe$eigen_sim_up))) + + g <- ggplot2::ggplot(eframe, mapping = ggplot2::aes(x = number, y = eigen_value)) + + ggplot2::geom_errorbar(ggplot2::aes(ymin = eigen_sim_low, ymax = eigen_sim_up), color = "grey55", + width = 0.2, size = 1) + + ggplot2::geom_point(size = 2.25) + + ggplot2::scale_y_continuous(name = gettext("Eigenvalue"), breaks = yBreaks, limits = range(yBreaks)) + + ggplot2::scale_x_continuous(name = gettext("Eigenvalue No."), breaks = seq_len(k), + expand = ggplot2::expand_scale(mult = c(.1, .1))) + + plot$plotObject <- jaspGraphs::themeJasp(g) + + return() +} diff --git a/R/unidimensionalReliabilityBayesian.R b/R/reliabilityUnidimensionalBayesian.R similarity index 99% rename from R/unidimensionalReliabilityBayesian.R rename to R/reliabilityUnidimensionalBayesian.R index 9745ca32..f0bff51b 100644 --- a/R/unidimensionalReliabilityBayesian.R +++ b/R/reliabilityUnidimensionalBayesian.R @@ -5,7 +5,7 @@ #' @importFrom stats approxfun cor cov cov2cor density integrate median na.omit pnorm qchisq qnorm quantile rgamma rnorm sd var #' @export -unidimensionalReliabilityBayesian <- function(jaspResults, dataset, options) { +reliabilityUnidimensionalBayesian <- function(jaspResults, dataset, options) { options <- jaspBase::.parseAndStoreFormulaOptions(jaspResults, options, "inverseWishartPriorScale") diff --git a/R/unidimensionalReliabilityFrequentist.R b/R/reliabilityUnidimensionalFrequentist.R similarity index 99% rename from R/unidimensionalReliabilityFrequentist.R rename to R/reliabilityUnidimensionalFrequentist.R index 218a2d75..91e61582 100644 --- a/R/unidimensionalReliabilityFrequentist.R +++ b/R/reliabilityUnidimensionalFrequentist.R @@ -1,6 +1,6 @@ #' @export -unidimensionalReliabilityFrequentist <- function(jaspResults, dataset, options) { +reliabilityUnidimensionalFrequentist <- function(jaspResults, dataset, options) { # check for listwise deletion diff --git a/inst/Description.qml b/inst/Description.qml index 9e7b4155..e1306a19 100644 --- a/inst/Description.qml +++ b/inst/Description.qml @@ -18,8 +18,8 @@ Description Analysis { title: qsTr("Reliability") - qml: "UnidimensionalReliabilityFrequentist.qml" - func: "unidimensionalReliabilityFrequentist" + qml: "ReliabilityUnidimensionalFrequentist.qml" + func: "reliabilityUnidimensionalFrequentist" } Analysis @@ -28,7 +28,7 @@ Description qml: "IntraclassCorrelation.qml" func: "intraclassCorrelation" } - + Analysis { title: qsTr("Rater Agreement") @@ -58,10 +58,17 @@ Description } Analysis { - menu: qsTr("Reliability") title: qsTr("Bayesian Reliability") - qml: "UnidimensionalReliabilityBayesian.qml" - func: "unidimensionalReliabilityBayesian" + menu: qsTr("Reliability") + qml: "ReliabilityUnidimensionalBayesian.qml" + func: "reliabilityUnidimensionalBayesian" + } + Analysis + { + title: qsTr("Bayesian Multidimensional Reliability") + menu: qsTr("Multidimensional Reliability") + qml: "ReliabilityMultidimensionalBayesian.qml" + func: "reliabilityMultidimensionalBayesian" } } diff --git a/inst/Upgrades.qml b/inst/Upgrades.qml index 9561f52a..4f3f5694 100644 --- a/inst/Upgrades.qml +++ b/inst/Upgrades.qml @@ -741,4 +741,20 @@ Upgrades } } + + Upgrade + { + functionName: "unidimensionalReliabilityFrequentist" + newFunctionName: "reliabilityUnidimensionalFrequentist" + fromVersion: "0.17.0" + toVersion: "0.97.0" + } + + Upgrade + { + functionName: "unidimensionalReliabilityBayesian" + newFunctionName: "reliabilityUnidimensionalBayesian" + fromVersion: "0.17.0" + toVersion: "0.97.0" + } } diff --git a/inst/help/unidimensionalReliabilityBayesian.md b/inst/help/reliabilityUnidimensionalBayesian.md similarity index 100% rename from inst/help/unidimensionalReliabilityBayesian.md rename to inst/help/reliabilityUnidimensionalBayesian.md diff --git a/inst/help/unidimensionalReliabilityFrequentist.md b/inst/help/reliabilityUnidimensionalFrequentist.md similarity index 100% rename from inst/help/unidimensionalReliabilityFrequentist.md rename to inst/help/reliabilityUnidimensionalFrequentist.md diff --git a/inst/qml/ReliabilityMultidimensionalBayesian.qml b/inst/qml/ReliabilityMultidimensionalBayesian.qml new file mode 100644 index 00000000..4bfe916c --- /dev/null +++ b/inst/qml/ReliabilityMultidimensionalBayesian.qml @@ -0,0 +1,479 @@ +// +// Copyright (C) 2013-2020 University of Amsterdam +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public +// License along with this program. If not, see +// . +// + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import JASP.Controls +import JASP.Theme +import JASP.Widgets + +Form +{ + FactorsForm + { + id: factors + name: "factors" + initNumberFactors: 2 + allowedColumns: ["scale"] + } + + DropDown + { + id: modelType + name: "modelType" + label: qsTr("Model") + values: + [ + { label: qsTr("Second-order"), value: "secondOrder" }, + { label: qsTr("Bi-factor"), value: "biFactor" }, + { label: qsTr("Correlated factors"), value: "correlated" } + ] + info: qsTr("The factor model used to estimate the reliability coefficients. McDonald's ω_h (general/group-common reliability) is only available for the second-order and bi-factor models.") + } + + RadioButtonGroup + { + name: "scoresMethod" + title: qsTr("Mean and standard deviation of") + + RadioButton { value: "sumScores"; label: qsTr("participants' sum scores"); checked: true} + RadioButton { value: "meanScores"; label: qsTr("participants' mean scores")} + } + + Group + { + title: qsTr("Item statistics") + CheckBox { name: "itemDeletedOmegaT"; label: qsTr("McDonald's ω_t (if item dropped)") } + CheckBox { name: "itemDeletedOmegaH"; label: qsTr("McDonald's ω_h (if item dropped)"); enabled: modelType.currentValue !== "correlated" } + CheckBox { name: "itemRestCor"; label: qsTr("Item-rest correlation") } + } + + Section + { + title: qsTr("Output options") + Group + { + title: qsTr("Scale Statistics") + CIField + { + name: "credibleIntervalValue"; + label: qsTr("Credible interval"); + defaultValue: 95; + } + } + + Group + { + CheckBox + { + name: "plotPosterior"; + label: qsTr("Plot Posteriors"); + id: postPlot + + CheckBox + { + name: "fixXRange"; + label: qsTr("Fix range to 0-1") + } + + CheckBox + { + name: "dispPrior"; + label: qsTr("Display Priors") + } + + } + } + + Group + { + CheckBox + { + id: probTable + name: "probTable" + label: qsTr("Probability for:") + childrenOnSameRow: true + + RowLayout + { + DoubleField + { + id: probTableValueLow + name: "probTableValueLow" + label: "" + defaultValue: 0.70 + min: 0 + max: 1 + decimals: 2 + fieldWidth: 40 + } + + Label + { text: qsTr("< Reliability <")} + + DoubleField + { + name: "probTableValueHigh" + label: "" + defaultValue: .90 + min: 0 + max: 1 + decimals: 2 + fieldWidth: 40 + } + } + } + + + Item + { + width: shadePlots.width + Theme.subOptionOffset + height: shadePlots.height + + CheckBox + { + id: shadePlots + name: "shadePlots"; + indent: true + label: qsTr("Shade posterior region in plot"); + enabled: probTable.checked & postPlot.checked + x: Theme.subOptionOffset + } + } + } + + Group + { + title: qsTr("") + + RadioButtonGroup + { + name: "pointEst" + title: qsTr("Posterior Point Estimate") + RadioButton{ value: "mean"; label: qsTr("Mean"); checked: true } + RadioButton{ value: "median"; label: qsTr("Median") } + } + } + + Group + { + title: qsTr("Model fit") + CheckBox + { + name: "dispPPC" + label: qsTr("Posterior predictive check"); + } + CheckBox + { + name: "fitMeasures" + label: qsTr("Fit measures"); + + CIField + { + name: "credibleIntervalValueFitMeasures"; + label: qsTr("Credible interval"); + defaultValue: 90 + } + + DoubleField + { + name: "fitCutoffSat" + label: qsTr("p(RMSEA <") + defaultValue: .08 + min: 0 + max: 1 + fieldWidth: 40 + afterLabel: qsTr(")") + } + DoubleField + { + name: "fitCutoffNull" + label: qsTr("p(CFI/TLI >") + defaultValue: .9 + min: 0 + max: 1 + fieldWidth: 40 + afterLabel: qsTr(")") + } + } + } + } + Section + { + title: qsTr("MCMC options") + + Group + { + title: qsTr("MCMC parameters"); + + IntegerField + { + id: noSamples + name: "noSamples" + label: qsTr("No. samples") + defaultValue: 2000 + fieldWidth: 60 + min: 100 + max: 1e7 + } + + IntegerField + { + id: noBurnin + name: "noBurnin" + label: qsTr("No. burnin samples") + defaultValue: 200 + fieldWidth: 60 + min: 1 + max: 1e6 + } + + IntegerField + { + id: noThin + name: "noThin" + label: qsTr("Thinning") + defaultValue: 1 + fieldWidth: 40 + min: 1 + max: 1e5 + } + + IntegerField + { + name: "noChains" + label: qsTr("No. chains") + defaultValue: 3 + fieldWidth: 40 + min: 2 + max: 100 + } + } + + Group + { + title: qsTr("Diagnostics") + + CheckBox { name: "rHat"; label: qsTr("R-hat"); } + CheckBox { name: "tracePlot"; label: qsTr("Traceplots"); } + } + + Group + { + title: qsTr("Repeatability") + + CheckBox + { + name: "setSeed" + label: qsTr("Set seed") + childrenOnSameRow: true + + IntegerField + { + name: "seed" + label: "" + defaultValue: 1234 + fieldWidth: 100 + min: 1 + max: 1e9 + } + } + } + + Group + { + title: qsTr("Samples") + + CheckBox + { + name: "disableSampleSave" + label: qsTr("Disable saving samples") + checked: false + } + + } + } + + Section + { + title: qsTr("Reverse-Scaled Items") + + VariablesForm + { + height: 150 + AvailableVariablesList { name: "normalScaledItems"; title: qsTr("Normal-Scaled Items"); source: factors.name } + AssignedVariablesList { name: "reverseScaledItems"; title: qsTr("Reverse-Scaled Items") } + } + } + + Section + { + title: qsTr("Priors") + + Group + { + title: qsTr("Measurement level") + + Group + { + title: qsTr("Residual variances: Inverse gamma") + IntegerField + { + name: "igShapeManifest" + label: qsTr("shape") + defaultValue: 2 + min: 0 + max: 100 + fieldWidth: 40 + } + IntegerField + { + name: "igScaleManifest" + label: qsTr("scale") + defaultValue: 1 + min: 0 + max: 100 + fieldWidth: 40 + } + } + + Group + { + title: qsTr("Loadings: Normal") + DoubleField + { + name: "loadMeanManifest" + label: qsTr("mean") + defaultValue: 0 + min: -10 + max: 10 + fieldWidth: 40 + } + } + } + + Group + { + title: qsTr("Structural level") + visible: modelType.currentValue !== "correlated" + + Group + { + title: qsTr("Residual variances: Inverse gamma") + IntegerField + { + name: "igShapeLatent" + label: qsTr("shape") + defaultValue: 2 + min: 0 + max: 100 + fieldWidth: 40 + } + IntegerField + { + name: "igScaleLatent" + label: qsTr("scale") + defaultValue: 1 + min: 0 + max: 100 + fieldWidth: 40 + } + } + + Group + { + title: qsTr("Loadings: Normal") + DoubleField + { + name: "loadMeanLatent" + label: qsTr("mean") + defaultValue: 0 + min: -10 + max: 10 + fieldWidth: 40 + } + } + Group + { + title: qsTr("Factor variance: Inverse gamma") + + IntegerField + { + name: "igShapeGFactor" + label: qsTr("shape") + defaultValue: 2 + min: 1 + max: 100 + fieldWidth: 40 + } + IntegerField + { + name: "igScaleGFactor" + label: qsTr("scale") + defaultValue: 1 + min: 1 + max: 100 + fieldWidth: 40 + } + } + } + + + + Group + { + title: qsTr("Latent correlations") + visible: modelType.currentValue === "correlated" + + Group + { + title: qsTr("Correlation matrix: Inverse-Wishart") + IntegerField + { + name: "latentCorDf" + label: qsTr("degrees of freedom") + defaultValue: 2 + min: 1 + max: 1000 + fieldWidth: 40 + } + } + } + } + + Section + { + title: qsTr("Advanced Options") + + Group + { + title: qsTr("Missing Values") + RadioButtonGroup + { + title: qsTr("") + name: "missingValues" + + RadioButton { value: "excludeCasesPairwise"; label: qsTr("Bayesian imputation"); checked: true} + RadioButton { value: "excludeCasesListwise"; label: qsTr("Exclude cases listwise")} + } + } + + } + +} diff --git a/inst/qml/UnidimensionalReliabilityBayesian.qml b/inst/qml/ReliabilityUnidimensionalBayesian.qml similarity index 100% rename from inst/qml/UnidimensionalReliabilityBayesian.qml rename to inst/qml/ReliabilityUnidimensionalBayesian.qml diff --git a/inst/qml/UnidimensionalReliabilityFrequentist.qml b/inst/qml/ReliabilityUnidimensionalFrequentist.qml similarity index 100% rename from inst/qml/UnidimensionalReliabilityFrequentist.qml rename to inst/qml/ReliabilityUnidimensionalFrequentist.qml diff --git a/man/dot-frequentistOmegaScale.Rd b/man/dot-frequentistOmegaScale.Rd index e2510a22..aeef0162 100644 --- a/man/dot-frequentistOmegaScale.Rd +++ b/man/dot-frequentistOmegaScale.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/unidimensionalReliabilityFrequentist.R +% Please edit documentation in R/reliabilityUnidimensionalFrequentist.R \name{.frequentistOmegaScale} \alias{.frequentistOmegaScale} \title{So the structure here is to first calculcate the bootstrap samples per coefficient diff --git a/renv.lock b/renv.lock index d007a83f..87387d13 100644 --- a/renv.lock +++ b/renv.lock @@ -2527,40 +2527,72 @@ "Package": "jaspBase", "Version": "0.20.4", "Source": "GitHub", - "Requirements": [ + "Type": "Package", + "Title": "JASP Base", + "Author": "JASP Team", + "Maintainer": "Bruno Boutin ", + "Description": "Package contains the JASP Bayesian and Frequentist analyses. See for more details.", + "License": "GPL2+", + "Imports": [ "cli", "codetools", + "compiler", "ggplot2", + "grDevices", + "grid", "gridExtra", "gridGraphics", "jaspGraphs", "jsonlite", "lifecycle", + "methods", "officer", "pkgbuild", "plyr", "ragg", "R6", - "Rcpp", + "Rcpp (>= 0.12.14)", "rvg", "svglite", "systemfonts", - "withr", - "testthat" + "withr" ], + "RoxygenNote": "7.3.3", + "Roxygen": "list(markdown = TRUE)", + "Encoding": "UTF-8", + "LinkingTo": [ + "Rcpp" + ], + "RcppModules": "jaspResults", + "NeedsCompilation": "yes", + "Suggests": [ + "testthat (>= 3.0.0)" + ], + "Config/testthat/edition": "3", "RemoteType": "github", "RemoteHost": "api.github.com", "RemoteUsername": "jasp-stats", "RemoteRepo": "jaspBase", - "RemoteSha": "93f004588f6d56b46d23210e23bff003ae7b1ff4" + "RemoteRef": "master", + "RemoteSha": "209d1787d5c9400601df960535b261029a350b12", + "Remotes": "jasp-stats/jaspGraphs" }, "jaspGraphs": { "Package": "jaspGraphs", "Version": "0.20.0", "Source": "GitHub", - "Requirements": [ + "Type": "Package", + "Title": "Custom Graphs for JASP", + "Author": "Don van den Bergh", + "Maintainer": "JASP-team ", + "Description": "Graph making functions and wrappers for JASP.", + "License": "GPL", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.3.3", + "Imports": [ "cli", - "ggplot2", + "ggplot2 (>= 3.0.0)", "gridExtra", "gtable", "htmlwidgets", @@ -2569,15 +2601,61 @@ "plotly", "R6", "rlang", - "scales", + "scales" + ], + "Suggests": [ "testthat", "vdiffr" ], + "Roxygen": "list(markdown = TRUE)", "RemoteType": "github", "RemoteHost": "api.github.com", "RemoteUsername": "jasp-stats", "RemoteRepo": "jaspGraphs", - "RemoteSha": "1eb48e7e0fe9559bbd15da25f30703c7cca246bb" + "RemoteRef": "master", + "RemoteSha": "cbe943517ac21078d0a502bcfaf8ae5e11756a05" + }, + "jaspTools": { + "Package": "jaspTools", + "Version": "0.20.1", + "Source": "GitHub", + "Type": "Package", + "Title": "Helps Preview and Debug JASP Analyses", + "Authors@R": "c( person(\"Tim\", \"de Jong\", role = \"aut\"), person(\"Don\", \"van den Bergh\", role = c(\"ctb\", \"cre\"), email = \"d.vandenbergh@uva.nl\"), person(\"František\", \"Bartoš\", role = \"ctb\"))", + "Maintainer": "Don van den Bergh ", + "Description": "This package assists JASP developers when writing R code. It removes the necessity of building JASP every time a change is made. Rather, analyses can be called directly in R and be debugged interactively.", + "License": "GNU General Public License", + "Encoding": "UTF-8", + "LazyData": "true", + "Imports": [ + "archive (>= 1.1.6)", + "cli", + "data.table", + "DBI", + "httr", + "jsonlite", + "lifecycle", + "pkgload", + "remotes", + "rjson", + "RSQLite", + "stringi", + "stringr", + "testthat (>= 3.2.2)", + "vdiffr (>= 1.0.7)" + ], + "Suggests": [ + "ggplot2" + ], + "RoxygenNote": "7.3.3", + "Roxygen": "list(markdown = TRUE)", + "Author": "Tim de Jong [aut], Don van den Bergh [ctb, cre], František Bartoš [ctb]", + "RemoteType": "github", + "RemoteHost": "api.github.com", + "RemoteUsername": "jasp-stats", + "RemoteRepo": "jaspTools", + "RemoteRef": "master", + "RemoteSha": "281f17a2d6761eb5ec247d7ddcd59042f01fa409" }, "jquerylib": { "Package": "jquerylib", diff --git a/tests/testthat/_snaps/blandAltman/reference_plotobject/baplot.rds b/tests/testthat/_snaps/blandAltman/reference_plotobject/baplot.rds new file mode 100644 index 00000000..39d602f5 Binary files /dev/null and b/tests/testthat/_snaps/blandAltman/reference_plotobject/baplot.rds differ diff --git a/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-1-anova.rds b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-1-anova.rds new file mode 100644 index 00000000..8b2a61fa Binary files /dev/null and b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-1-anova.rds differ diff --git a/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-10-irt-grm.rds b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-10-irt-grm.rds new file mode 100644 index 00000000..69ac2b94 Binary files /dev/null and b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-10-irt-grm.rds differ diff --git a/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-11-mollenkopf-feldt.rds b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-11-mollenkopf-feldt.rds new file mode 100644 index 00000000..4aa8ce77 Binary files /dev/null and b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-11-mollenkopf-feldt.rds differ diff --git a/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-12-thorndike.rds b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-12-thorndike.rds new file mode 100644 index 00000000..0cea011d Binary files /dev/null and b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-12-thorndike.rds differ diff --git a/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-2-feldt.rds b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-2-feldt.rds new file mode 100644 index 00000000..ab099720 Binary files /dev/null and b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-2-feldt.rds differ diff --git a/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-3-irt-grm.rds b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-3-irt-grm.rds new file mode 100644 index 00000000..99fa13db Binary files /dev/null and b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-3-irt-grm.rds differ diff --git a/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-4-mollenkopf-feldt.rds b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-4-mollenkopf-feldt.rds new file mode 100644 index 00000000..3c48dedf Binary files /dev/null and b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-4-mollenkopf-feldt.rds differ diff --git a/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-5-thorndike.rds b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-5-thorndike.rds new file mode 100644 index 00000000..49030b6e Binary files /dev/null and b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-5-thorndike.rds differ diff --git a/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-6-combined-plot.rds b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-6-combined-plot.rds new file mode 100644 index 00000000..8e0aa1d2 Binary files /dev/null and b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-6-combined-plot.rds differ diff --git a/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-7-histogram-of-counts-per-sum-score-group.rds b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-7-histogram-of-counts-per-sum-score-group.rds new file mode 100644 index 00000000..f8da9798 Binary files /dev/null and b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-7-histogram-of-counts-per-sum-score-group.rds differ diff --git a/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-8-anova.rds b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-8-anova.rds new file mode 100644 index 00000000..acc1a6e6 Binary files /dev/null and b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-8-anova.rds differ diff --git a/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-9-feldt.rds b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-9-feldt.rds new file mode 100644 index 00000000..c95eff79 Binary files /dev/null and b/tests/testthat/_snaps/library-ADD symptoms/reference_plotobject/analysis-1-figure-9-feldt.rds differ diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/coefficient-alpha-item.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/coefficient-alpha-item.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/coefficient-alpha-item.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/coefficient-alpha-item.svg diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/coefficient-alpha-scale.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/coefficient-alpha-scale.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/coefficient-alpha-scale.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/coefficient-alpha-scale.svg diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/coefficient-alpha-std.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/coefficient-alpha-std.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/coefficient-alpha-std.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/coefficient-alpha-std.svg diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/coefficient-alpha-tp.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/coefficient-alpha-tp.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/coefficient-alpha-tp.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/coefficient-alpha-tp.svg diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/coefficient-omega-item.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/coefficient-omega-item.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/coefficient-omega-item.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/coefficient-omega-item.svg diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/coefficient-omega-scale.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/coefficient-omega-scale.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/coefficient-omega-scale.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/coefficient-omega-scale.svg diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/coefficient-omega-std.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/coefficient-omega-std.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/coefficient-omega-std.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/coefficient-omega-std.svg diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/coefficient-omega-tp.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/coefficient-omega-tp.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/coefficient-omega-tp.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/coefficient-omega-tp.svg diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/cronbach-s-alpha-item-mean-ordered.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/cronbach-s-alpha-item-mean-ordered.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/cronbach-s-alpha-item-mean-ordered.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/cronbach-s-alpha-item-mean-ordered.svg diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/guttman-s-lambda2-item.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/guttman-s-lambda2-item.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/guttman-s-lambda2-item.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/guttman-s-lambda2-item.svg diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/guttman-s-lambda2-scale.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/guttman-s-lambda2-scale.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/guttman-s-lambda2-scale.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/guttman-s-lambda2-scale.svg diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/guttman-s-lambda2-std.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/guttman-s-lambda2-std.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/guttman-s-lambda2-std.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/guttman-s-lambda2-std.svg diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/guttman-s-lambda2-tp.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/guttman-s-lambda2-tp.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/guttman-s-lambda2-tp.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/guttman-s-lambda2-tp.svg diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/lambda2-prior-adjusted.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/lambda2-prior-adjusted.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/lambda2-prior-adjusted.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/lambda2-prior-adjusted.svg diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/omega-prior-adjusted.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/omega-prior-adjusted.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/omega-prior-adjusted.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/omega-prior-adjusted.svg diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/posterior-predictive-check-omega.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/posterior-predictive-check-omega.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/posterior-predictive-check-omega.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/posterior-predictive-check-omega.svg diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-alpha-item.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-alpha-item.rds new file mode 100644 index 00000000..7e430b90 Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-alpha-item.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-alpha-scale.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-alpha-scale.rds new file mode 100644 index 00000000..2ac44532 Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-alpha-scale.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-alpha-std.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-alpha-std.rds new file mode 100644 index 00000000..b7eaa328 Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-alpha-std.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-alpha-tp.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-alpha-tp.rds new file mode 100644 index 00000000..d5f7c680 Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-alpha-tp.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-omega-item.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-omega-item.rds new file mode 100644 index 00000000..13237f23 Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-omega-item.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-omega-scale.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-omega-scale.rds new file mode 100644 index 00000000..7195f5fd Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-omega-scale.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-omega-std.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-omega-std.rds new file mode 100644 index 00000000..a7133326 Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-omega-std.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-omega-tp.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-omega-tp.rds new file mode 100644 index 00000000..927ebfc0 Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/coefficient-omega-tp.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/cronbach-s-alpha-item-mean-ordered.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/cronbach-s-alpha-item-mean-ordered.rds new file mode 100644 index 00000000..985312b2 Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/cronbach-s-alpha-item-mean-ordered.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/guttman-s-lambda2-item.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/guttman-s-lambda2-item.rds new file mode 100644 index 00000000..c3ad1b05 Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/guttman-s-lambda2-item.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/guttman-s-lambda2-scale.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/guttman-s-lambda2-scale.rds new file mode 100644 index 00000000..f78354ac Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/guttman-s-lambda2-scale.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/guttman-s-lambda2-std.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/guttman-s-lambda2-std.rds new file mode 100644 index 00000000..fda3e296 Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/guttman-s-lambda2-std.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/guttman-s-lambda2-tp.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/guttman-s-lambda2-tp.rds new file mode 100644 index 00000000..56b11c21 Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/guttman-s-lambda2-tp.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/lambda2-prior-adjusted.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/lambda2-prior-adjusted.rds new file mode 100644 index 00000000..40619046 Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/lambda2-prior-adjusted.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/omega-prior-adjusted.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/omega-prior-adjusted.rds new file mode 100644 index 00000000..7f086ecb Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/omega-prior-adjusted.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/posterior-predictive-check-omega.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/posterior-predictive-check-omega.rds new file mode 100644 index 00000000..0b29f26f Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/posterior-predictive-check-omega.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/split-half-coefficient-item.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/split-half-coefficient-item.rds new file mode 100644 index 00000000..db2ec6fb Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/split-half-coefficient-item.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/split-half-coefficient-scale.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/split-half-coefficient-scale.rds new file mode 100644 index 00000000..89db9cfc Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/split-half-coefficient-scale.rds differ diff --git a/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/split-half-coefficient-tp.rds b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/split-half-coefficient-tp.rds new file mode 100644 index 00000000..fe294179 Binary files /dev/null and b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/reference_plotobject/split-half-coefficient-tp.rds differ diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/split-half-coefficient-item.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/split-half-coefficient-item.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/split-half-coefficient-item.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/split-half-coefficient-item.svg diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/split-half-coefficient-scale.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/split-half-coefficient-scale.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/split-half-coefficient-scale.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/split-half-coefficient-scale.svg diff --git a/tests/testthat/_snaps/unidimensionalReliabilityBayesian/split-half-coefficient-tp.svg b/tests/testthat/_snaps/reliabilityUnidimensionalBayesian/split-half-coefficient-tp.svg similarity index 100% rename from tests/testthat/_snaps/unidimensionalReliabilityBayesian/split-half-coefficient-tp.svg rename to tests/testthat/_snaps/reliabilityUnidimensionalBayesian/split-half-coefficient-tp.svg diff --git a/tests/testthat/_snaps/standardErrorOfMeasurement/reference_plotobject/anova-ci-plot.rds b/tests/testthat/_snaps/standardErrorOfMeasurement/reference_plotobject/anova-ci-plot.rds new file mode 100644 index 00000000..752ab410 Binary files /dev/null and b/tests/testthat/_snaps/standardErrorOfMeasurement/reference_plotobject/anova-ci-plot.rds differ diff --git a/tests/testthat/_snaps/standardErrorOfMeasurement/reference_plotobject/feldt-ci-plot.rds b/tests/testthat/_snaps/standardErrorOfMeasurement/reference_plotobject/feldt-ci-plot.rds new file mode 100644 index 00000000..db7b5a27 Binary files /dev/null and b/tests/testthat/_snaps/standardErrorOfMeasurement/reference_plotobject/feldt-ci-plot.rds differ diff --git a/tests/testthat/_snaps/standardErrorOfMeasurement/reference_plotobject/keats-ci-plot.rds b/tests/testthat/_snaps/standardErrorOfMeasurement/reference_plotobject/keats-ci-plot.rds new file mode 100644 index 00000000..418a8c46 Binary files /dev/null and b/tests/testthat/_snaps/standardErrorOfMeasurement/reference_plotobject/keats-ci-plot.rds differ diff --git a/tests/testthat/test-library-ASRM - Mania Scale.R b/tests/testthat/test-library-ASRM - Mania Scale.R index 7217b24d..52923794 100644 --- a/tests/testthat/test-library-ASRM - Mania Scale.R +++ b/tests/testthat/test-library-ASRM - Mania Scale.R @@ -3,7 +3,7 @@ context("Library: ASRM - Mania Scale") # This test file was auto-generated from a JASP example file. # The JASP file is stored in tests/testthat/jaspfiles/library/. -test_that("unidimensionalReliabilityBayesian results match", { +test_that("reliabilityUnidimensionalBayesian results match", { # Load from JASP example file jaspFile <- testthat::test_path("jaspfiles", "library", "ASRM - Mania Scale.jasp") @@ -13,7 +13,7 @@ test_that("unidimensionalReliabilityBayesian results match", { # Encode and run analysis encoded <- jaspTools:::encodeOptionsAndDataset(opts, dataset) set.seed(1) - results <- jaspTools::runAnalysis("unidimensionalReliabilityBayesian", encoded$dataset, encoded$options, encodedDataset = TRUE) + results <- jaspTools::runAnalysis("reliabilityUnidimensionalBayesian", encoded$dataset, encoded$options, encodedDataset = TRUE) table <- results[["results"]][["stateContainer"]][["collection"]][["stateContainer_itemTable"]][["data"]] jaspTools::expect_equal_tables(table, diff --git a/tests/testthat/test-library-Fear of Statistics.R b/tests/testthat/test-library-Fear of Statistics.R index 3efe2293..79f234e0 100644 --- a/tests/testthat/test-library-Fear of Statistics.R +++ b/tests/testthat/test-library-Fear of Statistics.R @@ -3,7 +3,7 @@ context("Library: Fear of Statistics") # This test file was auto-generated from a JASP example file. # The JASP file is stored in tests/testthat/jaspfiles/library/. -test_that("unidimensionalReliabilityFrequentist results match", { +test_that("reliabilityUnidimensionalFrequentist results match", { # Load from JASP example file jaspFile <- testthat::test_path("jaspfiles", "library", "Fear of Statistics.jasp") @@ -13,7 +13,7 @@ test_that("unidimensionalReliabilityFrequentist results match", { # Encode and run analysis encoded <- jaspTools:::encodeOptionsAndDataset(opts, dataset) set.seed(1) - results <- jaspTools::runAnalysis("unidimensionalReliabilityFrequentist", encoded$dataset, encoded$options, encodedDataset = TRUE) + results <- jaspTools::runAnalysis("reliabilityUnidimensionalFrequentist", encoded$dataset, encoded$options, encodedDataset = TRUE) table <- results[["results"]][["stateContainer"]][["collection"]][["stateContainer_itemTable"]][["data"]] jaspTools::expect_equal_tables(table, diff --git a/tests/testthat/test-reliabilityMultidimensionalBayesian.R b/tests/testthat/test-reliabilityMultidimensionalBayesian.R new file mode 100644 index 00000000..0115198d --- /dev/null +++ b/tests/testthat/test-reliabilityMultidimensionalBayesian.R @@ -0,0 +1,113 @@ + +# 2-factor second-order model on the Reliability example data, with one crossloading +# item (Question_12 loads on both factors) +f1 <- paste0("Question_", sprintf("%02d", 1:12)) +f2 <- paste0("Question_", sprintf("%02d", 12:23)) + +options <- analysisOptions("reliabilityMultidimensionalBayesian") +options$factors <- list( + list(indicators = f1, name = "Factor1", title = "Factor 1"), + list(indicators = f2, name = "Factor2", title = "Factor 2") +) +options$modelType <- "secondOrder" +# scale coefficients are always displayed; item statistics are opt-in +options$itemRestCor <- TRUE +options$probTable <- TRUE +options$probTableValueLow <- 0.7 +options$probTableValueHigh <- 0.9 +options$noSamples <- 200 +options$noBurnin <- 50 +options$noChains <- 2 +options$rHat <- TRUE +options$setSeed <- TRUE +options$seed <- 1 +options$fitMeasures <- TRUE +set.seed(1) +results <- runAnalysis("reliabilityMultidimensionalBayesian", testthat::test_path("Reliability.csv"), options, makeTests = FALSE) + +test_that("Analysis completes without errors", { + expect_equal(results[["status"]], "complete") +}) + +test_that("Bayesian Scale Reliability Statistics table results match", { + table <- results[["results"]][["stateContainer"]][["collection"]][["stateContainer_scaleTable"]][["data"]] + jaspTools::expect_equal_tables(table, + list("McDonald's ", 0.7788594113243, 0.7655848422395, + 0.998727899094338, 0.791322733994566, "McDonald's ", + 0.757721516474659, 0.741581961183294, 1.00323445815622, 0.771598841259063, + "Average interitem correlation", 0.130074006470925, "", "", + "", "Mean", 61.437183975107, "", "", "", "SD", 9.01983558246063, + "", "", "")) +}) + +test_that("Bayesian Individual Item Reliability Statistics table results match", { + table <- results[["results"]][["stateContainer"]][["collection"]][["stateContainer_itemTable"]][["data"]] + jaspTools::expect_equal_tables(table, + list("Question_01", 0.491798910912644, "Question_02", -0.105371122635483, + "Question_03", -0.434761937472932, "Question_04", 0.533243866223406, + "Question_05", 0.453605309151933, "Question_06", 0.477809305171136, + "Question_07", 0.559884251471989, "Question_08", 0.493112167091624, + "Question_09", -0.0811768317813592, "Question_10", 0.345790483737811, + "Question_11", 0.540473158732128, "Question_12", 0.518535898276985, + "Question_13", 0.558606070855461, "Question_14", 0.528139241251555, + "Question_15", 0.457047628630301, "Question_16", 0.524877464899673, + "Question_17", 0.568384535026814, "Question_18", 0.578263548919627, + "Question_19", -0.247956846021939, "Question_20", 0.265420749483938, + "Question_21", 0.514201155527712, "Question_22", -0.120800284171491, + "Question_23", -0.0127987366827629)) +}) + +test_that("Probability table results match", { + table <- results[["results"]][["stateContainer"]][["collection"]][["stateContainer_probabilityTable"]][["data"]] + jaspTools::expect_equal_tables(table, + list("McDonald's ", 1, "McDonald's ", 1)) +}) + +test_that("Fit measures table results match", { + table <- results[["results"]][["stateContainer"]][["collection"]][["stateContainer_fitTable"]][["data"]] + jaspTools::expect_equal_tables(table, + list("Point estimate", 4494.12650123064, 0.089187044699341, 0.063017234802653, + "90% CI lower bound", "", 0.0888221787024989, 0.0641069635806036, + "90% CI upper bound", "", 0.0895624113228447, 0.0688465705668997, + "Relative to cutoff", "", 0, "")) +}) + + +# correlated-factors model: McDonald's omega_h is undefined and must be dropped with a footnote +optionsCorr <- options +optionsCorr$modelType <- "correlated" +set.seed(1) +resultsCorr <- runAnalysis("reliabilityMultidimensionalBayesian", "Reliability.csv", optionsCorr, makeTests = FALSE) + +test_that("Correlated model omits omega_h and adds a footnote", { + scaleTable <- resultsCorr[["results"]][["stateContainer"]][["collection"]][["stateContainer_scaleTable"]] + coefficients <- vapply(scaleTable[["data"]], function(x) x[["coefficient"]], character(1)) + expect_false(any(grepl("ωₕ", coefficients))) # no McDonald's omega_h row + expect_true(length(scaleTable[["footnotes"]]) >= 1) +}) + + +# omega-if-item-deleted: per-item refit. Use 2 factors x 3 items so dropping an item leaves valid +# (2-item) factors and every item yields a refit value. +optionsDel <- analysisOptions("reliabilityMultidimensionalBayesian") +optionsDel$factors <- list( + list(indicators = paste0("Question_", sprintf("%02d", 1:3)), name = "Factor1", title = "Factor 1"), + list(indicators = paste0("Question_", sprintf("%02d", 4:6)), name = "Factor2", title = "Factor 2") +) +optionsDel$modelType <- "secondOrder" +optionsDel$itemDeletedOmegaT <- TRUE +optionsDel$itemDeletedOmegaH <- TRUE +optionsDel$noSamples <- 100 +optionsDel$noBurnin <- 30 +optionsDel$noChains <- 2 +optionsDel$setSeed <- TRUE +optionsDel$seed <- 1 +set.seed(1) +resultsDel <- runAnalysis("reliabilityMultidimensionalBayesian", "Reliability.csv", optionsDel, makeTests = FALSE) + +test_that("Omega-if-item-deleted produces a populated item table", { + itemTable <- resultsDel[["results"]][["stateContainer"]][["collection"]][["stateContainer_itemTable"]][["data"]] + expect_equal(length(itemTable), 6L) # one row per item + omtDropped <- vapply(itemTable, function(x) x[["omegaT"]], numeric(1)) + expect_true(all(is.finite(omtDropped))) # every item refit succeeded +}) diff --git a/tests/testthat/test-unidimensionalReliabilityBayesian.R b/tests/testthat/test-reliabilityUnidimensionalBayesian.R similarity index 96% rename from tests/testthat/test-unidimensionalReliabilityBayesian.R rename to tests/testthat/test-reliabilityUnidimensionalBayesian.R index 76f31440..e425a492 100644 --- a/tests/testthat/test-unidimensionalReliabilityBayesian.R +++ b/tests/testthat/test-reliabilityUnidimensionalBayesian.R @@ -1,6 +1,6 @@ # common options -options <- analysisOptions("unidimensionalReliabilityBayesian") +options <- analysisOptions("reliabilityUnidimensionalBayesian") options$variables <- c("contNormal", "contcor1", "contcor2", "facFive", "debMiss30") # options$variables.types <- c("scale", "scale", "scale", "scale", "scale") options$scaleAlpha <- TRUE @@ -40,7 +40,7 @@ options$itemDeletedPlotOrderedType <- "kullbackLeibler" options$inverseWishartPriorDf <- length(options$variables) options$inverseWishartPriorScale <- 0.0000000001 set.seed(1) -results <- runAnalysis("unidimensionalReliabilityBayesian", "test.csv", options, makeTests = F) +results <- runAnalysis("reliabilityUnidimensionalBayesian", "test.csv", options, makeTests = F) test_that("Bayesian Individual Item Reliability Statistics table results match", { table <- results[["results"]][["stateContainer"]][["collection"]][["stateContainer_itemTable"]][["data"]] @@ -173,7 +173,7 @@ test_that("Bayesian Scale Reliability Statistics table results match", { # disabled sample saving -options <- analysisOptions("unidimensionalReliabilityBayesian") +options <- analysisOptions("reliabilityUnidimensionalBayesian") options$variables <- c("contNormal", "contcor1", "contcor2", "facFive", "debMiss30") options$scaleAlpha <- TRUE options$scaleLambda2 <- TRUE @@ -185,7 +185,7 @@ options$inverseWishartPriorDf <- length(options$variables) options$inverseWishartPriorScale <- 0.0000000001 set.seed(1) -results <- runAnalysis("unidimensionalReliabilityBayesian", "test.csv", options, makeTests = F) +results <- runAnalysis("reliabilityUnidimensionalBayesian", "test.csv", options, makeTests = F) test_that("Bayesian Scale Reliability Statistics table results match", { table <- results[["results"]][["stateContainer"]][["collection"]][["stateContainer_scaleTable"]][["data"]] jaspTools::expect_equal_tables(table, @@ -198,7 +198,7 @@ jaspTools::expect_equal_tables(table, # adjusted priors -options <- analysisOptions("unidimensionalReliabilityBayesian") +options <- analysisOptions("reliabilityUnidimensionalBayesian") options$variables <- c("asrm_1", "asrm_2", "asrm_3", "asrm_4", "asrm_5") options$scaleOmega <- TRUE options$scaleLambda2 <- TRUE @@ -225,7 +225,7 @@ options$inverseGammaPriorScale <- 10 options$normalPriorMean <- 1 set.seed(1) -results <- runAnalysis("unidimensionalReliabilityBayesian", testthat::test_path("asrm_mis.csv"), options, makeTests =F) +results <- runAnalysis("reliabilityUnidimensionalBayesian", testthat::test_path("asrm_mis.csv"), options, makeTests =F) test_that("Bayesian Individual Item Reliability Statistics table results match", { table <- results[["results"]][["stateContainer"]][["collection"]][["stateContainer_itemTable"]][["data"]] @@ -278,7 +278,7 @@ test_that("Bayesian Scale Reliability Statistics table results match", { # standardization and median -options <- analysisOptions("unidimensionalReliabilityBayesian") +options <- analysisOptions("reliabilityUnidimensionalBayesian") options$variables <- c("contNormal", "contcor1", "contcor2", "facFive") options$scaleAlpha <- TRUE options$scaleLambda2 <- TRUE @@ -301,7 +301,7 @@ options$standardizedLoadings <- TRUE options$coefficientType <- "standardized" options$pointEstimate <- "median" set.seed(1) -results <- runAnalysis("unidimensionalReliabilityBayesian", "test.csv", options, makeTests = FALSE) +results <- runAnalysis("reliabilityUnidimensionalBayesian", "test.csv", options, makeTests = FALSE) test_that("Bayesian Individual Item Reliability Statistics table results match", { table <- results[["results"]][["stateContainer"]][["collection"]][["stateContainer_itemTable"]][["data"]] @@ -370,7 +370,7 @@ test_that("Bayesian Scale Reliability Statistics table results match", { # fit indices # results were compared to blavFitIndices and lavaan omegaFitMeasures with the same data but 2000 obs -options <- analysisOptions("unidimensionalReliabilityBayesian") +options <- analysisOptions("reliabilityUnidimensionalBayesian") options$variables <- c("asrm_1", "asrm_2", "asrm_3", "asrm_4", "asrm_5") options$scaleOmega <- TRUE options$samples <- 200 @@ -382,7 +382,7 @@ options$omegaFitMeasuresCutoffCfiTli <- .85 options$omegaPosteriorPredictiveCheck <- TRUE set.seed(1) -results <- runAnalysis("unidimensionalReliabilityBayesian", testthat::test_path("asrm.csv"), options) +results <- runAnalysis("reliabilityUnidimensionalBayesian", testthat::test_path("asrm.csv"), options) test_that("Fit Measures for the Single-Factor Model table results match", { table <- results[["results"]][["stateContainer"]][["collection"]][["stateContainer_fitTable"]][["data"]] @@ -402,7 +402,7 @@ test_that("Posterior Predictive Check Omega plot matches", { # item plot ordered by mean -options <- analysisOptions("unidimensionalReliabilityBayesian") +options <- analysisOptions("reliabilityUnidimensionalBayesian") options$variables <- c("contNormal", "contcor1", "contcor2", "facFive", "debMiss30") options$scaleAlpha <- TRUE options$itemDeletedAlpha <- TRUE @@ -414,7 +414,7 @@ options$inverseWishartPriorScale <- 0.0000000001 options$samples <- 200 options$chains <- 2 set.seed(1) -results <- runAnalysis("unidimensionalReliabilityBayesian", "test.csv", options) +results <- runAnalysis("reliabilityUnidimensionalBayesian", "test.csv", options) test_that("Cronbach's alpha plot item deleted plot matches ordered by mean", { plotName <- results[["results"]][["stateContainer"]][["collection"]][["stateContainer_plotContainerItem"]][["collection"]][["stateContainer_plotContainerItem_alpha"]][["data"]] diff --git a/tests/testthat/test-unidimensionalReliabilityFrequentist.R b/tests/testthat/test-reliabilityUnidimensionalFrequentist.R similarity index 96% rename from tests/testthat/test-unidimensionalReliabilityFrequentist.R rename to tests/testthat/test-reliabilityUnidimensionalFrequentist.R index 6204f78b..6a12c125 100644 --- a/tests/testthat/test-unidimensionalReliabilityFrequentist.R +++ b/tests/testthat/test-reliabilityUnidimensionalFrequentist.R @@ -1,5 +1,5 @@ # analytic confidence interval -options <- analysisOptions("unidimensionalReliabilityFrequentist") +options <- analysisOptions("reliabilityUnidimensionalFrequentist") options$scaleOmega <- FALSE options$itemDeletedAlpha <- TRUE options$scaleAlpha <- TRUE @@ -20,7 +20,7 @@ options$setSeed <- TRUE options$hiddenScaleThreshold <- 10 options$variables <- c("asrm_1", "asrm_2", "asrm_3", "asrm_4", "asrm_5") set.seed(1) -results <- runAnalysis("unidimensionalReliabilityFrequentist", testthat::test_path("asrm.csv"), options, makeTests = F) +results <- runAnalysis("reliabilityUnidimensionalFrequentist", testthat::test_path("asrm.csv"), options, makeTests = F) test_that("Frequentist Individual Item Reliability Statistics table results match", { @@ -65,7 +65,7 @@ test_that("Frequentist Scale Reliability Statistics table results match", { }) # special options test -options <- analysisOptions("unidimensionalReliabilityFrequentist") +options <- analysisOptions("reliabilityUnidimensionalFrequentist") options$intervalMethod <- "bootstrapped" options$itemDeletedAlpha <- TRUE options$scaleAlpha <- TRUE @@ -89,7 +89,7 @@ options$setSeed <- TRUE options$hiddenScaleThreshold <- 10 options$variables <- c("contNormal", "contcor1", "contcor2", "debMiss30") set.seed(1) -results <- runAnalysis("unidimensionalReliabilityFrequentist", "test.csv", options, makeTests = F) +results <- runAnalysis("reliabilityUnidimensionalFrequentist", "test.csv", options, makeTests = F) test_that("Frequentist Individual Item Reliability Statistics table results match", { table <- results[["results"]][["stateContainer"]][["collection"]][["stateContainer_itemTable"]][["data"]] @@ -138,7 +138,7 @@ test_that("Frequentist Scale Reliability Statistics table results match", { # omega test -options <- analysisOptions("unidimensionalReliabilityFrequentist") +options <- analysisOptions("reliabilityUnidimensionalFrequentist") options$omegaFitMeasures <- TRUE options$bootstrapSamples <- 100 options$intervalMethod <- "bootstrapped" @@ -151,7 +151,7 @@ options$hiddenScaleThreshold <- 10 options$variables <- c("asrm_1", "asrm_2", "asrm_3", "asrm_4", "asrm_5") options$setSeed <- TRUE set.seed(1) -results <- runAnalysis("unidimensionalReliabilityFrequentist", testthat::test_path("asrm_mis.csv"), options, +results <- runAnalysis("reliabilityUnidimensionalFrequentist", testthat::test_path("asrm_mis.csv"), options, makeTests = F) test_that("Fit Measures of Single Factor Model Fit table results match", { @@ -188,7 +188,7 @@ test_that("Standardized Loadings of the Single-Factor Model table results match" # standardized coefficients work -options <- analysisOptions("unidimensionalReliabilityFrequentist") +options <- analysisOptions("reliabilityUnidimensionalFrequentist") options$itemDeletedAlpha <- TRUE options$scaleAlpha <- TRUE options$ciLevel <- 0.9 @@ -205,7 +205,7 @@ options$setSeed <- TRUE options$hiddenScaleThreshold <- 10 options$variables <- c("asrm_1", "asrm_2", "asrm_3", "asrm_4") set.seed(1) -results <- runAnalysis("unidimensionalReliabilityFrequentist", testthat::test_path("asrm.csv"), options, +results <- runAnalysis("reliabilityUnidimensionalFrequentist", testthat::test_path("asrm.csv"), options, makeTests = F) test_that("Frequentist Individual Item Reliability Statistics table results match", { @@ -236,7 +236,7 @@ test_that("Frequentist Scale Reliability Statistics table results match", { # check lambda2 analytic confidence interval -options <- analysisOptions("unidimensionalReliabilityFrequentist") +options <- analysisOptions("reliabilityUnidimensionalFrequentist") options$intervalMethod <- "analytic" options$scaleOmega <- FALSE options$itemDeletedLambda2 <- TRUE @@ -245,7 +245,7 @@ options$setSeed <- TRUE options$variables <- c("contNormal", "contcor1", "contcor2") options$hiddenScaleThreshold <- 10 set.seed(1) -results <- runAnalysis("unidimensionalReliabilityFrequentist", "test.csv", options, makeTests = F) +results <- runAnalysis("reliabilityUnidimensionalFrequentist", "test.csv", options, makeTests = F) test_that("Frequentist Individual Item Reliability Statistics table results match", { table <- results[["results"]][["stateContainer"]][["collection"]][["stateContainer_itemTable"]][["data"]] diff --git a/tests/testthat/test-verified-unidimensionalReliabilityFrequentist.R b/tests/testthat/test-verified-reliabilityUnidimensionalFrequentist.R similarity index 97% rename from tests/testthat/test-verified-unidimensionalReliabilityFrequentist.R rename to tests/testthat/test-verified-reliabilityUnidimensionalFrequentist.R index cddcca20..f3a902d6 100644 --- a/tests/testthat/test-verified-unidimensionalReliabilityFrequentist.R +++ b/tests/testthat/test-verified-reliabilityUnidimensionalFrequentist.R @@ -1,6 +1,6 @@ context("Unidimensional Reliability Frequentist -- Verification project") -options <- analysisOptions("unidimensionalReliabilityFrequentist") +options <- analysisOptions("reliabilityUnidimensionalFrequentist") options$scaleOmega <- TRUE options$scaleAlpha <- TRUE options$scaleLambda2 <- TRUE @@ -19,7 +19,7 @@ options$variables <- c(paste("Question", c(1, 4:8), sep="_0"), paste("Question", 10, sep="_")) set.seed(1) -results <- jaspTools::runAnalysis("unidimensionalReliabilityFrequentist", +results <- jaspTools::runAnalysis("reliabilityUnidimensionalFrequentist", testthat::test_path("Reliability.csv"), options, makeTests = F) test_that("Main (scale) table results match R, SPSS, SAS and MiniTab", {