Skip to content

Commit b23e559

Browse files
committed
Remove gs_info_rd_ from developer testing and verify the weight via the aggregated info0, info1
1 parent a12f99e commit b23e559

File tree

1 file changed

+71
-118
lines changed

1 file changed

+71
-118
lines changed

tests/testthat/test-developer-gs_info_rd.R

Lines changed: 71 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,134 +1,87 @@
11
test_that("Testing weights calculation", {
22

3-
# The following function is almost the same as gs_info_rd.
4-
# The only difference is that:
5-
# gs_info_rd returns `ans`
6-
# gs_info_rd_ returns `tbl` with out removing columns
7-
# If there is a suggested way to avoid copy-pasting these similar functions, please let me know!
8-
gs_info_rd_ <- function(p_c = tibble::tibble(stratum = "All", rate = .2),
9-
p_e = tibble::tibble(stratum = "All", rate = .15),
10-
n = tibble::tibble(stratum = "All", n = c(100, 200, 300), analysis = 1:3),
11-
rd0 = 0, ratio = 1, weight = c("unstratified", "ss", "invar", "mr")) {
12-
13-
n_analysis <- max(n$analysis)
14-
weight <- match.arg(weight)
15-
16-
# Pool the input arguments together ----
17-
suppressMessages(
18-
tbl <- n |>
19-
left_join(p_c) |>
20-
rename(p_c = rate) |>
21-
left_join(p_e) |>
22-
rename(p_e = rate) |>
23-
left_join(if ("data.frame" %in% class(rd0)) {
24-
rd0
25-
} else {
26-
tibble(analysis = 1:n_analysis, rd0 = rd0)
27-
}) |>
28-
mutate(
29-
n_e = n / (1 + ratio),
30-
n_c = n * ratio / (1 + ratio),
31-
d = ifelse(p_c > p_e, 1, -1),
32-
p_pool_per_k_per_s = (n_c * p_c + n_e * p_e) / n,
33-
p_e0 = (p_c + ratio * p_e - d * rd0) / (ratio + 1),
34-
p_c0 = p_e0 + d * rd0
35-
)
36-
)
37-
38-
# Calculate the variance of the risk difference ----
39-
if (is.numeric(rd0) && rd0 == 0) {
40-
tbl <- tbl |> mutate(
41-
sigma2_H0_per_k_per_s = p_pool_per_k_per_s * (1 - p_pool_per_k_per_s) * (1 / n_c + 1 / n_e),
42-
sigma2_H1_per_k_per_s = p_c * (1 - p_c) / n_c + p_e * (1 - p_e) / n_e
43-
)
44-
} else if ("data.frame" %in% class(rd0) || rd0 != 0) {
45-
tbl <- tbl |> mutate(
46-
sigma2_H0_per_k_per_s = p_c0 * (1 - p_c0) / n_c + p_e0 * (1 - p_e0) / n_e,
47-
sigma2_H1_per_k_per_s = p_c * (1 - p_c) / n_c + p_e * (1 - p_e) / n_e
48-
)
49-
}
50-
51-
# Assign weights ----
52-
if (weight == "unstratified") {
53-
tbl <- tbl |> mutate(weight_per_k_per_s = 1)
54-
} else if (weight == "ss") {
55-
suppressMessages(
56-
tbl <- tbl |>
57-
left_join(
58-
tbl |>
59-
group_by(analysis) |>
60-
summarize(sum_ss = sum(n_c * n_e / (n_c + n_e)))
61-
) |>
62-
mutate(weight_per_k_per_s = n_c * n_e / (n_c + n_e) / sum_ss) |>
63-
select(-sum_ss)
64-
)
65-
} else if (weight == "invar") {
66-
suppressMessages(
67-
tbl <- tbl |>
68-
left_join(
69-
tbl |>
70-
group_by(analysis) |>
71-
summarize(sum_inv_var_per_s = sum(1 / sigma2_H1_per_k_per_s))
72-
) |>
73-
mutate(weight_per_k_per_s = 1 / sigma2_H1_per_k_per_s / sum_inv_var_per_s) |>
74-
select(-sum_inv_var_per_s)
75-
)
76-
} else if (weight == "mr") {
77-
suppressMessages(
78-
tbl <- tbl |>
79-
left_join(
80-
tbl |>
81-
group_by(analysis) |>
82-
summarize(sum_inv_var_per_s = sum(1 / sigma2_H1_per_k_per_s))
83-
) |>
84-
ungroup() |>
85-
group_by(analysis) |>
86-
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),
87-
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))),
88-
weight_per_k_per_s = beta_per_k_per_s / sum_inv_var_per_s -
89-
(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))) *
90-
(sum((p_e - p_c) * beta_per_k_per_s) / sum_inv_var_per_s)
91-
) # |>
92-
# select(-c(sum_inv_var_per_s, alpha_per_k_per_s, beta_per_k_per_s))
93-
)
94-
}
95-
96-
return(tbl)
97-
}
98-
993
# This example following the second example in the paper "Minimum risk weights for comparing treatments in stratified binomial trials"
1004
p_c <- data.frame(stratum = c("Stratum1", "Stratum2"), rate = c(0.48, 0.8))
1015
p_e <- data.frame(stratum = c("Stratum1", "Stratum2"), rate = c(0.53, 0.95))
1026
n <- data.frame(stratum = c("Stratum1", "Stratum2"), n = c(63, 37), analysis = 1)
1037

104-
# Testing the INVAR weight
105-
weight_invar <- gs_info_rd_(p_c = p_c, p_e = p_e, n = n, rd0 = 0, ratio = 1, weight = "invar")$weight_per_k_per_s
106-
expect_equal(weight_invar, c(0.41, 0.59), tolerance = 1e-2)
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)
10740

108-
# Testing the SS weight
109-
weight_ss <- gs_info_rd_(p_c = p_c, p_e = p_e, n = n, rd0 = 0, ratio = 1, weight = "ss")$weight_per_k_per_s
110-
expect_equal(weight_ss, c(0.63, 0.37), tolerance = 1e-2)
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)
11159

11260
# Testing the MR weight following formula (10)
113-
x_mr <- gs_info_rd_(p_c = p_c, p_e = p_e, n = n, rd0 = 0, ratio = 1, weight = "mr")
114-
V1 <- x_mr$sigma2_H1_per_k_per_s[1]
115-
V2 <- x_mr$sigma2_H1_per_k_per_s[2]
116-
delta1 <- x_mr$p_e[1] - x_mr$p_c[1]
117-
delta2 <- x_mr$p_e[2] - x_mr$p_c[2]
118-
f1 <- x_mr$n[1] / sum(x_mr$n)
119-
f2 <- x_mr$n[2] / sum(x_mr$n)
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)
12069

12170
w1 <- (V2+(delta1-delta2)^2*f1) / (V1 + V2 + (delta1 - delta2)^2)
12271
w2 <- 1 - w1
123-
expect_equal(gs_info_rd_(p_c = p_c, p_e = p_e, n = n, rd0 = 0, ratio = 1, weight = "mr")$weight_per_k_per_s,
124-
c(w1, w2))
125-
126-
# Note that if is risk difference is constant across strata,then alpha_per_k_per_s is zero
127-
expect_equal(gs_info_rd_(p_c = data.frame(stratum = c("Stratum1", "Stratum2"), rate = c(0.4, 0.8)),
128-
p_e = data.frame(stratum = c("Stratum1", "Stratum2"), rate = c(0.5, 0.9)),
129-
n = data.frame(stratum = c("Stratum1", "Stratum2"), n = c(50, 50), analysis = 1),
130-
rd0 = 0, ratio = 1, weight = "mr")$alpha_per_k_per_s,
131-
c(0, 0))
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)
13285

13386

13487
})

0 commit comments

Comments
 (0)