diff --git a/DESCRIPTION b/DESCRIPTION index 3b0e2f0..73d0171 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: rpact Title: Confirmatory Adaptive Clinical Trial Design and Analysis -Version: 4.0.1.9264 -Date: 2024-09-26 +Version: 4.1.0 +Date: 2024-09-27 Authors@R: c( person( given = "Gernot", diff --git a/R/class_simulation_results.R b/R/class_simulation_results.R index c254783..4d22bab 100644 --- a/R/class_simulation_results.R +++ b/R/class_simulation_results.R @@ -13,8 +13,8 @@ ## | ## | Contact us for information about our services: info@rpact.com ## | -## | File version: $Revision: 8232 $ -## | Last changed: $Date: 2024-09-19 08:22:37 +0200 (Do, 19 Sep 2024) $ +## | File version: $Revision: 8277 $ +## | Last changed: $Date: 2024-09-27 08:16:45 +0200 (Fr, 27 Sep 2024) $ ## | Last changed by: $Author: pahlke $ ## | @@ -567,6 +567,9 @@ SimulationResults <- R6::R6Class("SimulationResults", "numberOfPopulations", "expectedNumberOfSubjects", "expectedNumberOfEvents", + "numberOfSubjects", + "numberOfSubjects1", + "numberOfSubjects2", "sampleSizes", "singleEventsPerArmAndStage", "singleEventsPerSubsetAndStage", @@ -1708,10 +1711,10 @@ SimulationResultsCountData <- R6::R6Class("SimulationResultsCountData", accrualIntensity = NULL, followUpTime = NULL, groups = NULL, + expectedNumberOfSubjects = NULL, numberOfSubjects = NULL, numberOfSubjects1 = NULL, numberOfSubjects2 = NULL, - expectedNumberOfSubjects = NULL, iterations = NULL, futilityStop = NULL, futilityPerStage = NULL, diff --git a/R/class_summary.R b/R/class_summary.R index 63aebf6..369e53b 100644 --- a/R/class_summary.R +++ b/R/class_summary.R @@ -13,8 +13,8 @@ ## | ## | Contact us for information about our services: info@rpact.com ## | -## | File version: $Revision: 8276 $ -## | Last changed: $Date: 2024-09-26 13:37:54 +0200 (Do, 26 Sep 2024) $ +## | File version: $Revision: 8277 $ +## | Last changed: $Date: 2024-09-27 08:16:45 +0200 (Fr, 27 Sep 2024) $ ## | Last changed by: $Author: pahlke $ ## | @@ -506,7 +506,8 @@ SummaryFactory <- R6::R6Class("SummaryFactory", "expectedEventsH1", "expectedNumberOfEvents", "expectedStudyDurationH1", - "studyDuration")) { + "studyDuration", + "earlyStop")) { transposed <- TRUE } } @@ -3552,8 +3553,9 @@ SummaryFactory <- R6::R6Class("SummaryFactory", } if (designPlan$.getParameterType(parameterNameSubjects) == C_PARAM_GENERATED) { - subjectsCaption <- ifelse(design$kMax > 1 && inherits(designPlan, "SimulationResults") && - !survivalEnabled, "Stage-wise number of subjects", "Number of subjects") + subjectsCaption <- ifelse(design$kMax > 1 && + inherits(designPlan, "SimulationResults") && !survivalEnabled, + "Stage-wise number of subjects", "Number of subjects") summaryFactory$addParameter(designPlan, parameterName = parameterNameSubjects, parameterCaption = subjectsCaption, @@ -3566,33 +3568,6 @@ SummaryFactory <- R6::R6Class("SummaryFactory", } } - if (baseEnabled && countDataEnabled && design$kMax > 1 && - !is.null(designPlan[["maxNumberOfSubjects"]]) && - designPlan$.getParameterType("maxNumberOfSubjects") == C_PARAM_GENERATED) { - summaryFactory$addParameter(designPlan, - parameterName = "maxNumberOfSubjects", - parameterCaption = "Maximum number of subjects", - roundDigits = digitSettings$digitsSampleSize - ) - summaryFactory$addParameter(designPlan, - parameterName = "expectedNumberOfSubjectsH1", - parameterCaption = "Expected number of subjects", - roundDigits = digitSettings$digitsSampleSize - ) - } - if (baseEnabled && !countDataEnabled && design$kMax > 1) { - summaryFactory$addParameter(designPlan, - parameterName = ifelse(inherits(designPlan, "TrialDesignPlan") && - (designPlan$.isSampleSizeObject() || countDataEnabled), - "expectedNumberOfSubjectsH1", "expectedNumberOfSubjects"), - parameterCaption = "Expected number of subjects under H1", - roundDigits = digitSettings$digitsSampleSize, - transpose = TRUE, - validateParameterType = !countDataEnabled, - lastStage = design$kMax - ) - } - if (simulationEnabled && (multiArmEnabled || enrichmentEnabled || countDataEnabled)) { if (survivalEnabled) { summaryFactory$addParameter(designPlan, @@ -3612,6 +3587,29 @@ SummaryFactory <- R6::R6Class("SummaryFactory", ) } } + else if (baseEnabled && design$kMax > 1) { + parameterName <- ifelse(inherits(designPlan, "TrialDesignPlan") && + (designPlan$.isSampleSizeObject() || countDataEnabled), + "expectedNumberOfSubjectsH1", "expectedNumberOfSubjects") + summaryFactory$addParameter(designPlan, + parameterName = parameterName, + parameterCaption = "Expected number of subjects under H1", + roundDigits = digitSettings$digitsSampleSize, + transpose = TRUE, + validateParameterType = !countDataEnabled, + lastStage = design$kMax + ) + if (countDataEnabled && + (is.null(designPlan[[parameterName]]) || all(is.na(designPlan[[parameterName]]))) && + !is.null(designPlan[["maxNumberOfSubjects"]]) && + designPlan$.getParameterType("maxNumberOfSubjects") == C_PARAM_GENERATED) { + summaryFactory$addParameter(designPlan, + parameterName = "maxNumberOfSubjects", + parameterCaption = "Maximum number of subjects", + roundDigits = digitSettings$digitsSampleSize + ) + } + } if (baseEnabled && survivalEnabled && outputSize %in% c("medium", "large")) { parameterNameEvents <- NULL @@ -3671,7 +3669,8 @@ SummaryFactory <- R6::R6Class("SummaryFactory", parameterCaption = "Overall exit probability", # (under H1) roundDigits = digitSettings$digitsProbabilities, smoothedZeroFormat = TRUE, - transpose = TRUE + transpose = TRUE, + lastStage = design$kMax ) } diff --git a/R/f_design_plan_count_data.R b/R/f_design_plan_count_data.R index c97a0d0..d68d290 100644 --- a/R/f_design_plan_count_data.R +++ b/R/f_design_plan_count_data.R @@ -13,8 +13,8 @@ ## | ## | Contact us for information about our services: info@rpact.com ## | -## | File version: $Revision: 8268 $ -## | Last changed: $Date: 2024-09-25 16:14:45 +0200 (Mi, 25 Sep 2024) $ +## | File version: $Revision: 8279 $ +## | Last changed: $Date: 2024-09-27 10:49:35 +0200 (Fr, 27 Sep 2024) $ ## | Last changed by: $Author: wassmer $ ## | @@ -162,7 +162,7 @@ followUpTime <- studyTime - max(accrualTime) } - if (designPlan$.objectType == "power"){ + if (designPlan$.objectType == "power") { nParameters <- 1 } else { nParameters <- length(lambda1) @@ -192,7 +192,7 @@ criticalValues <- .getCriticalValues(design) futilityBounds <- design$futilityBounds futilityBounds[!is.na(futilityBounds) & futilityBounds <= C_FUTILITY_BOUNDS_DEFAULT] <- NA_real_ - + for (iCase in 1:nParameters) { ar <- allocationRatioPlanned[iCase] @@ -224,7 +224,7 @@ recruit2 <- seq(0, accrualTime, length.out = maxNumberOfSubjects[iCase] / (1 + ar)) } } - + # calculate theta that solves (ln(theta) - ln(thetaH0) sqrt(FisherInformation_k) = boundary for (j in seq_len(length(criticalValues))) { if (all(is.na(numberOfSubjects[, iCase]))) { @@ -354,12 +354,13 @@ )$root) }, error = function(e) { - stop("Failed to calculate the calendar time. ", + warning("Failed to calculate the calendar time. ", "Fisher information might be bounded, e.g., due to overdispersion > 0", call. = FALSE ) } ) + return(NA_real_) } .getMaximumSampleSizeTwoGroups <- function(allocationRatioPlanned, @@ -402,8 +403,7 @@ )) } -.getDesignPlanCountData <- function( - design, +.getDesignPlanCountData <- function(design, designCharacteristics, objectType, sided, @@ -1137,7 +1137,9 @@ getPowerCounts <- function(design = NULL, ..., accrualTime <- accrualTime[-1] } directionUpper <- .assertIsValidDirectionUpper(directionUpper, - design, objectType = "power", userFunctionCallEnabled = TRUE) + design, + objectType = "power", userFunctionCallEnabled = TRUE + ) .setValueAndParameterType(designPlan, "directionUpper", directionUpper, C_DIRECTION_UPPER_DEFAULT) futilityPerStage <- matrix(NA_real_, kMax - 1, totalCases) diff --git a/R/f_simulation_base_count_data.R b/R/f_simulation_base_count_data.R index e8f78a7..24f3107 100644 --- a/R/f_simulation_base_count_data.R +++ b/R/f_simulation_base_count_data.R @@ -13,8 +13,8 @@ ## | ## | Contact us for information about our services: info@rpact.com ## | -## | File version: $Revision: 8243 $ -## | Last changed: $Date: 2024-09-20 07:33:34 +0200 (Fr, 20 Sep 2024) $ +## | File version: $Revision: 8277 $ +## | Last changed: $Date: 2024-09-27 08:16:45 +0200 (Fr, 27 Sep 2024) $ ## | Last changed by: $Author: pahlke $ ## | @@ -593,27 +593,33 @@ getSimulationCounts <- function(design = NULL, simulationResults$iterations <- iterations simulationResults$.setParameterType("iterations", C_PARAM_GENERATED) + if (kMax == 1) { + sampleSizePerStage <- rep(maxNumberOfSubjects, totalCases) + expectedSampleSize <- sampleSizePerStage + } + sampleSizePerStage[is.nan(sampleSizePerStage)] <- NA_integer_ simulationResults$numberOfSubjects <- sampleSizePerStage simulationResults$.setParameterType( "numberOfSubjects", - ifelse(is.na(nTotal), C_PARAM_NOT_APPLICABLE, C_PARAM_GENERATED) + ifelse(kMax == 1 || is.na(nTotal), C_PARAM_NOT_APPLICABLE, C_PARAM_GENERATED) ) + simulationResults$expectedNumberOfSubjects <- expectedSampleSize simulationResults$.setParameterType( "expectedNumberOfSubjects", - ifelse(all(is.na(expectedSampleSize)), C_PARAM_NOT_APPLICABLE, C_PARAM_GENERATED) + ifelse(kMax == 1 || all(is.na(expectedSampleSize)), C_PARAM_NOT_APPLICABLE, C_PARAM_GENERATED) ) simulationResults$numberOfSubjects1 <- n1 simulationResults$.setParameterType( "numberOfSubjects1", - ifelse(allocationRatioPlanned == 1, C_PARAM_NOT_APPLICABLE, C_PARAM_GENERATED) + ifelse(kMax == 1 && allocationRatioPlanned != 1, C_PARAM_GENERATED, C_PARAM_NOT_APPLICABLE) ) simulationResults$numberOfSubjects2 <- n2 simulationResults$.setParameterType( "numberOfSubjects2", - ifelse(allocationRatioPlanned == 1, C_PARAM_NOT_APPLICABLE, C_PARAM_GENERATED) + ifelse(kMax == 1 && allocationRatioPlanned != 1, C_PARAM_GENERATED, C_PARAM_NOT_APPLICABLE) ) simulationResults$overallReject <- overallReject diff --git a/cran-comments.md b/cran-comments.md index 531380c..2ff0769 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -10,7 +10,7 @@ There were no ERRORs or WARNINGs. ## Unit tests: testthat results (complete test) -OK: 36947 +OK: 36943 Failed: 0 Warnings: 0 Skipped: 0 diff --git a/inst/doc/rpact_getting_started.html b/inst/doc/rpact_getting_started.html index 5578db4..a79f378 100644 --- a/inst/doc/rpact_getting_started.html +++ b/inst/doc/rpact_getting_started.html @@ -12,7 +12,7 @@ - + Getting started with rpact @@ -239,7 +239,7 @@

Getting started with rpact

Friedrich Pahlke and Gernot Wassmer

-

2024-09-26

+

2024-09-27

diff --git a/tests/testthat/test-f_design_plan_count_data.R b/tests/testthat/test-f_design_plan_count_data.R index 43b0b36..fdcce4f 100644 --- a/tests/testthat/test-f_design_plan_count_data.R +++ b/tests/testthat/test-f_design_plan_count_data.R @@ -178,7 +178,6 @@ test_that("'getSampleSizeCounts': Sample size calculation of testing count data lambda2 = 1.4, accrualTime = c(0, 20), allocationRatioPlanned = 1, maxNumberOfSubjects = 100 ) - ## Comparison of the results of TrialDesignPlanCountData object 'result4' with expected results expect_equal(result4$directionUpper, c(FALSE, FALSE, FALSE), label = paste0(result4$directionUpper)) expect_equal(result4$theta, c(0.75, 0.85714286, 0.96428571), tolerance = 1e-07, label = paste0(result4$theta)) @@ -214,10 +213,11 @@ test_that("'getSampleSizeCounts': Sample size calculation of testing count data expect_true(is.matrix(mtx)) expect_true(nrow(mtx) > 0 && ncol(mtx) > 0) } + # @refFS[Formula]{fs:FisherInfCounts} # @refFS[Formula]{fs:maximumSampleSizeVariableExposureCounts} # @refFS[Formula]{fs:observationTimePerStageCounts} - expect_error(getSampleSizeCounts( + expect_warning(getSampleSizeCounts( alpha = 0.01, beta = 0.05, lambda1 = seq(1.35, 1.35, 0.15), overdispersion = 0.01, lambda2 = 1.4, accrualTime = c(0, 10, 20), accrualIntensity = c(5, 10) )) diff --git a/tests/testthat/test-f_simulation_base_count_data.R b/tests/testthat/test-f_simulation_base_count_data.R index 8c187eb..d34a536 100644 --- a/tests/testthat/test-f_simulation_base_count_data.R +++ b/tests/testthat/test-f_simulation_base_count_data.R @@ -269,10 +269,8 @@ test_that("'getSimulationCounts': fixed exposure", { ## Comparison of the results of SimulationResultsCountData object 'result2' with expected results expect_equal(result2$lambda1, c(1.05, 1.5866662), tolerance = 1e-07, label = paste0(result2$lambda1)) - expect_equal(result2$numberOfSubjects[1, ], c(0, 0), label = paste0(result2$numberOfSubjects[1, ])) expect_equal(result2$iterations[1, ], c(100, 100), label = paste0(result2$iterations[1, ])) expect_equal(result2$overallReject, c(0.14, 0), tolerance = 1e-07, label = paste0(result2$overallReject)) - expect_equal(result2$expectedNumberOfSubjects, c(0, 0), label = paste0(result2$expectedNumberOfSubjects)) if (isTRUE(.isCompleteUnitTestSetEnabled())) { invisible(capture.output(expect_error(print(result2), NA))) expect_output(print(result2)$show()) @@ -280,10 +278,8 @@ test_that("'getSimulationCounts': fixed exposure", { expect_output(summary(result2)$show()) suppressWarnings(result2CodeBased <- eval(parse(text = getObjectRCode(result2, stringWrapParagraphWidth = NULL)))) expect_equal(result2CodeBased$lambda1, result2$lambda1, tolerance = 1e-07) - expect_equal(result2CodeBased$numberOfSubjects, result2$numberOfSubjects, tolerance = 1e-07) expect_equal(result2CodeBased$iterations, result2$iterations, tolerance = 1e-07) expect_equal(result2CodeBased$overallReject, result2$overallReject, tolerance = 1e-07) - expect_equal(result2CodeBased$expectedNumberOfSubjects, result2$expectedNumberOfSubjects, tolerance = 1e-07) expect_type(names(result2), "character") df <- as.data.frame(result2) expect_s3_class(df, "data.frame")