|
408 | 408 | state <- .irtIRTState(dataset, options, jaspResults) |
409 | 409 | } |
410 | 410 | plotdata <- state[["plotDataTestInformation"]] |
411 | | - xBreaks <- jaspGraphs::getPrettyAxisBreaks(c(-6, 6), min.n = 4) |
412 | | - yBreaks <- jaspGraphs::getPrettyAxisBreaks(c(0, subset(plotdata$y, plotdata$x >= -6 & plotdata$x <= 6)), min.n = 4) |
| 411 | + xBreaks <- jaspGraphs::getPrettyAxisBreaks(c(-3, 3), min.n = 4) |
| 412 | + yBreaks <- jaspGraphs::getPrettyAxisBreaks(c(0, subset(plotdata$y, plotdata$x >= -3 & plotdata$x <= 3)), min.n = 4) |
413 | 413 | p <- ggplot2::ggplot(data = plotdata, mapping = ggplot2::aes(x = x, y = y, color = type)) + |
414 | 414 | ggplot2::geom_line() + |
415 | 415 | ggplot2::scale_x_continuous(name = "\u03B8", breaks = xBreaks, limits = range(xBreaks)) + |
|
444 | 444 | } |
445 | 445 | plotdata <- state[["plotDataItemInformation"]] |
446 | 446 | plotdata <- subset(plotdata, plotdata$item %in% match(options[["plotItemInformationItems"]], options[["items"]])) |
447 | | - xBreaks <- jaspGraphs::getPrettyAxisBreaks(c(-6, 6), min.n = 4) |
448 | | - yBreaks <- jaspGraphs::getPrettyAxisBreaks(c(0, subset(plotdata$y, plotdata$x >= -6 & plotdata$x <= 6)), min.n = 4) |
| 447 | + xBreaks <- jaspGraphs::getPrettyAxisBreaks(c(-3, 3), min.n = 4) |
| 448 | + yBreaks <- jaspGraphs::getPrettyAxisBreaks(c(0, subset(plotdata$y, plotdata$x >= -3 & plotdata$x <= 3)), min.n = 4) |
449 | 449 | colors <- colorspace::qualitative_hcl(length(options[["plotItemInformationItems"]])) |
450 | 450 | p <- ggplot2::ggplot(data = plotdata, mapping = ggplot2::aes(x = x, y = y, col = factor(item))) + |
451 | 451 | ggplot2::geom_line() + |
|
482 | 482 | object <- createJaspContainer(title = gettext("Item Characteristic Curves")) |
483 | 483 | } |
484 | 484 | object$position <- position + 1 |
485 | | - object$dependOn(options = c(.irtCommonDeps(type = "irt"), "plotItemCharacteristicItems", "plotItemCharacteristicLabels")) |
| 485 | + object$dependOn(options = c(.irtCommonDeps(type = "irt"), "plotItemCharacteristicItems", "plotItemCharacteristicLabels", "plotItemCharacteristicFromX", "plotItemCharacteristicToX")) |
486 | 486 | jaspResults[["plotItemCharacteristic"]] <- object |
487 | 487 | if (!ready) { |
488 | 488 | return() |
|
492 | 492 | } else { |
493 | 493 | state <- .irtIRTState(dataset, options, jaspResults) |
494 | 494 | } |
495 | | - xBreaks <- jaspGraphs::getPrettyAxisBreaks(c(-6, 6), min.n = 4) |
| 495 | + xBreaks <- jaspGraphs::getPrettyAxisBreaks(c(options[["plotItemCharacteristicFromX"]], options[["plotItemCharacteristicToX"]]), min.n = 4) |
496 | 496 | if (options[["plotItemCharacteristicGroup"]]) { |
497 | 497 | plotdata <- state[["plotDataItemCharacteristic"]] |
498 | 498 | plotdata <- subset(plotdata, plotdata$item %in% match(options[["plotItemCharacteristicItems"]], options[["items"]])) |
|
904 | 904 | result <- list(model = model, data = data, pars = pars) |
905 | 905 | return(result) |
906 | 906 | } |
| 907 | + |
| 908 | +.irtDifAnalysisTable <- function(dataset, options, jaspResults, ready, position) { |
| 909 | + if (options[["explanatoryText"]] && options[["tableDifAnalysis"]]) { |
| 910 | + text <- createJaspHtml(gettext("<h3>Explanatory Text: Differential Item Functioning (DIF)</h3> The table below presents the results of a Differential Item Functioning (DIF) analysis. A DIF-analysis is conducted to assess whether specific items perform differently across groups while controlling for overall ability or trait levels. This ensures that the items are fair and not biased toward any particular group.")) |
| 911 | + text$position <- position |
| 912 | + text$dependOn(options = c("explanatoryText", "tableDifAnalysis")) |
| 913 | + jaspResults[["tableDifAnalysisText"]] <- text |
| 914 | + } |
| 915 | + if (!is.null(jaspResults[["tableDifAnalysis"]]) || !options[["tableDifAnalysis"]]) { |
| 916 | + return() |
| 917 | + } |
| 918 | + tb <- createJaspTable(title = gettext("Differential Item Functioning (DIF)")) |
| 919 | + tb$position <- position + 1 |
| 920 | + tb$addColumnInfo(name = "item", title = gettext("Item"), type = "string") |
| 921 | + tb$addColumnInfo(name = "aic", title = gettext("AIC"), type = "number") |
| 922 | + tb$addColumnInfo(name = "sabic", title = gettext("SABIC"), type = "number") |
| 923 | + tb$addColumnInfo(name = "hq", title = gettext("HQ"), type = "number") |
| 924 | + tb$addColumnInfo(name = "bic", title = gettext("BIC"), type = "number") |
| 925 | + tb$addColumnInfo(name = "x2", title = gettext("X2"), type = "number") |
| 926 | + tb$addColumnInfo(name = "df", title = gettext("df"), type = "integer") |
| 927 | + tb$addColumnInfo(name = "p", title = gettext("p"), type = "pvalue") |
| 928 | + tb$dependOn(options = c(.irtCommonDeps(type = "irt"), "tableDifAnalysis", "groupingVariable", "tableDifAnalysisDifficulty", "tableDifAnalysisDiscrimination", "tableDifAnalysisGuess", "tableDifAnalysisSlip")) |
| 929 | + tb$addFootnote(gettext("For each item, the null hypothesis specifies that there is no DIF between the groups.")) |
| 930 | + tb$addFootnote(gettext("p-values are not adjusted for multiple comparisons."), colName = "p") |
| 931 | + if (length(options[["covariates"]]) > 0) { |
| 932 | + tb$addFootnote(gettext("The latent regressions present in the ungrouped model are not included in this analysis.")) |
| 933 | + } |
| 934 | + jaspResults[["tableDifAnalysis"]] <- tb |
| 935 | + if (!ready || options[["groupingVariable"]] == "") { |
| 936 | + return() |
| 937 | + } |
| 938 | + state <- .irtIRTStateBayesian(dataset, options, jaspResults) |
| 939 | + parameters <- character() |
| 940 | + if (options[["dichotomous"]]) { |
| 941 | + if (options[["tableDifAnalysisDifficulty"]]) { |
| 942 | + parameters <- c(parameters, "d") |
| 943 | + } |
| 944 | + if (options[["tableDifAnalysisDiscrimination"]] && options[["model"]] %in% c("2PL", "3PL", "4PL")) { |
| 945 | + parameters <- c(parameters, "a1") |
| 946 | + } |
| 947 | + if (options[["tableDifAnalysisGuess"]] && options[["model"]] %in% c("3PL", "4PL")) { |
| 948 | + parameters <- c(parameters, "g") |
| 949 | + } |
| 950 | + if (options[["tableDifAnalysisSlip"]] && options[["model"]] == "4PL") { |
| 951 | + parameters <- c(parameters, "u") |
| 952 | + } |
| 953 | + } else { |
| 954 | + all_parameters <- colnames(state[["coefficients"]]) |
| 955 | + if (options[["tableDifAnalysisDifficulty"]]) { |
| 956 | + if (options[["model"]] %in% c("rsm", "grsm")) { |
| 957 | + parameters <- c(parameters, "c") |
| 958 | + } else if (options[["model"]] == "nominal") { |
| 959 | + colnames_diff <- colnames(state[["coefficients"]])[grep("c", colnames(state[["coefficients"]]))] |
| 960 | + colnames_diff <- gsub("c", "", colnames_diff) |
| 961 | + colnames_diff <- paste0("d", as.numeric(colnames_diff) - 1) |
| 962 | + parameters <- c(parameters, colnames_diff) |
| 963 | + } else { |
| 964 | + colnames_diff <- colnames(state[["coefficients"]])[grep("b", colnames(state[["coefficients"]]))] |
| 965 | + colnames_diff <- gsub("b", "d", colnames_diff) |
| 966 | + parameters <- c(parameters, colnames_diff) |
| 967 | + } |
| 968 | + } |
| 969 | + if (options[["tableDifAnalysisDiscrimination"]] && options[["model"]] %in% c("gpcm", "grsm", "graded", "nominal")) { |
| 970 | + if (options[["model"]] == "nominal") { |
| 971 | + colnames_disc <- colnames(state[["coefficients"]])[grep("a", colnames(state[["coefficients"]]))] |
| 972 | + colnames_disc <- gsub("a", "", colnames_disc) |
| 973 | + colnames_disc <- paste0("ak", as.numeric(colnames_disc) - 1) |
| 974 | + parameters <- c(parameters, colnames_disc) |
| 975 | + } else { |
| 976 | + parameters <- c(parameters, "a1") |
| 977 | + } |
| 978 | + } |
| 979 | + if (options[["tableDifAnalysisThreshold"]] && options[["model"]] %in% c("rsm", "grsm")) { |
| 980 | + colnames_tresh <- colnames(state[["coefficients"]])[grep("b", colnames(state[["coefficients"]]))] |
| 981 | + parameters <- c(parameters, colnames_tresh) |
| 982 | + } |
| 983 | + } |
| 984 | + if (length(parameters) == 0) { |
| 985 | + tb$setError(gettext("DIf-analysis not possible: Select at least one parameter to test.")) |
| 986 | + return() |
| 987 | + } |
| 988 | + result <- try({ |
| 989 | + fit <- mirt::multipleGroup(data = state[["items"]], model = 1, itemtype = options[["model"]], group = dataset[[options[["groupingVariable"]]]], SE = FALSE, verbose = FALSE, TOL = options[["emTolerance"]], technical = list(NCYCLES = options[["emIterations"]], set.seed = options[["seed"]])) |
| 990 | + dif <- mirt::DIF(fit, which.par = parameters) |
| 991 | + }) |
| 992 | + if (jaspBase:::isTryError(result)) { |
| 993 | + tb$setError(jaspBase:::.extractErrorMessage(result)) |
| 994 | + return() |
| 995 | + } |
| 996 | + tb[["item"]] <- options[["items"]] |
| 997 | + tb[["aic"]] <- dif[["AIC"]] |
| 998 | + tb[["sabic"]] <- dif[["SABIC"]] |
| 999 | + tb[["hq"]] <- dif[["HQ"]] |
| 1000 | + tb[["bic"]] <- dif[["BIC"]] |
| 1001 | + tb[["x2"]] <- dif[["X2"]] |
| 1002 | + tb[["df"]] <- dif[["df"]] |
| 1003 | + tb[["p"]] <- dif[["p"]] |
| 1004 | +} |
0 commit comments