Skip to content

Commit 954059c

Browse files
committed
Update documentation and improve argument checks
1 parent ef3fc37 commit 954059c

11 files changed

+250
-38
lines changed

R/SampleSize.R

Lines changed: 121 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#' @param step.up Logical. If `TRUE` (default), the sample size search increments upward from the `lower` limit; if `FALSE`, it decrements downward from the `upper` limit. Used only when `optimization_method` is `"fast"`.
3939
#' @param pos.side Logical. If `TRUE`, finds the smallest integer, `i`, closest to the root such that `f(i) > 0`. Used only when `optimization_method` is `"fast"`.
4040
#' @param maxiter Integer. Maximum number of iterations allowed for finding the sample size. Defaults to 1000. Used only when `optimization_method` is `"fast"`.
41+
#' @param verbose Logical. If `TRUE`, the function displays progress and informational messages during execution. Defaults to `FALSE`.
4142
#' @return An object simss that contains the following elements :
4243
#' \describe{
4344
#' \item{"response"}{ array with the sample sizes for each arm and aproximated achieved power with confidence intervals}
@@ -117,46 +118,37 @@ sampleSize <- function(mu_list, varcov_list = NA, sigma_list = NA, cor_mat = NA,
117118
step.power=6,
118119
step.up=TRUE,
119120
pos.side=FALSE,
120-
maxiter = 1000
121+
maxiter = 1000, verbose = FALSE
121122
){
122123

123124
# Assign default values for Eper and Eco
124-
if (missing(Eper)) Eper <- c(0, 0)
125-
if (missing(Eco)) Eco <- c(0, 0)
125+
if (missing(Eper)) {
126+
Eper <- c(0, 0)
127+
info_msg("Eper not provided. Defaulting to c(0, 0).", verbose)
128+
}
129+
if (missing(Eco)) {
130+
Eco <- c(0, 0)
131+
info_msg("Eco not provided. Defaulting to c(0, 0).", verbose)
132+
}
126133

127134
# is mu provided?
128135
if (all(is.na(mu_list))) {
129136
stop("mu_list must be provided")
130137
}
131138

132-
# Parameters endpoints -----
133-
n <- length(mu_list) # number of arms
134-
135-
# Derive the arm names
136-
if (any(is.na(arm_names))) {
137-
if (!is.null(names(mu_list))) {
138-
arm_names <- names(mu_list)
139-
}
140-
}
141-
142-
if (any(is.na(ynames_list))) {
143-
144-
# Try to derive the ynames from mu_list
145-
ynames_list <- lapply(mu_list, function(x) names(x))
146-
147-
if (length(names(ynames_list)) == 0 | any(sapply(ynames_list, is.null))) {
148-
#warning("no all endpoints names provided for each arm, so arbitrary names are assigned")
149-
ynames_list <- lapply(mu_list, function(x) paste0("y", 1:length(x)))
150-
}
151-
}
139+
# Derive the Number of Arms
140+
n <- length(mu_list)
152141

142+
# Derive the Arm Names
143+
arm_names <- derive_arm_names(arm_names = arm_names, mu_list = mu_list,
144+
verbose = verbose)
153145

154-
# Treatment allocation rate
155-
if (any(is.na(TAR))) {
156-
TAR <- rep(1,n)
157-
}
146+
# Derive the Endpoint Names
147+
ynames_list <- derive_endpoint_names(ynames_list = ynames_list,
148+
mu_list = mu_list, verbose = verbose)
158149

159-
TAR_list <- as.list(TAR)
150+
# Derive the Treatment Allocation Rate
151+
TAR_list <- derive_allocation_rate(TAR = TAR, n_arms = n, verbose = verbose)
160152

161153

162154
for (i in 1:n) {
@@ -281,11 +273,6 @@ sampleSize <- function(mu_list, varcov_list = NA, sigma_list = NA, cor_mat = NA,
281273
}
282274
names(weight_seq) <- uynames
283275

284-
# Give to list the arm names
285-
if (any(is.na(arm_names))) {
286-
arm_names <- paste0("A",rep(1:n))
287-
}
288-
289276
#if (len_mu[[1]] == 1){
290277
# mu_list <- lapply(mu_list,FUN = function(x){array(unlist(x))})
291278
# varcov_list <- lapply(varcov_list,FUN = function(x){matrix(unlist(x))})}
@@ -470,13 +457,16 @@ sampleSize <- function(mu_list, varcov_list = NA, sigma_list = NA, cor_mat = NA,
470457
}
471458

472459

473-
# Save endopoints related information on a parameter list
460+
# Save endpoints related information on a parameter list
474461

475462
param <- list(mu = mu_list, varcov = varcov_list, sigmaB = sigmaB,
476463
TAR_list = TAR_list, type_y = type_y, weight_seq = weight_seq,
477464
arm_names = arm_names, ynames_list = ynames_list,
478465
list_comparator = list_comparator,
479-
list_y_comparator = list_y_comparator,sigmaB = sigmaB,
466+
list_y_comparator = list_y_comparator,
467+
list_lequi.tol = list_lequi.tol,
468+
list_uequi.tol = list_uequi.tol,
469+
sigmaB = sigmaB,
480470
Eper = Eper, Eco = Eco)
481471

482472
# Parameters related to design ----
@@ -579,4 +569,100 @@ sampleSize <- function(mu_list, varcov_list = NA, sigma_list = NA, cor_mat = NA,
579569

580570
}
581571

572+
#' Derive or Assign Arm Names
573+
#'
574+
#' This function checks if `arm_names` is provided. If `arm_names` is missing, it attempts to derive names
575+
#' from `mu_list`. If `mu_list` does not contain names, it assigns default names ("A1", "A2", etc.) to each arm.
576+
#' Informational messages are displayed if `verbose` is set to `TRUE`.
577+
#'
578+
#' @author Thomas Debray \email{[email protected]}
579+
#'
580+
#' @param arm_names Optional vector of arm names.
581+
#' @param mu_list Named list of means per treatment arm, from which arm names may be derived.
582+
#' @param verbose Logical, if `TRUE`, displays messages about the derivation process.
583+
#'
584+
#' @return A vector of arm names.
585+
derive_arm_names <- function(arm_names, mu_list, verbose = FALSE) {
586+
587+
# Check if arm_names is missing and attempt to derive from mu_list
588+
if (any(is.na(arm_names))) {
589+
if (!is.null(names(mu_list))) {
590+
arm_names <- names(mu_list)
591+
info_msg(paste("Arm names derived from mu_list: ", paste(arm_names, collapse = ", ")), verbose)
592+
} else {
593+
arm_names <- paste0("A",seq(mu_list))
594+
info_msg(paste("Arm names not provided and could not be derived from mu_list. Assigning default names: ", paste(arm_names, collapse = ", ")), verbose)
595+
}
596+
} else {
597+
info_msg(paste("Using user-provided arm names: ", paste(arm_names, collapse = ", ")), verbose)
598+
}
599+
600+
return(arm_names)
601+
}
602+
603+
#' Derive Endpoint Names
604+
#'
605+
#' @author Thomas Debray \email{[email protected]}
606+
#'
607+
#' This function derives endpoint names (`ynames_list`) from `mu_list` if `ynames_list`
608+
#' is missing. If `ynames_list` is already provided, it confirms the names to the user when
609+
#' `verbose` is set to `TRUE`.
610+
#'
611+
#' @param ynames_list Optional list of vectors with endpoint names for each arm.
612+
#' @param mu_list Named list of means per treatment arm, where names can be used as endpoint names.
613+
#' @param verbose Logical, if `TRUE`, displays messages about the derivation process.
614+
#'
615+
#' @return A list of endpoint names for each arm.
616+
derive_endpoint_names <- function(ynames_list, mu_list, verbose = FALSE) {
617+
618+
# Check if ynames_list is missing and attempt to derive from mu_list
619+
if (any(is.na(ynames_list))) {
620+
621+
# Try to derive the ynames from mu_list
622+
ynames_list <- lapply(mu_list, function(x) names(x))
623+
info_msg("Attempting to derive endpoint names (ynames_list) from mu_list.", verbose)
624+
625+
# Check if ynames were successfully derived
626+
if (length(names(ynames_list)) == 0 || any(sapply(ynames_list, is.null))) {
627+
info_msg("Not all endpoint names were provided. Assigning arbitrary names (y1, y2, etc.) to endpoints for each arm.", verbose)
628+
ynames_list <- lapply(mu_list, function(x) paste0("y", 1:length(x)))
629+
} else {
630+
info_msg("Endpoint names derived from mu_list.", verbose)
631+
}
632+
} else {
633+
info_msg("Using user-provided endpoint names (ynames_list).", verbose)
634+
}
635+
636+
return(ynames_list)
637+
}
638+
639+
#' Derive Treatment Allocation Rate (TAR)
640+
#'
641+
#' This function checks if `TAR` (treatment allocation rate) is provided. If `TAR` is missing, it assigns a default
642+
#' equal allocation rate across all arms. It then converts `TAR` to a list format for further use.
643+
#' Informational messages are displayed if `verbose` is set to `TRUE`.
644+
#'
645+
#' @author Thomas Debray \email{[email protected]}
646+
#'
647+
#' @param TAR Optional numeric vector specifying the allocation rate for each treatment arm. If missing, a default equal allocation rate is assigned.
648+
#' @param n_arms Integer specifying the number of treatment arms.
649+
#' @param verbose Logical, if `TRUE`, displays messages about the status of `TAR` derivation or assignment.
650+
#'
651+
#' @return A list representing the treatment allocation rate for each arm.
652+
derive_allocation_rate <- function(TAR, n_arms, verbose = FALSE) {
653+
654+
# Check if TAR is missing and assign default if necessary
655+
if (any(is.na(TAR))) {
656+
TAR <- rep(1, n_arms) # Default equal allocation across all arms
657+
info_msg(paste("TAR not provided. Assigning equal allocation rate across all arms: ", paste(TAR, collapse = ":")), verbose)
658+
} else {
659+
info_msg(paste("Using user-provided TAR: ", paste(TAR, collapse = ":")), verbose)
660+
}
661+
662+
# Convert TAR to list format
663+
TAR_list <- as.list(TAR)
664+
665+
return(TAR_list)
666+
}
667+
582668

R/helper.r

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ print.simss <- function(x, ...) {
2424
}
2525

2626

27+

R/utils.R

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,4 +437,16 @@ mcsapply <- function (X, FUN, ..., simplify = TRUE, USE.NAMES = TRUE) {
437437
else answer
438438
}
439439

440+
#' Helper function for conditional messages
441+
#'
442+
#' This function displays a message if the `verbose` parameter is set to `TRUE`.
443+
#' It is useful for providing optional feedback to users during function execution.
444+
#' @author Thomas Debray \email{[email protected]}
445+
#' @param message A character string containing the message to display.
446+
#' @param verbose Logical, if `TRUE`, the message is displayed; if `FALSE`, the message is suppressed.
447+
#'
448+
#' @return NULL (invisible). This function is used for side effects (displaying messages).
449+
info_msg <- function(message, verbose) {
450+
if (verbose) message(message)
451+
}
440452

man/derive_allocation_rate.Rd

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/derive_arm_names.Rd

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/derive_endpoint_names.Rd

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/info_msg.Rd

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/sampleSize.Rd

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/validate_positive_definite.Rd

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/validate_sample_size_limits.Rd

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)