Skip to content

Commit c92e9e2

Browse files
Correct the minor formula mistakes in gs_info_rd (#615)
* Correct the formula mistake and add developer tests to `gs_info_rd` * Remove `gs_info_rd_` from developer testing and verify the weight via the aggregated info0, info1 * update NEWS.md
1 parent bc27a8a commit c92e9e2

3 files changed

Lines changed: 93 additions & 5 deletions

File tree

NEWS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## New features
44

5-
- The minimal risk weighting strategy has been added to `gs_design_rd()` and `gs_power_rd()` for risk difference design (#611, thanks to @LittleBeannie).
5+
- 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

88
# gsDesign2 1.1.8

R/gs_info_rd.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -248,11 +248,11 @@ gs_info_rd <- function(
248248
) |>
249249
ungroup() |>
250250
group_by(analysis) |>
251-
mutate(alpha_per_k_per_s = (p_c - p_e) * sum_inv_var_per_s - sum((p_c - p_e) / sigma2_H1_per_k_per_s),
252-
beta_per_k_per_s = 1/sigma2_H1_per_k_per_s * (1 + alpha_per_k_per_s * sum((p_c - p_e) * n / max(n))),
251+
mutate(alpha_per_k_per_s = (p_e - p_c) * sum_inv_var_per_s - sum((p_e - p_c) / sigma2_H1_per_k_per_s),
252+
beta_per_k_per_s = 1/sigma2_H1_per_k_per_s * (1 + alpha_per_k_per_s * sum((p_e - p_c) * n / sum(n))),
253253
weight_per_k_per_s = beta_per_k_per_s / sum_inv_var_per_s -
254-
alpha_per_k_per_s / sigma2_H1_per_k_per_s / (sum_inv_var_per_s + sum(alpha_per_k_per_s * (p_c - p_e) / sigma2_H1_per_k_per_s)) *
255-
sum((p_c - p_e) * beta_per_k_per_s) / sum_inv_var_per_s
254+
alpha_per_k_per_s / sigma2_H1_per_k_per_s / (sum_inv_var_per_s + sum(alpha_per_k_per_s * (p_e - p_c) / sigma2_H1_per_k_per_s)) *
255+
sum((p_e - p_c) * beta_per_k_per_s) / sum_inv_var_per_s
256256
) |>
257257
select(-c(sum_inv_var_per_s, alpha_per_k_per_s, beta_per_k_per_s))
258258
)
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
test_that("Testing weights calculation", {
2+
3+
# This example following the second example in the paper "Minimum risk weights for comparing treatments in stratified binomial trials"
4+
p_c <- data.frame(stratum = c("Stratum1", "Stratum2"), rate = c(0.48, 0.8))
5+
p_e <- data.frame(stratum = c("Stratum1", "Stratum2"), rate = c(0.53, 0.95))
6+
n <- data.frame(stratum = c("Stratum1", "Stratum2"), n = c(63, 37), analysis = 1)
7+
8+
# sample size
9+
n_c_stratum1 <- n$n[1] / 2
10+
n_e_stratum1 <- n$n[1] / 2
11+
n_c_stratum2 <- n$n[2] / 2
12+
n_e_stratum2 <- n$n[2] / 2
13+
n_stratum1 <- n_c_stratum1 + n_e_stratum1
14+
n_stratum2 <- n_c_stratum2 + n_e_stratum2
15+
16+
# failure rate
17+
p_c_stratum1 <- p_c$rate[1]
18+
p_e_stratum1 <- p_e$rate[1]
19+
p_c_stratum2 <- p_c$rate[2]
20+
p_e_stratum2 <- p_e$rate[2]
21+
p_pool_stratum1 <- (p_c_stratum1 + p_e_stratum1)/2
22+
p_pool_stratum2 <- (p_c_stratum2 + p_e_stratum2)/2
23+
24+
# variance for each stratum under H1
25+
var_H1_stratum1 <- p_c_stratum1 * (1 - p_c_stratum1) / n_c_stratum1 + p_e_stratum1 * (1 - p_e_stratum1) / n_e_stratum1
26+
var_H1_stratum2 <- p_c_stratum2 * (1 - p_c_stratum2) / n_c_stratum2 + p_e_stratum2 * (1 - p_e_stratum2) / n_e_stratum2
27+
28+
# variance for each stratum under H0
29+
var_H0_stratum1 <- p_pool_stratum1 * (1 - p_pool_stratum1) * (1/n_c_stratum1 + 1/n_e_stratum1)
30+
var_H0_stratum2 <- p_pool_stratum2 * (1 - p_pool_stratum2) * (1/n_c_stratum2 + 1/n_e_stratum2)
31+
32+
# Testing the INVAR weight via the aggregated info0, info1
33+
# the weight 0.41 and 0.59 comes from Table IV of "Minimum risk weights for comparing treatments in stratified binomial trials"
34+
x <- gs_info_rd(p_c = p_c, p_e = p_e, n = n, rd0 = 0, ratio = 1, weight = "invar")
35+
36+
expect_equal(1/x$info0,
37+
0.41^2 * p_pool_stratum1 * (1 - p_pool_stratum1) * (1 / n_c_stratum1 + 1 / n_e_stratum1) +
38+
0.59^2 * p_pool_stratum2 * (1 - p_pool_stratum2) * (1 / n_c_stratum2 + 1 / n_e_stratum2),
39+
tolerance = 1e-4)
40+
41+
expect_equal(1/x$info1,
42+
0.41^2 * p_c_stratum1 * (1 - p_c_stratum1) / n_c_stratum1 + 0.41^2 * p_e_stratum1 * (1 - p_e_stratum1) / n_e_stratum1 +
43+
0.59^2 * p_c_stratum2 * (1 - p_c_stratum2) / n_c_stratum2 + 0.59^2 * p_e_stratum2 * (1 - p_e_stratum2) / n_e_stratum2,
44+
tolerance = 1e-4)
45+
46+
# Testing the SS weight via the aggregated info0, info1
47+
# the weight 0.63 and 0.37 comes from Table IV of "Minimum risk weights for comparing treatments in stratified binomial trials"
48+
x <- gs_info_rd(p_c = p_c, p_e = p_e, n = n, rd0 = 0, ratio = 1, weight = "ss")
49+
50+
expect_equal(1/x$info0,
51+
0.63^2 * p_pool_stratum1 * (1 - p_pool_stratum1) * (1 / n_c_stratum1 + 1 / n_e_stratum1) +
52+
0.37^2 * p_pool_stratum2 * (1 - p_pool_stratum2) * (1 / n_c_stratum2 + 1 / n_e_stratum2),
53+
tolerance = 1e-4)
54+
55+
expect_equal(1/x$info1,
56+
0.63^2 * p_c_stratum1 * (1 - p_c_stratum1) / n_c_stratum1 + 0.63^2 * p_e_stratum1 * (1 - p_e_stratum1) / n_e_stratum1 +
57+
0.37^2 * p_c_stratum2 * (1 - p_c_stratum2) / n_c_stratum2 + 0.37^2 * p_e_stratum2 * (1 - p_e_stratum2) / n_e_stratum2,
58+
tolerance = 1e-4)
59+
60+
# Testing the MR weight following formula (10)
61+
# the weight 0.47 and 0.53 comes from Table IV of "Minimum risk weights for comparing treatments in stratified binomial trials"
62+
x_mr <- gs_info_rd(p_c = p_c, p_e = p_e, n = n, rd0 = 0, ratio = 1, weight = "mr")
63+
V1 <- var_H1_stratum1
64+
V2 <- var_H1_stratum2
65+
delta1 <- p_e_stratum1 - p_c_stratum1
66+
delta2 <- p_e_stratum2 - p_c_stratum2
67+
f1 <- n_stratum1 / (n_stratum1 + n_stratum2)
68+
f2 <- n_stratum2 / (n_stratum1 + n_stratum2)
69+
70+
w1 <- (V2+(delta1-delta2)^2*f1) / (V1 + V2 + (delta1 - delta2)^2)
71+
w2 <- 1 - w1
72+
expect_equal(c(w1, w2), c(0.47, 0.53), tolerance = 5e-3)
73+
74+
x <- gs_info_rd(p_c = p_c, p_e = p_e, n = n, rd0 = 0, ratio = 1, weight = "mr")
75+
76+
expect_equal(1/x$info0,
77+
w1^2 * p_pool_stratum1 * (1 - p_pool_stratum1) * (1 / n_c_stratum1 + 1 / n_e_stratum1) +
78+
w2^2 * p_pool_stratum2 * (1 - p_pool_stratum2) * (1 / n_c_stratum2 + 1 / n_e_stratum2),
79+
tolerance = 1e-4)
80+
81+
expect_equal(1/x$info1,
82+
w1^2 * p_c_stratum1 * (1 - p_c_stratum1) / n_c_stratum1 + w1^2 * p_e_stratum1 * (1 - p_e_stratum1) / n_e_stratum1 +
83+
w2^2 * p_c_stratum2 * (1 - p_c_stratum2) / n_c_stratum2 + w2^2 * p_e_stratum2 * (1 - p_e_stratum2) / n_e_stratum2,
84+
tolerance = 1e-4)
85+
86+
87+
})
88+

0 commit comments

Comments
 (0)