9 Scenario VIII: large effect, unknown variance
9.1 Details
In this scenario, we investigate the scenario of a large effect with unknown common variance \(\sigma\). The test statistic then follows a \(t\)-distribution. For a large sample size, the \(t\)-distribution can be approximated by the normal distribution and we find ourselves in Scenario I. The larger the assumed effect size in the alternative, the lower the necessary number of subjects to achieve a minimum power. Thus, we choose an effect size of \(\delta=1\) with point prior distribution. The null hypothesis is given by \(\mathcal{H}_0: \delta \leq 0\). The maximal type one error is bounded by \(\alpha=0.025\) and at the point alternative of \(\delta=1\) the power should be at least \(0.9\).
#data distributions and hypothesis
<- Student(two_armed=TRUE)
datadist <- PointMassPrior(.0, 1)
H_0 <- PointMassPrior(1.0, 1)
prior
#define constraints
<- 0.025
alpha <- 0.9
min_power <- Power(datadist,H_0) <= alpha
toer_cnstr <- Power(datadist,prior) >= min_power pow_cnstr
9.2 Variant VIII-1: Minimizing Expected Sample Size under Point Prior
9.2.1 Objective
Firstly, we minimize the expected sample size under the alternative, e.g. \(\boldsymbol{E}\big[n(\mathcal{D})\big]\).
<- ExpectedSampleSize(datadist, prior) ess
9.2.2 Constraints
No additional constraints beside type one error rate and power are considered in this variant.
9.2.3 Initial Designs
For this example, the optimal one-stage, group-sequential, and generic two-stage designs are computed. The initial design for the one-stage case is determined heuristically. Both the group sequential and the generic two-stage designs are optimized starting from the corresponding group-sequential design as computed by the rpact
package.
<- 7L
order # data frame of initial designs
<- tibble(
tbl_designs type = c("one-stage", "group-sequential", "two-stage"),
initial = list(
OneStageDesign(20, 2.0),
rpact_design(datadist, 1.0, 0.025, 0.9, TRUE, order),
TwoStageDesign(rpact_design(datadist, 1.0, 0.025, 0.9, TRUE, order))) )
9.2.4 Optimization
<- tbl_designs %>%
tbl_designs mutate(
optimal = purrr::map(initial, ~minimize(
ess,subject_to(
toer_cnstr,
pow_cnstr
),
initial_design = .,
opts = opts)) )
9.2.5 Test Cases
To avoid improper solutions, it is first verified that the maximum number of iterations was not exceeded in any of the three cases.
%>%
tbl_designs transmute(
type, iterations = purrr::map_int(tbl_designs$optimal,
~.$nloptr_return$iterations) ) %>%
print(.); .} %>%
{::expect_true(all(.$iterations < opts$maxeval))} {testthat
## # A tibble: 3 × 2
## type iterations
## <chr> <int>
## 1 one-stage 19
## 2 group-sequential 1878
## 3 two-stage 4574
Next, the type one error rate and power constraints are verified for all three designs by simulation:
%>%
tbl_designs transmute(
type, toer = purrr::map(tbl_designs$optimal,
~sim_pr_reject(.[[1]], .0, datadist)$prob),
power = purrr::map(tbl_designs$optimal,
~sim_pr_reject(.[[1]], 1.0, datadist)$prob) ) %>%
unnest(., cols = c(toer, power)) %>%
print(.); .} %>% {
{::expect_true(all(.$toer <= alpha * (1 + tol)))
testthat::expect_true(all(.$power >= min_power * (1 - tol)))
testthat }
## # A tibble: 3 × 3
## type toer power
## <chr> <dbl> <dbl>
## 1 one-stage 0.0251 0.899
## 2 group-sequential 0.0250 0.898
## 3 two-stage 0.0247 0.897
The \(n_2\) function of the optimal two-stage design is expected to be monotonously decreasing:
expect_true(
all(diff(
# get optimal two-stage design n2 pivots
%>% filter(type == "two-stage") %>%
tbl_designs "optimal"]][[1]]$design@n2_pivots}
{.[[< 0) ) )
Since the optimal two-stage design is more flexible than the optimal group-sequential design (constant
\(n_2\) function) and this is more flexible than the optimal one-stage design (no second stage), the expected sample sizes under the prior should be ordered in the opposite way. Additionally, expected sample sizes under the null hypothesis are computed both via evaluate()
and simulation-based.
%>%
tbl_designs mutate(
ess = map_dbl(optimal,
~evaluate(ess, .$design) ),
ess_sim = map_dbl(optimal,
~sim_n(.$design, 1, datadist)$n ),
ess0 = map_dbl(optimal,
~evaluate(ess0, .$design) ),
ess0_sim = map_dbl(optimal,
~sim_n(.$design, .0, datadist)$n ) ) %>%
print(.); .} %>% {
{# sim/evaluate same under alternative?
::expect_equal(.$ess, .$ess_sim,
testthattolerance = tol_n,
scale = 1)
# sim/evaluate same under null?
::expect_equal(.$ess0, .$ess0_sim,
testthattolerance = tol_n,
scale = 1)
# monotonicity with respect to degrees of freedom
::expect_true(all(diff(.$ess) < 0))
testthat }
## # A tibble: 3 × 7
## type initial optimal ess ess_sim ess0 ess0_sim
## <chr> <list> <list> <dbl> <dbl> <dbl> <dbl>
## 1 one-stage <OnStgDsg> <adptrOpR [3]> 22 22 22 22
## 2 group-sequential <GrpSqntD> <adptrOpR [3]> 17.3 17.3 15.7 15.7
## 3 two-stage <TwStgDsg> <adptrOpR [3]> 17.0 17.0 16.7 16.6
The expected sample size under the alternative must be lower or equal than the expected sample size of the initial rpact group-sequential design that is based on the inverse normal combination test.
::expect_lte(
testthatevaluate(ess,
%>%
tbl_designs filter(type == "group-sequential") %>%
pull(optimal) %>%
1]] %>%
.[[$design ),
.evaluate(ess,
%>%
tbl_designs filter(type == "group-sequential") %>%
pull(initial) %>%
1]] ) ) .[[
9.3 Variant VIII-2: Comparison to Normal Distribution
9.3.1 Generate Comparison Design
We now compare the expected sample size of this scenario to the expected sample size when we assume that the variance is known. Thus, we need to find the optimal designs with normal distributed test statistic. These steps are completely analogous to scenario I.
<- Normal(two_armed=TRUE)
datadistnorm <- PointMassPrior(.0,1)
H_0norm <- PointMassPrior(1.0,1)
priornorm
<- Power(datadistnorm,H_0norm) <= alpha
toernorm <- Power(datadistnorm,priornorm) >= min_power pownorm
We minimize the expected sample size under the alternative.
<- ExpectedSampleSize(datadistnorm,priornorm) essnorm
We now choose different initial designs since we do not use the \(t\)-distribution anymore.
<- tibble(
tbl_designsnorm type = c("one-stage", "group-sequential", "two-stage"),
initial = list(
OneStageDesign(20, 2.0),
rpact_design(datadist, 1.0, 0.025, 0.9, TRUE, order),
TwoStageDesign(rpact_design(datadist, 1.0, 0.025, 0.9, TRUE, order))) )
<- tbl_designsnorm %>%
tbl_designsnorm mutate(
optimal = purrr::map(initial, ~minimize(
ess,subject_to(
toernorm,
pownorm
),
initial_design = .,
opts = opts)) )
9.3.2 Test Cases
In all of the three designs, we should see that the expected sample size under the normal distributed test statistic is lower than the expected sample size when we use the \(t\)-distribution.
<- map_dbl(tbl_designs$optimal,~evaluate(ess,.$design))
essstudent <- map_dbl(tbl_designsnorm$optimal,~evaluate(ess,.$design)) essnorm
## Student
## 22 17.3488 16.97228
## Normal
## 21 15.87601 15.59286
<- essstudent-essnorm
diff ::expect_true(all(diff > 0)) testthat