Skip to content

Commit 2c015f6

Browse files
authored
Merge pull request #216 from jdblischak/rmst-formula
Create formula interface for RMST test
2 parents db0d586 + 34f7789 commit 2c015f6

12 files changed

+259
-40
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: simtrial
22
Type: Package
33
Title: Clinical Trial Simulation
4-
Version: 0.3.2.10
4+
Version: 0.3.2.13
55
Authors@R: c(
66
person("Keaven", "Anderson", email = "[email protected]", role = c("aut")),
77
person("Yilong", "Zhang", email = "[email protected]", role = c("aut")),

R/maxcombo.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
#' sim_pw_surv(n = 200) |>
3737
#' cut_data_by_event(150) |>
3838
#' maxcombo(rho = c(0, 0), gamma = c(0, 0.5))
39-
maxcombo <- function(data, rho, gamma){
39+
maxcombo <- function(data, rho, gamma) {
4040
stopifnot(
4141
is.numeric(rho), is.numeric(gamma),
4242
rho >= 0, gamma >= 0,
@@ -50,7 +50,7 @@ maxcombo <- function(data, rho, gamma){
5050
return_corr = TRUE
5151
)
5252

53-
ans <- data.frame(p_value = pvalue_maxcombo(ans))
53+
ans <- data.frame(p_value = pvalue_maxcombo(ans))
5454

5555
return(ans)
5656
}

R/rmst.R

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,25 @@
2525
#' @param var_label_tte Column name of the TTE variable.
2626
#' @param var_label_event Column name of the event variable.
2727
#' @param var_label_group Column name of the grouping variable.
28+
#' @param formula (default: `NULL`) A formula that indicates the TTE, event, and
29+
#' group variables (in that exact order; see Details below). This is an
30+
#' alternative to specifying the variables as strings. If a formula is
31+
#' provided, the values passed to `var_label_tte`, `var_label_event`, and
32+
#' `var_label_group` are ignored.
2833
#' @param reference A group label indicating the reference group.
2934
#' @param alpha Type I error.
3035
#'
36+
#' @details
37+
#' The argument `formula` is provided as a convenience to easily specify the TTE,
38+
#' event, and grouping variables. Note however that only the order of the three
39+
#' variables is actually used by the underlying function. Any functions applied
40+
#' in the formula are ignored, and thus should only be used for documenting your
41+
#' intent. For example, you can use the syntax from the survival package
42+
#' `Surv(tte | event) ~ group` to highlight the relation between the TTE and
43+
#' event variables, but the function `Surv()` is never actually executed.
44+
#' Importantly, you shouldn't apply any transformation functions such as `log()`
45+
#' since these will also be ignored.
46+
#'
3147
#' @return The z statistics.
3248
#'
3349
#' @export
@@ -42,14 +58,55 @@
4258
#' tau = 10,
4359
#' reference = "0"
4460
#' )
61+
#'
62+
#' # Formula interface
63+
#' library("survival")
64+
#'
65+
#' rmst(
66+
#' data = ex1_delayed_effect,
67+
#' formula = Surv(month | evntd) ~ trt,
68+
#' tau = 10,
69+
#' reference = "0"
70+
#' )
71+
#'
72+
#' # alternative
73+
#' rmst(
74+
#' data = ex1_delayed_effect,
75+
#' formula = ~ Surv(month, evntd, trt),
76+
#' tau = 10,
77+
#' reference = "0"
78+
#' )
79+
#'
80+
#' # This example doesn't make statistical sense, but demonstrates that only the
81+
#' # order of the 3 variables actually matters
82+
#' rmst(
83+
#' data = ex1_delayed_effect,
84+
#' formula = month ~ evntd + trt,
85+
#' tau = 10,
86+
#' reference = "0"
87+
#' )
4588
rmst <- function(
4689
data,
4790
tau = 10,
4891
var_label_tte = "tte",
4992
var_label_event = "event",
5093
var_label_group = "treatment",
94+
formula = NULL,
5195
reference = "control",
5296
alpha = 0.05) {
97+
stopifnot(is.data.frame(data))
98+
99+
if (!is.null(formula)) {
100+
stopifnot(inherits(formula, "formula"))
101+
variables <- colnames(stats::get_all_vars(formula = formula, data = data))
102+
if (length(variables) != 3) {
103+
stop("The formula interface requires exactly 3 variables specified")
104+
}
105+
var_label_tte <- variables[1]
106+
var_label_event <- variables[2]
107+
var_label_group <- variables[3]
108+
}
109+
53110
res <- rmst_two_arm(
54111
time_var = data[[var_label_tte]],
55112
event_var = data[[var_label_event]],

R/sim_gs_n.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ sim_gs_n <- function(
285285

286286
for (i_analysis in seq_len(n_analysis)) {
287287
# Get cut date
288-
cut_date[i_analysis] <- cutting[[i_analysis]](data = simu_data)
288+
cut_date[i_analysis] <- cutting[[i_analysis]](simu_data)
289289

290290
# Cut the data
291291
simu_data_cut <- simu_data |> cut_data_by_date(cut_date[i_analysis])

R/wlr.R

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,35 +40,35 @@
4040
#' cut_data_by_event(150) |>
4141
#' wlr(weight = early_zero(early_period = 4))
4242
#'
43-
wlr <- function(data, weight){
44-
43+
wlr <- function(data, weight) {
4544
if (inherits(weight, "fh")) {
4645
ans <- data |>
4746
counting_process(arm = "experimental") |>
4847
fh_weight(rho_gamma = data.frame(rho = weight$rho, gamma = weight$gamma))
49-
5048
} else if (inherits(weight, "mb")) {
5149
ans <- data |>
5250
counting_process(arm = "experimental") |>
5351
mb_weight(delay = weight$delay, w_max = weight$w_max)
5452
setDT(ans)
55-
ans <- ans[,
56-
.(
57-
s = sum(o_minus_e * mb_weight),
58-
v = sum(var_o_minus_e * mb_weight^2)
59-
)
53+
ans <- ans[
54+
,
55+
.(
56+
s = sum(o_minus_e * mb_weight),
57+
v = sum(var_o_minus_e * mb_weight^2)
58+
)
6059
][, .(z = s / sqrt(v))]
6160
setDF(ans)
6261
} else if (inherits(weight, "early_period")) {
6362
ans <- data |>
6463
counting_process(arm = "experimental") |>
6564
early_zero_weight(early_period = weight$early_period)
6665
setDT(ans)
67-
ans <- ans[,
68-
.(
69-
s = sum(o_minus_e * weight),
70-
v = sum(var_o_minus_e * weight^2)
71-
)
66+
ans <- ans[
67+
,
68+
.(
69+
s = sum(o_minus_e * weight),
70+
v = sum(var_o_minus_e * weight^2)
71+
)
7272
][, .(z = s / sqrt(v))]
7373
setDF(ans)
7474
}

R/wlr_weight.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#' @return A list of parameters of the Fleming-Harrington weighting function
2626
#' @examples
2727
#' fh(rho = 0, gamma = 0.5)
28-
fh <- function(rho = 0, gamma = 0){
28+
fh <- function(rho = 0, gamma = 0) {
2929
structure(list(rho = rho, gamma = gamma), class = c("list", "fh", "wlr"))
3030
}
3131

@@ -42,7 +42,7 @@ fh <- function(rho = 0, gamma = 0){
4242
#'
4343
#' @examples
4444
#' mb(delay = 6, w_max = 2)
45-
mb <- function(delay = 4, w_max = Inf){
45+
mb <- function(delay = 4, w_max = Inf) {
4646
structure(list(delay = delay, w_max = w_max), class = c("list", "mb", "wlr"))
4747
}
4848

@@ -59,6 +59,6 @@ mb <- function(delay = 4, w_max = Inf){
5959
#'
6060
#' @examples
6161
#' early_zero(6)
62-
early_zero <- function(early_period){
62+
early_zero <- function(early_period) {
6363
structure(list(early_period = early_period), class = c("list", "early_period", "wlr"))
6464
}

man/rmst.Rd

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

tests/testthat/helper-pmvnorm.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ ptvnorm <- function(h, r, ro) {
137137
hp2 <- (h2 * rr133 - h1 * f3 - h3 * f2) / fac / sqrt(rr133)
138138
TV <- w * exp((rr12 * h12 - h122) / rr122) / sqrt(rr122) * pnorm(hp1) *
139139
r12 + w * exp((rr13 * h13 - h132) / rr133) / sqrt(rr133) * pnorm(hp2) *
140-
r13
140+
r13
141141
TV <- sum(TV)
142142
rho <- matrix(c(1, r23, r23, 1), 2, 2)
143143
p2 <- mvtnorm::pmvnorm(-Inf, c(h2, h3), c(0, 0), rho)

tests/testthat/helper-sim_gs_n.R

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,26 @@
33
test_enroll_rate <- function() {
44
# parameters for enrollment
55
enroll_rampup_duration <- 4 # duration for enrollment ramp up
6-
enroll_duration <- 16 # total enrollment duration
6+
enroll_duration <- 16 # total enrollment duration
77
enroll_rate <- gsDesign2::define_enroll_rate(
8-
duration = c(enroll_rampup_duration,
9-
enroll_duration - enroll_rampup_duration),
8+
duration = c(
9+
enroll_rampup_duration,
10+
enroll_duration - enroll_rampup_duration
11+
),
1012
rate = c(10, 30)
1113
)
1214
return(enroll_rate)
1315
}
1416

1517
test_fail_rate <- function() {
1618
# parameters for treatment effect
17-
delay_effect_duration <- 3 # delay treatment effect in months
18-
median_ctrl <- 9 # survival median of the control arm
19-
median_exp <- c(9, 14) # survival median of the experimental arm
19+
delay_effect_duration <- 3 # delay treatment effect in months
20+
median_ctrl <- 9 # survival median of the control arm
21+
median_exp <- c(9, 14) # survival median of the experimental arm
2022
dropout_rate <- 0.001
2123
fail_rate <- gsDesign2::define_fail_rate(
2224
duration = c(delay_effect_duration, 100),
23-
fail_rate = log(2) / median_ctrl,
25+
fail_rate = log(2) / median_ctrl,
2426
hr = median_ctrl / median_exp,
2527
dropout_rate = dropout_rate
2628
)
@@ -29,9 +31,9 @@ test_fail_rate <- function() {
2931

3032
test_cutting <- function() {
3133
# other related parameters
32-
alpha <- 0.025 # type I error
33-
beta <- 0.1 # type II error
34-
ratio <- 1 # randomization ratio (exp:ctrl)
34+
alpha <- 0.025 # type I error
35+
beta <- 0.1 # type II error
36+
ratio <- 1 # randomization ratio (exp:ctrl)
3537
# Define cuttings of 2 IAs and 1 FA
3638
# IA1
3739
# The 1st interim analysis will occur at the later of the following 3 conditions:

tests/testthat/helper-simfix.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Helper functions used by test-double_programming_simfix.R
22

3-
test_simfix <- function () {
3+
test_simfix <- function() {
44
# Study design using gsDesign
55
alpha <- 0.025
66
gamma <- c(5, 5, 47)

0 commit comments

Comments
 (0)