1 Test 1: Examples from spec

1.1 Default

The default of gs_power_npe is a single analysis with type I error controlled.

x1 <- gs_power_npe(theta = 0) %>% filter(bound == "upper")
x2 <- gs_power_npe_(theta = 0) %>% filter(Bound == "Upper")
analysis bound z probability theta theta1 info_frac info info0 info1 Computated from
1 upper 1.959964 0.025 0 0 1 1 1 1 new version
1 Upper 1.959964 0.025 0 0 NA 1 1 1 old version

1.2 Fixed bound

x1 <- gs_power_npe(
  theta = c(.1, .2, .3),
  info = (1:3) * 40,
  upper = gs_b,
  upar = gsDesign::gsDesign(k = 3, sfu = gsDesign::sfLDOF)$upper$bound,
  lower = gs_b,
  lpar = c(-1, 0, 0)
) %>% mutate(`Computated from` = "new version")

x2 <- gs_power_npe_(
  theta = c(.1, .2, .3),
  info = (1:3) * 40,
  upper = gs_b,
  upar = gsDesign::gsDesign(k = 3, sfu = gsDesign::sfLDOF)$upper$bound,
  lower = gs_b,
  lpar = c(-1, 0, 0)
) %>% mutate(`Computated from` = "old version")
analysis bound z probability theta theta1 info_frac info info0 info1 Computated from
1 upper 3.710303 0.001042508 0.1 0.1 0.3333333 40 40 40 new version
2 upper 2.511427 0.234899008 0.2 0.2 0.6666667 80 80 80 new version
3 upper 1.993048 0.868689026 0.3 0.3 1.0000000 120 120 120 new version
1 lower -1.000000 0.051291779 0.1 0.1 0.3333333 40 40 40 new version
2 lower 0.000000 0.071509147 0.2 0.2 0.6666667 80 80 80 new version
3 lower 0.000000 0.071522125 0.3 0.3 1.0000000 120 120 120 new version
1 Upper 3.710303 0.001042508 0.1 0.1 NA 40 40 40 old version
2 Upper 2.511427 0.234899008 0.2 0.2 NA 80 80 80 old version
3 Upper 1.993048 0.868689026 0.3 0.3 NA 120 120 120 old version
1 Lower -1.000000 0.051291779 0.1 0.1 NA 40 40 40 old version
2 Lower 0.000000 0.071509147 0.2 0.2 NA 80 80 80 old version
3 Lower 0.000000 0.071522125 0.3 0.3 NA 120 120 120 old version

1.3 Same fixed efficacy bounds, no futility bound (i.e., non-binding bound), null hypothesis

x1 <- gs_power_npe(
  theta = rep(0, 3),
  info = (1:3) * 40,
  upar = gsDesign::gsDesign(k = 3, sfu = gsDesign::sfLDOF)$upper$bound,
  lpar = rep(-Inf, 3)
) %>% mutate(`Computated from` = "new version")

x2 <- gs_power_npe_(
  theta = rep(0, 3),
  info = (1:3) * 40,
  upar = gsDesign::gsDesign(k = 3, sfu = gsDesign::sfLDOF)$upper$bound,
  lpar = rep(-Inf, 3)
) %>% mutate(`Computated from` = "old version")
analysis bound z probability theta theta1 info_frac info info0 info1 Computated from
1 upper 3.710303 0.0001035057 0 0 0.3333333 40 40 40 new version
2 upper 2.511427 0.0060485045 0 0 0.6666667 80 80 80 new version
3 upper 1.993048 0.0250002354 0 0 1.0000000 120 120 120 new version
1 lower -Inf 0.0000000000 0 0 0.3333333 40 40 40 new version
2 lower -Inf 0.0000000000 0 0 0.6666667 80 80 80 new version
3 lower -Inf 0.0000000000 0 0 1.0000000 120 120 120 new version
1 Upper 3.710303 0.0001035057 0 0 NA 40 40 40 old version
2 Upper 2.511427 0.0060485045 0 0 NA 80 80 80 old version
3 Upper 1.993048 0.0250002354 0 0 NA 120 120 120 old version
1 Lower -Inf 0.0000000000 0 0 NA 40 40 40 old version
2 Lower -Inf 0.0000000000 0 0 NA 80 80 80 old version
3 Lower -Inf 0.0000000000 0 0 NA 120 120 120 old version

1.4 Fixed bound with futility only at analysis 1; efficacy only at analyses 2, 3

x1 <- gs_power_npe(
  theta = c(.1, .2, .3),
  info = (1:3) * 40,
  upper = gs_b,
  upar = c(Inf, 3, 2),
  lower = gs_b,
  lpar = c(qnorm(.1), -Inf, -Inf)
) %>% mutate(`Computated from` = "new version")

x2 <- gs_power_npe_(
  theta = c(.1, .2, .3),
  info = (1:3) * 40,
  upper = gs_b,
  upar = c(Inf, 3, 2),
  lower = gs_b,
  lpar = c(qnorm(.1), -Inf, -Inf)
) %>% mutate(`Computated from` = "old version")
analysis bound z probability theta theta1 info_frac info info0 info1 Computated from
1 upper Inf 0.00000000 0.1 0.1 0.3333333 40 40 40 new version
2 upper 3.000000 0.11291848 0.2 0.2 0.6666667 80 80 80 new version
3 upper 2.000000 0.88742529 0.3 0.3 1.0000000 120 120 120 new version
1 lower -1.281552 0.02780962 0.1 0.1 0.3333333 40 40 40 new version
2 lower -Inf 0.02780962 0.2 0.2 0.6666667 80 80 80 new version
3 lower -Inf 0.02780962 0.3 0.3 1.0000000 120 120 120 new version
1 Upper Inf 0.00000000 0.1 0.1 NA 40 40 40 old version
2 Upper 3.000000 0.11291848 0.2 0.2 NA 80 80 80 old version
3 Upper 2.000000 0.88742529 0.3 0.3 NA 120 120 120 old version
1 Lower -1.281552 0.02780962 0.1 0.1 NA 40 40 40 old version
2 Lower -Inf 0.02780962 0.2 0.2 NA 80 80 80 old version
3 Lower -Inf 0.02780962 0.3 0.3 NA 120 120 120 old version

1.5 Spending function bounds

# Lower spending based on non-zero effect
x1 <- gs_power_npe(
  theta = c(.1, .2, .3),
  info = (1:3) * 40,
  upper = gs_spending_bound,
  upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL),
  lower = gs_spending_bound,
  lpar = list(sf = gsDesign::sfHSD, total_spend = 0.1, param = -1, timing = NULL)
) %>% mutate(`Computated from` = "new version")

x2 <- gs_power_npe_(
  theta = c(.1, .2, .3),
  info = (1:3) * 40,
  upper = gs_spending_bound,
  upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL),
  lower = gs_spending_bound,
  lpar = list(sf = gsDesign::sfHSD, total_spend = 0.1, param = -1, timing = NULL)
) %>% mutate(`Computated from` = "old version")
analysis bound z probability theta theta1 info_frac info info0 info1 Computated from
1 upper 3.71030287 0.001042508 0.1 0.1 0.3333333 40 40 40 new version
2 upper 2.51143381 0.234968841 0.2 0.2 0.6666667 80 80 80 new version
3 upper 1.99305108 0.882718886 0.3 0.3 1.0000000 120 120 120 new version
1 lower -1.36250263 0.023023722 0.1 0.1 0.3333333 40 40 40 new version
2 lower 0.07264138 0.055155914 0.2 0.2 0.6666667 80 80 80 new version
3 lower 1.85908660 0.100000000 0.3 0.3 1.0000000 120 120 120 new version
1 Upper 3.71030287 0.001042508 0.1 0.1 NA 40 40 40 old version
2 Upper 2.51143381 0.234968841 0.2 0.2 NA 80 80 80 old version
3 Upper 1.99305108 0.882718886 0.3 0.3 NA 120 120 120 old version
1 Lower -1.36250263 0.023023722 0.1 0.1 NA 40 40 40 old version
2 Lower 0.07264138 0.055155914 0.2 0.2 NA 80 80 80 old version
3 Lower 1.85908660 0.100000000 0.3 0.3 NA 120 120 120 old version

1.6 Same bounds, but power under different theta

x1 <- gs_power_npe(
  theta = c(.15, .25, .35),
  info = (1:3) * 40,
  upper = gs_spending_bound,
  upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL),
  lower = gs_spending_bound,
  lpar = list(sf = gsDesign::sfHSD, total_spend = 0.1, param = -1, timing = NULL)
) %>% mutate(`Computated from` = "new version")

x2 <- gs_power_npe_(
  theta = c(.15, .25, .35),
  info = (1:3) * 40,
  upper = gs_spending_bound,
  upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL),
  lower = gs_spending_bound,
  lpar = list(sf = gsDesign::sfHSD, total_spend = 0.1, param = -1, timing = NULL)
) %>% mutate(`Computated from` = "old version")
analysis bound z probability theta theta1 info_frac info info0 info1 Computated from
1 upper 3.710303 0.002875773 0.15 0.15 0.3333333 40 40 40 new version
2 upper 2.511434 0.391439113 0.25 0.25 0.6666667 80 80 80 new version
3 upper 1.993051 0.931364287 0.35 0.35 1.0000000 120 120 120 new version
1 lower -1.046275 0.023023722 0.15 0.15 0.3333333 40 40 40 new version
2 lower 0.519855 0.055155914 0.25 0.25 0.6666667 80 80 80 new version
3 lower 2.408073 0.100000000 0.35 0.35 1.0000000 120 120 120 new version
1 Upper 3.710303 0.002875773 0.15 0.15 NA 40 40 40 old version
2 Upper 2.511434 0.391439113 0.25 0.25 NA 80 80 80 old version
3 Upper 1.993051 0.931364287 0.35 0.35 NA 120 120 120 old version
1 Lower -1.046275 0.023023722 0.15 0.15 NA 40 40 40 old version
2 Lower 0.519855 0.055155914 0.25 0.25 NA 80 80 80 old version
3 Lower 2.408073 0.100000000 0.35 0.35 NA 120 120 120 old version

1.7 Two-sided symmetric spend, O’Brien-Fleming spending

Typically, 2-sided bounds are binding

x1 <- gs_power_npe(
  theta = rep(0, 3),
  info = (1:3) * 40,
  binding = TRUE,
  upper = gs_spending_bound,
  upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL),
  lower = gs_spending_bound,
  lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL)
) %>% mutate(`Computated from` = "new version")

x2 <- gs_power_npe_(
  theta = rep(0, 3),
  info = (1:3) * 40,
  binding = TRUE,
  upper = gs_spending_bound,
  upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL),
  lower = gs_spending_bound,
  lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL)
) %>% mutate(`Computated from` = "old version")
analysis bound z probability theta theta1 info_frac info info0 info1 Computated from
1 upper 3.710303 0.0001035057 0 0 0.3333333 40 40 40 new version
2 upper 2.511434 0.0060483891 0 0 0.6666667 80 80 80 new version
3 upper 1.993051 0.0250000000 0 0 1.0000000 120 120 120 new version
1 lower -3.710303 0.0001035057 0 0 0.3333333 40 40 40 new version
2 lower -2.511434 0.0060483891 0 0 0.6666667 80 80 80 new version
3 lower -1.993051 0.0250000000 0 0 1.0000000 120 120 120 new version
1 Upper 3.710303 0.0001035057 0 0 NA 40 40 40 old version
2 Upper 2.511434 0.0060483891 0 0 NA 80 80 80 old version
3 Upper 1.993051 0.0250000000 0 0 NA 120 120 120 old version
1 Lower -3.710303 0.0001035057 0 0 NA 40 40 40 old version
2 Lower -2.511434 0.0060483891 0 0 NA 80 80 80 old version
3 Lower -1.993051 0.0250000000 0 0 NA 120 120 120 old version

1.8 Re-use these bounds under alternate hypothesis

Always use binding = TRUE for power calculations

xx1 <- gs_power_npe(
  theta = c(.1, .2, .3),
  info = (1:3) * 40,
  binding = TRUE,
  upar = (x1 %>% filter(bound == "upper"))$z,
  lpar = -(x1 %>% filter(bound == "upper"))$z
) %>% mutate(`Computated from` = "new version")

xx2 <- gs_power_npe_(
  theta = c(.1, .2, .3),
  info = (1:3) * 40,
  binding = TRUE,
  upar = (x1 %>% filter(bound == "upper"))$z,
  lpar = -(x1 %>% filter(bound == "upper"))$z
) %>% mutate(`Computated from` = "old version")
analysis bound z probability theta theta1 info_frac info info0 info1 Computated from
1 upper 3.710303 1.042508e-03 0.1 0.1 0.3333333 40 40 40 new version
2 upper 2.511434 2.349812e-01 0.2 0.2 0.6666667 80 80 80 new version
3 upper 1.993051 9.020711e-01 0.3 0.3 1.0000000 120 120 120 new version
1 lower -3.710303 7.035242e-06 0.1 0.1 0.3333333 40 40 40 new version
2 lower -2.511434 1.510031e-05 0.2 0.2 0.6666667 80 80 80 new version
3 lower -1.993051 1.512598e-05 0.3 0.3 1.0000000 120 120 120 new version
1 Upper 3.710303 1.042508e-03 0.1 0.1 NA 40 40 40 old version
2 Upper 2.511434 2.349812e-01 0.2 0.2 NA 80 80 80 old version
3 Upper 1.993051 9.020711e-01 0.3 0.3 NA 120 120 120 old version
1 Lower -3.710303 7.035242e-06 0.1 0.1 NA 40 40 40 old version
2 Lower -2.511434 1.510031e-05 0.2 0.2 NA 80 80 80 old version
3 Lower -1.993051 1.512598e-05 0.3 0.3 NA 120 120 120 old version

2 Test 2: Fixed Design

The power at the following analysis is expected at 0.975.

gs_power_npe(
  theta = 0,
  upper = gs_b, upar = qnorm(0.025),
  lower = gs_b, lpar = -Inf
)
## # A tibble: 2 × 10
##   analysis bound       z probability theta theta1 info_frac  info info0 info1
##      <int> <chr>   <dbl>       <dbl> <dbl>  <dbl>     <dbl> <dbl> <dbl> <dbl>
## 1        1 upper   -1.96       0.975     0      0         1     1     1     1
## 2        1 lower -Inf          0         0      0         1     1     1     1

3 Test 3: info != info0 != info1

If one inputs info in upar

x1_a <- gs_power_npe(
  theta = c(.1, .2, .3),
  info = (1:3) * 80, info0 = (1:3) * 90 + 10, info1 = (1:3) * 70 - 5, info_scale = 0,
  upper = gs_b, upar = gsDesign::gsDesign(k = 3, sfu = gsDesign::sfLDOF)$upper$bound,
  lower = gs_b, lpar = c(-1, 0, 0)
) %>% mutate(`Computated from` = "new version", `Info scale` = 0)
x1_b <- gs_power_npe(
  theta = c(.1, .2, .3),
  info = (1:3) * 80, info0 = (1:3) * 90 + 10, info1 = (1:3) * 70 - 5, info_scale = 1,
  upper = gs_b, upar = gsDesign::gsDesign(k = 3, sfu = gsDesign::sfLDOF)$upper$bound,
  lower = gs_b, lpar = c(-1, 0, 0)
) %>% mutate(`Computated from` = "new version", `Info scale` = 1)
x1_c <- gs_power_npe(
  theta = c(.1, .2, .3),
  info = (1:3) * 80, info0 = (1:3) * 90 + 10, info1 = (1:3) * 70 - 5, info_scale = 2,
  upper = gs_b, upar = gsDesign::gsDesign(k = 3, sfu = gsDesign::sfLDOF)$upper$bound,
  lower = gs_b, lpar = c(-1, 0, 0)
) %>% mutate(`Computated from` = "new version", `Info scale` = 2)
x2 <- gs_power_npe_(
  theta = c(.1, .2, .3),
  info = (1:3) * 80, info0 = (1:3) * 90 + 10, info1 = (1:3) * 70 - 5,
  upper = gs_b, upar = gsDesign::gsDesign(k = 3, sfu = gsDesign::sfLDOF)$upper$bound,
  lower = gs_b, lpar = c(-1, 0, 0)
) %>% mutate(`Computated from` = "old version")
x1_a %>%
  union_all(x1_b) %>%
  union_all(x1_c) %>%
  union_all(x2 %>% rename(bound = Bound, probability = Probability, z = Z, analysis = Analysis)) %>%
  arrange(analysis) %>%
  group_by(analysis, bound) %>%
  gt() %>%
  tab_style(
    style = list(cell_fill(color = "#d3edeb")),
    locations = cells_body(rows = `Computated from` == "old version")
  )
z probability theta theta1 info_frac info info0 info1 Computated from Info scale
1 - upper
3.710303 0.003361090 0.1 0.1 0.3571429 100 100 100 new version 0
3.710303 0.001841687 0.1 0.1 0.3170732 65 65 65 new version 1
3.710303 0.007671740 0.1 0.1 0.3333333 80 100 65 new version 2
1 - lower
-1.000000 0.022750132 0.1 0.1 0.3571429 100 100 100 new version 0
-1.000000 0.035441540 0.1 0.1 0.3170732 65 65 65 new version 1
-1.000000 0.036819135 0.1 0.1 0.3333333 80 100 65 new version 2
1 - Upper
3.710303 0.007671740 0.1 0.1 NA 80 100 65 old version NA
1 - Lower
-1.000000 0.036819135 0.1 0.1 NA 80 100 65 old version NA
2 - upper
2.511427 0.596459227 0.2 0.2 0.6785714 190 190 190 new version 0
2.511427 0.425190347 0.2 0.2 0.6585366 135 135 135 new version 1
2.511427 0.512129734 0.2 0.2 0.6666667 160 190 135 new version 2
2 - lower
0.000000 0.023865544 0.2 0.2 0.6785714 190 190 190 new version 0
0.000000 0.040277466 0.2 0.2 0.6585366 135 135 135 new version 1
0.000000 0.039313062 0.2 0.2 0.6666667 160 190 135 new version 2
2 - Upper
2.511427 0.512129734 0.2 0.2 NA 160 190 135 old version NA
2 - Lower
0.000000 0.039313062 0.2 0.2 NA 160 190 135 old version NA
3 - upper
1.993048 0.975690714 0.3 0.3 1.0000000 280 280 280 new version 0
1.993048 0.954614762 0.3 0.3 1.0000000 205 205 205 new version 1
1.993048 0.971978079 0.3 0.3 1.0000000 240 280 205 new version 2
3 - lower
0.000000 0.023865545 0.3 0.3 1.0000000 280 280 280 new version 0
0.000000 0.040277546 0.3 0.3 1.0000000 205 205 205 new version 1
0.000000 0.039313070 0.3 0.3 1.0000000 240 280 205 new version 2
3 - Upper
1.993048 0.971978079 0.3 0.3 NA 240 280 205 old version NA
3 - Lower
0.000000 0.039313070 0.3 0.3 NA 240 280 205 old version NA

4 Test 3: Developer Tests

4.1 1-sided test

r <- 80
x <- gs_power_npe(
  theta = 0,
  info = (1:3) * 400,
  binding = FALSE, r = r,
  upper = gs_b, # gs_spending_bound,
  upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF)$upper$bound,
  lower = gs_b,
  lpar = rep(-Inf, 3)
) %>% filter(bound == "upper")

y <- gs_power_npe_(
  theta = 0,
  info = (1:3) * 400,
  binding = FALSE, r = r,
  upper = gs_b, # gs_spending_bound,
  upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF)$upper$bound,
  # list(par = list(sf = gsDesign::sfLDOF, param = NULL, total_spend = 0.025)),
  lower = gs_b,
  lpar = rep(-Inf, 3)
) %>% filter(Bound == "Upper")

z <- gsProbability(
  k = 3,
  theta = 0,
  n.I = (1:3) * 400,
  b = gsDesign(k = 3, test.type = 1, sfu = sfLDOF)$upper$bound, a = rep(-20, 3), r = r
)
Calculated from upper bound upper prob
1
new version 3.710303 0.0001035057
old version 3.710303 0.0001035057
gsDesign 3.710303 0.0001035057
2
new version 2.511427 0.0060483973
old version 2.511427 0.0060483973
gsDesign 2.511427 0.0060483970
3
new version 1.993048 0.0250000020
old version 1.993048 0.0250000020
gsDesign 1.993048 0.0250000013

5 Test 4: Independent Tests

5.1 Expect equal with mvtnorm for efficacy and futility bounds

info <- c(40, 100)
r <- info[1] / info[2]

test <- gs_power_npe(
  theta = 0,
  info = info,
  info0 = NULL,
  binding = FALSE,
  upper = gs_spending_bound,
  upar = list(sf = gsDesign::sfLDOF, param = NULL, total_spend = 0.025),
  lower = gs_spending_bound,
  lpar = list(sf = gsDesign::sfLDOF, param = NULL, total_spend = 0.02)
)

test1 <- test %>% filter(bound == "upper")
test2 <- test %>% filter(bound == "lower")

alpha.t <- 0.025
b.ia <- gsDesign::sfLDOF(alpha = alpha.t, t = r)
alpha.ia <- b.ia$spend

Pb <- function(alpha.t, alpha.ia, r, b) {
  temp <- mvtnorm::pmvnorm(
    lower = c(-Inf, b),
    upper = c(qnorm(1 - alpha.ia), Inf),
    corr = rbind(c(1, sqrt(r)), c(sqrt(r), 1))
  )
  return(alpha.t - alpha.ia - temp)
}

b <- uniroot(Pb, c(1.96, 4), alpha.t = alpha.t, alpha.ia = alpha.ia, r = r)

pb <- 1 - pnorm(b$root)

expect_equal(
  object = test1$z,
  expected = c(qnorm(1 - alpha.ia), b$root),
  tolerance = 0.001
)
expect_equal(
  object = test1$probability,
  expected = cumsum(c(b.ia$spend, pb)),
  tolerance = 0.001
)

beta.t <- 0.02
a.ia <- gsDesign::sfLDOF(alpha = beta.t, t = r)
beta.ia <- a.ia$spend

Pa <- function(beta.t, beta.ia, r, a) {
  temp <- mvtnorm::pmvnorm(
    lower = c(-Inf, qnorm(beta.ia)),
    upper = c(a, Inf),
    corr = rbind(c(1, sqrt(r)), c(sqrt(r), 1))
  )
  return(beta.t - beta.ia - temp)
}

a <- uniroot(Pa, c(-4, 1.96), beta.t = beta.t, beta.ia = beta.ia, r = r)

pa <- pnorm(a$root)

expect_equal(
  object = test2$z,
  expected = c(qnorm(beta.ia), a$root),
  tolerance = 0.001
)
expect_equal(
  object = test2$probability,
  expected = cumsum(c(a.ia$spend, pa)),
  tolerance = 0.001
)

5.2 Expect equal with gsDesign::gsProbability outcome for efficacy bounds

info <- c(40, 150, 200)

x <- gs_power_npe(
  theta = .1,
  info = info, binding = FALSE,
  upper = gs_spending_bound,
  upar = list(sf = gsDesign::sfLDOF, param = NULL, total_spend = 0.025),
  lower = gs_b,
  lpar = rep(-Inf, 3)
) %>% filter(bound == "upper")

y <- gs_power_npe(
  theta = .1,
  info = info, binding = FALSE,
  upper = gs_spending_bound,
  upar = list(sf = gsDesign::sfLDOF, param = NULL, total_spend = 0.025),
  lower = gs_b,
  lpar = rep(-Inf, 3)
) %>% filter(bound == "upper")

z <- gsDesign::gsProbability(
  k = 3, theta = .1,
  n.I = info,
  a = rep(-20, 3),
  b = gsDesign(k = 3, test.type = 1, sfu = sfLDOF, n.I = info)$upper$bound
)
Calculated from upper bound upper prob
1
new version 4.876885 1.095752e-05
old version 4.876885 1.095752e-05
gsDesign 4.876885 1.095752e-05
2
new version 2.339724 1.324308e-01
old version 2.339724 1.324308e-01
gsDesign 2.339719 1.324317e-01
3
new version 2.011782 2.870640e-01
old version 2.011782 2.870640e-01
gsDesign 2.011778 2.870653e-01

6 Test 5: Compare with gsDesign under information-based design

Information-based design is useful when testing for a natural parameter \(\delta\) (e.g., treatment difference on a relevant scale such as risk difference) where the variance of the estimate of \(\delta\) is unknown. The basic canonical form of represents information-based design, so it is a particularly simple way to check corresponding basic calculations for sample size, bounds and power in gs_power_npe() and gs_design_npe().

6.1 Step 1: set the design assumptions

k <- 2 # Number of analyses
test.type <- 4
alpha <- 0.025 # 1-sided Type I error
beta <- 0.15 # Type 2 error (1 - targeted power)
astar <- .1
timing <- 0.4 # Timing (information fraction) at interim analyses
sfu <- sfHSD # Efficacy bound spending function
sfupar <- -1 # Upper bound spending function parameters, if any
sfl <- sfLDPocock # Lower bound spending function, if used (test.type > 2)
sflpar <- 0 # Lower bound spending function parameters, if any
delta <- 0.1 # Natural parameter difference (assumed value - H0 value)
delta1 <- 0.1 # Natural parameter assumed value
delta0 <- 0 # Natural parameter difference under H0
endpoint <- "info"
n.fix <- 0

7 References