Skip to content

Commit cfc2765

Browse files
authored
Fix text summary for stratified designs (#619)
* Convert existing `text_summary()` examples to automated tests * Fix text summary of hazard ratios for stratified designs * Fix text summary of enrollment duration for stratified designs * Add NEWS bullet for PR 619
1 parent c92e9e2 commit cfc2765

3 files changed

Lines changed: 499 additions & 15 deletions

File tree

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
- The minimal risk weighting strategy has been added to `gs_design_rd()` and `gs_power_rd()` for risk difference design (#611, #614, thanks to @LittleBeannie).
66
- The `sequential_pval()` function has been added to calculate the sequential p-value for a AHR group sequential design (#605, thanks to @LittleBeannie).
77

8+
## Bug fixes
9+
10+
- The text summary of a stratified design now reports the correct enrollment duration and hazard ratios (#617, #619, thanks to @jdblischak).
11+
812
# gsDesign2 1.1.8
913

1014
## New features

R/text_summary.R

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -155,21 +155,23 @@ text_summary <- function(x, information = FALSE, time_unit = "months") {
155155
# ---------------------------------------- #
156156
# Add HR assumption
157157
# ---------------------------------------- #
158-
if (nrow(x$fail_rate) == 1) {
159-
temp <- paste("a hazard ratio of ", round(x$fail_rate$hr, 2), sep = "")
160-
} else if (nrow(x$fail_rate) == 2) {
161-
temp <- paste("hazard ratio of ",
162-
round(x$fail_rate$hr[1], 2), " during the first ", round(x$fail_rate$duration[1], 2), " ", time_unit,
163-
" and ", round(x$fail_rate$hr[2], 2), " thereafter", sep = "")
164-
} else if (nrow(x$fail_rate) <= 5) {
165-
temp <- paste(x$fail_rate$hr[1:(nrow(x$fail_rate) - 1)] |> round(2),
166-
c(" during the first ", rep(" during the next ", nrow(x$fail_rate) - 2)),
167-
c(x$fail_rate$duration[1:(nrow(x$fail_rate) - 1)] |> round(2)), time_unit) |>
168-
paste(collapse = ", ") |>
169-
paste(" and ", x$fail_rate$hr[nrow(x$fail_rate)] |> round(2), " thereafter")
170-
temp <- paste("hazard ratio of ", temp, sep = "")
158+
strata <- unique(x$fail_rate$stratum)
159+
nstrata <- length(strata)
160+
hr_per_stratum <- table(x$fail_rate$stratum)
161+
if (nstrata > 2 && max(hr_per_stratum) >= 3) {
162+
temp <- paste("piecewise hazard ratio in", nstrata, "strata")
171163
} else {
172-
temp <- "piecewise hazard ratio"
164+
temp <- character(length = nstrata)
165+
for (i in seq_len(nstrata)) {
166+
temp[i] <- text_summary_hr_per_stratum(
167+
x$fail_rate[x$fail_rate$stratum == strata[i], ],
168+
time_unit = time_unit
169+
)
170+
if (strata[i] != "All") {
171+
temp[i] <- paste(temp[i], "in stratum", strata[i])
172+
}
173+
}
174+
temp <- paste(temp, collapse = " and ")
173175
}
174176

175177
if (is_gs_design_ahr) {
@@ -183,7 +185,13 @@ text_summary <- function(x, information = FALSE, time_unit = "months") {
183185
# ---------------------------------------- #
184186
# Add enrollment and study duration
185187
# ---------------------------------------- #
186-
out <- paste(out, ". Enrollment and total study durations are assumed to be ", round(sum(x$enroll_rate$duration), 1),
188+
enroll_duration_per_strata <- tapply(
189+
X = x$enroll_rate$duration,
190+
INDEX = x$enroll_rate$stratum,
191+
FUN = sum
192+
)
193+
out <- paste(out, ". Enrollment and total study durations are assumed to be ",
194+
round(max(enroll_duration_per_strata), 1),
187195
" and ", round(max(x$analysis$time), 1), " ", time_unit, ", respectively.",
188196
sep = "")
189197

@@ -236,3 +244,23 @@ text_summary <- function(x, information = FALSE, time_unit = "months") {
236244

237245
return(out)
238246
}
247+
248+
# Text summary of hazard ratio assumption for a single stratum
249+
text_summary_hr_per_stratum <- function(fail_rate, time_unit) {
250+
if (nrow(fail_rate) == 1) {
251+
temp <- paste("a hazard ratio of ", round(fail_rate$hr, 2), sep = "")
252+
} else if (nrow(fail_rate) == 2) {
253+
temp <- paste("hazard ratio of ",
254+
round(fail_rate$hr[1], 2), " during the first ", round(fail_rate$duration[1], 2), " ", time_unit,
255+
" and ", round(fail_rate$hr[2], 2), " thereafter", sep = "")
256+
} else if (nrow(fail_rate) <= 5) {
257+
temp <- paste(fail_rate$hr[1:(nrow(fail_rate) - 1)] |> round(2),
258+
c(" during the first ", rep(" during the next ", nrow(fail_rate) - 2)),
259+
c(fail_rate$duration[1:(nrow(fail_rate) - 1)] |> round(2)), time_unit) |>
260+
paste(collapse = ", ") |>
261+
paste(" and ", fail_rate$hr[nrow(fail_rate)] |> round(2), " thereafter")
262+
temp <- paste("hazard ratio of ", temp, sep = "")
263+
} else {
264+
temp <- "piecewise hazard ratio"
265+
}
266+
}

0 commit comments

Comments
 (0)