Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Generated by roxygen2: do not edit by hand

S3method(as_gt,fixed_design)
S3method(as_gt,gs_design)
S3method(as_gt,fixed_design_summary)
S3method(as_gt,gs_design_summary)
S3method(as_gt,simtrial_gs_wlr)
S3method(as_rtf,fixed_design)
S3method(as_rtf,gs_design)
S3method(as_rtf,fixed_design_summary)
S3method(as_rtf,gs_design_summary)
S3method(summary,fixed_design)
S3method(summary,gs_design)
S3method(to_integer,fixed_design)
Expand Down
70 changes: 16 additions & 54 deletions R/as_gt.R
Original file line number Diff line number Diff line change
Expand Up @@ -78,60 +78,22 @@ as_gt <- function(x, ...) {
#' ) |>
#' summary() |>
#' as_gt()
as_gt.fixed_design <- function(x, title = NULL, footnote = NULL, ...) {
method <- fd_method(x)
ans <- gt::gt(x) |>
gt::tab_header(title = title %||% fd_title(method))
if (!isFALSE(footnote)) ans <- ans |>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously we could disable the footnote via footnote = FALSE. Now we wouldn't if this if statement is removed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Fixed by c8609a1

gt::tab_footnote(
footnote = footnote %||% fd_footnote(x, method),
locations = gt::cells_title(group = "title")
)
return(ans)
}

get_method <- function(x, methods) intersect(methods, class(x))[1]
as_gt.fixed_design_summary <- function(x, title = NULL, footnote = NULL, ...) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it's worth exposing the true defaults here, i.e.,

Suggested change
as_gt.fixed_design_summary <- function(x, title = NULL, footnote = NULL, ...) {
as_gt.fixed_design_summary <- function(x, title = attr(x, "title"), footnote = attr(x, "footnote"), ...) {

Two benefits are: 1) it'd be more transparent; 2) it'd make it possible to actually use NULL. The footnote = FALSE mentioned below was a hack that I resorted to because in the Shiny app I did need to disable the footnote. Although the natural choice was footnote = NULL, it just couldn't work because we override the NULL value by our defaults.

I don't have strong opinions on this, so if you prefer the current way, that will be fine to me.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like your proposal, but I don't want to introduce any API changes in this already large PR. Thus for now I am following the documented interface:

#' the table. To disable footnotes, use `footnote = FALSE`.

But given that you were the one that introduced the workaround footnote = FALSE (#514), please feel free to send a follow-up PR to adjust this behavior.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. I'll follow up.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided not to change this after looking at as_gt.gs_design_summary, in which the footnote logic was more complicated than that in as_gt.fixed_design_summary. Let's continue to use footnote = FALSE as the only way to disable footnotes.

if (is.null(title)) title <- attr(x, "title")
if (is.null(footnote)) footnote <- attr(x, "footnote")

# get the fixed design method
fd_method <- function(x) {
get_method(x, c("ahr", "fh", "mb", "lf", "rd", "maxcombo", "milestone", "rmst"))
}
ans <- gt::gt(x) |>
gt::tab_header(title = title)

# get the default title
fd_title <- function(method) {
sprintf("Fixed Design %s Method", switch(
method,
ahr = "under AHR", fh = "under Fleming-Harrington", mb = "under Magirr-Burman",
lf = "under Lachin and Foulkes", maxcombo = "under MaxCombo",
milestone = "under Milestone", rmst = "under Restricted Mean Survival Time",
rd = "of Risk Difference under Farrington-Manning"
))
}
if (!isFALSE(footnote)) {
ans <- ans |>
gt::tab_footnote(
footnote = footnote,
locations = gt::cells_title(group = "title")
)
}

# get the default footnote
fd_footnote <- function(x, method) {
switch(
method,
ahr = "Power computed with average hazard ratio method.",
fh = paste(
"Power for Fleming-Harrington test", substring(x$Design, 19),
"using method of Yung and Liu."
),
lf = paste(
"Power using Lachin and Foulkes method applied using expected",
"average hazard ratio (AHR) at time of planned analysis."
),
rd = paste(
"Risk difference power without continuity correction using method of",
"Farrington and Manning."
),
maxcombo = paste0(
"Power for MaxCombo test with Fleming-Harrington tests ",
substring(x$Design, 9), "."
),
# for mb, milestone, and rmst
paste("Power for", x$Design, "computed with method of Yung and Liu.")
)
return(ans)
}

#' @rdname as_gt
Expand Down Expand Up @@ -243,7 +205,7 @@ fd_footnote <- function(x, method) {
#' summary() |>
#' as_gt(display_columns = c("Analysis", "Bound", "Nominal p", "Z", "Probability"))
#' }
as_gt.gs_design <- function(
as_gt.gs_design_summary <- function(
x,
title = NULL,
subtitle = NULL,
Expand Down Expand Up @@ -355,7 +317,7 @@ gsd_footnote <- function(method, columns) {
# footnote for non-binding designs
gsd_footnote_nb <- function(x, x_alpha) {
full_alpha <- attr(x, "full_alpha")
if (!inherits(x, "non_binding") || x_alpha >= full_alpha) return()
if (attr(x, "binding") || x_alpha >= full_alpha) return()
a1 <- format(x_alpha, scientific = FALSE)
a2 <- format(full_alpha, scientific = FALSE)
a3 <- format(full_alpha - x_alpha, scientific = FALSE)
Expand Down Expand Up @@ -387,7 +349,7 @@ gsd_parts <- function(
x, title, subtitle, spannersub, footnote, bound, columns, inf_bound,
transform = identity
) {
method <- intersect(c("ahr", "wlr", "combo", "rd"), class(x))[1]
method <- attr(x, "design")
if (!inf_bound) x <- filter(x, !is.infinite(Z))
# `x` needs a custom transformation in as_rtf()
x2 <- transform(x)
Expand Down
11 changes: 6 additions & 5 deletions R/as_rtf.R
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ as_rtf <- function(x, ...) {
#' ) |>
#' summary() |>
#' as_rtf(file = tempfile(fileext = ".rtf"))
as_rtf.fixed_design <- function(
as_rtf.fixed_design_summary <- function(
x,
title = NULL,
footnote = NULL,
Expand All @@ -100,9 +100,10 @@ as_rtf.fixed_design <- function(
file,
...) {
orientation <- match.arg(orientation)
method <- fd_method(x)
title <- title %||% paste(fd_title(method), "{^a}")
footnote <- footnote %||% paste("{^a}", fd_footnote(x, method))
if (is.null(title)) title <- attr(x, "title")
if (is.null(footnote)) footnote <- attr(x, "footnote")
title <- paste(title, "{^a}")
footnote <- paste("{^a}", footnote)

# set default column width
n_row <- nrow(x)
Expand Down Expand Up @@ -266,7 +267,7 @@ check_rel_width <- function(width, n_col) {
#' file = tempfile(fileext = ".rtf")
#' )
#' }
as_rtf.gs_design <- function(
as_rtf.gs_design_summary <- function(
x,
title = NULL,
subtitle = NULL,
Expand Down
16 changes: 12 additions & 4 deletions R/fixed_design_ahr.R
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ fixed_design_ahr <- function(
info_scale = info_scale
)
}

# Prepare output ----
ans <- tibble(
design = "ahr",
n = d$analysis$n,
Expand All @@ -132,10 +134,16 @@ fixed_design_ahr <- function(
alpha = alpha,
power = (d$bound |> filter(bound == "upper"))$probability
)
y <- list(
input = input, enroll_rate = d$enroll_rate,
fail_rate = d$fail_rate, analysis = ans, design = "ahr"
y <- structure(
list(
input = input, enroll_rate = d$enroll_rate, fail_rate = d$fail_rate,
analysis = ans, design = "ahr"
),
class = "fixed_design",
design_display = "Average hazard ratio",
title = "Fixed Design under AHR Method",
footnote = "Power computed with average hazard ratio method."
)
class(y) <- c("fixed_design", class(y))

return(y)
}
24 changes: 19 additions & 5 deletions R/fixed_design_fh.R
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ fixed_design_fh <- function(
info_scale = info_scale
)
}

# Prepare output ----
ans <- tibble(
design = "fh",
n = d$analysis$n,
Expand All @@ -131,11 +133,23 @@ fixed_design_fh <- function(
alpha = alpha,
power = (d$bound |> filter(bound == "upper"))$probability
)
y <- list(
input = input, enroll_rate = d$enroll_rate, fail_rate = d$fail_rate,
analysis = ans,
design = "fh", design_par = list(rho = rho, gamma = gamma)
design_display <- paste0(
"Fleming-Harrington FH(", rho, ", ", gamma, ")",
if (rho == 0 && gamma == 0) " (logrank)"
)
y <- structure(
list(
input = input, enroll_rate = d$enroll_rate, fail_rate = d$fail_rate,
analysis = ans, design = "fh", design_par = list(rho = rho, gamma = gamma)
),
class = "fixed_design",
design_display = design_display,
title = "Fixed Design under Fleming-Harrington Method",
footnote = paste(
"Power for Fleming-Harrington test", substring(design_display, 19),
"using method of Yung and Liu."
)
)
class(y) <- c("fixed_design", class(y))

return(y)
}
25 changes: 18 additions & 7 deletions R/fixed_design_lf.R
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ fixed_design_lf <- function(
rr[, 1]
})
)

# Prepare output ----
ans <- tibble(
design = "lf",
n = d$n,
Expand All @@ -181,13 +183,22 @@ fixed_design_lf <- function(
alpha = d$alpha,
power = d$power
)
y <- list(
input = input,
enroll_rate = enroll_rate |> mutate(rate = rate * d$n / sum(enroll_rate$duration * enroll_rate$rate)),
fail_rate = fail_rate,
analysis = ans,
design = "lf"
y <- structure(
list(
input = input,
enroll_rate = enroll_rate |> mutate(rate = rate * d$n / sum(enroll_rate$duration * enroll_rate$rate)),
fail_rate = fail_rate,
analysis = ans,
design = "lf"
),
class = "fixed_design",
design_display = "Lachin and Foulkes",
title = "Fixed Design under Lachin and Foulkes Method",
footnote = paste(
"Power using Lachin and Foulkes method applied using expected",
"average hazard ratio (AHR) at time of planned analysis."
)
)
class(y) <- c("fixed_design", class(y))

return(y)
}
32 changes: 26 additions & 6 deletions R/fixed_design_maxcombo.R
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ fixed_design_maxcombo <- function(
lower = gs_b, lpar = -Inf
)
}
# get the output of MaxCombo

# Prepare output ----
ans <- tibble(
design = "maxcombo",
n = d$analysis$n,
Expand All @@ -126,11 +127,30 @@ fixed_design_maxcombo <- function(
alpha = alpha,
power = (d$bound |> filter(bound == "upper"))$probability
)
y <- list(
input = input,
enroll_rate = d$enroll_rate, fail_rate = d$fail_rate, analysis = ans,
design = "maxcombo", design_par = list(rho = rho, gamma = gamma, tau = tau)
design_display <- gsub(
"FH(0, 0)", "logrank", paste(
"MaxCombo:", paste0(
"FHC(", rho, ", ", gamma, ")",
collapse = ", "
)
),
fixed = TRUE
)
y <- structure(
list(
input = input, enroll_rate = d$enroll_rate, fail_rate = d$fail_rate,
analysis = ans, design = "maxcombo",
design_par = list(rho = rho, gamma = gamma, tau = tau)
),
class = "fixed_design",
design_display = design_display,
title = "Fixed Design under MaxCombo Method",
footnote = paste0(
"Power for MaxCombo test with Fleming-Harrington tests ",
substring(design_display, 9),
"."
)
)
class(y) <- c("fixed_design", class(y))

return(y)
}
21 changes: 16 additions & 5 deletions R/fixed_design_mb.R
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ fixed_design_mb <- function(
info_scale = info_scale
)
}
# get the output of MB

# Prepare output ----
ans <- tibble(
design = "mb",
n = d$analysis$n,
Expand All @@ -129,10 +130,20 @@ fixed_design_mb <- function(
alpha = alpha,
power = (d$bound |> filter(bound == "upper"))$probability
)
y <- list(
input = input, enroll_rate = d$enroll_rate, fail_rate = d$fail_rate, analysis = ans,
design = "mb", design_par = list(tau = tau, w_max = w_max)
design_display <- paste0("Modestly weighted LR: tau = ", tau)
y <- structure(
list(
input = input, enroll_rate = d$enroll_rate, fail_rate = d$fail_rate,
analysis = ans, design = "mb", design_par = list(tau = tau, w_max = w_max)
),
class = "fixed_design",
design_display = design_display,
title = "Fixed Design under Magirr-Burman Method",
footnote = paste(
"Power for", design_display,
"computed with method of Yung and Liu."
)
)
class(y) <- c("fixed_design", class(y))

return(y)
}
22 changes: 16 additions & 6 deletions R/fixed_design_milestone.R
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ fixed_design_milestone <- function(
tau = tau
)
}
# get the output of MaxCombo

# Prepare output ----
ans <- tibble(
design = "milestone",
n = d$analysis$n,
Expand All @@ -114,11 +115,20 @@ fixed_design_milestone <- function(
alpha = alpha,
power = (d$bound |> filter(bound == "upper"))$probability
)
y <- list(
input = input,
enroll_rate = d$enroll_rate, fail_rate = d$fail_rate, analysis = ans,
design = "milestone", design_par = list(tau = tau)
design_display <- paste("Milestone: tau =", tau)
y <- structure(
list(
input = input, enroll_rate = d$enroll_rate, fail_rate = d$fail_rate,
analysis = ans, design = "milestone", design_par = list(tau = tau)
),
class = "fixed_design",
design_display = design_display,
title = "Fixed Design under Milestone Method",
footnote = paste(
"Power for", design_display,
"computed with method of Yung and Liu."
)
)
class(y) <- c("fixed_design", class(y))

return(y)
}
Loading
Loading