The OssaNMA
package is built to calculate the optimal
sample size and allocation for treatment groups when we plan a new trial
and analyze it with the existing network meta-analysis (NMA). This
vignette shows you:
netmeta
package to calculate the
standard error of the estimated effect size between two treatments in
the existing network, which would be used as the input parameter of the
functions in OssaNMA
.We will start by loading OssaNMA
.
library(OssaNMA)
Assuming a new two-arm trial comparing treatment 1 and treatment 2 is to be planned. The two treatments exist in the existing network, which serves as a foundation to analyze the new trial with the existing network using network meta-analysis (NMA).
Given that the risk of treatment 1 is 0.2, the risk of treatment 2 is
0.3, and the standard error of the estimated effect size between two
treatments from the existing NMA is 0.3, ssnma()
can be
applied to solve the minimum required total sample size for the new
trial to achieve a power of 0.8 and allocate it to each treatment group
under different allocation method (even or uneven) and analysis method
(with or without the existing network):
# Analyze the new trial with the existing network
ssnma(p1 = 0.2, p2 = 0.3, enma_sigma = 0.3, power.level = 0.8,
sig.level = 0.05, method = "with", allocation = "uneven")
#> $sample_size
#> [1] 187 163
#>
#> $power
#> [1] 0.801
# Analyze the new trial with the existing network and
# keep the sample size of each group to be the same
ssnma(p1 = 0.2, p2 = 0.3, enma_sigma = 0.3, power.level = 0.8,
sig.level = 0.05, method = "with", allocation = "even")
#> $sample_size
#> [1] 176 176
#>
#> $power
#> [1] 0.801
# Analyze the new trial without the existing network
ssnma(p1 = 0.2, p2 = 0.3, enma_sigma = 0.3, power.level = 0.8,
sig.level = 0.05, method = "without", allocation = "uneven")
#> $sample_size
#> [1] 317 277
#>
#> $power
#> [1] 0.801
# Analyze the new trial without the existing network and
# keep the sample size of each group to be the same
ssnma(p1 = 0.2, p2 = 0.3, enma_sigma = 0.3, power.level = 0.8,
sig.level = 0.05, method = "without", allocation = "even")
#> $sample_size
#> [1] 298 298
#>
#> $power
#> [1] 0.801
Assume that we have the same new trial planned as the previous
section, the goal in this section is to calculate the optimal sample
size allocation to each treatment group with a fixed total sample size
of 200 to maximize the power, ssanma()
is used:
# Analyze the new trial with the existing network
ssanma(p1 = 0.2, p2 = 0.3, enma_sigma = 0.3, N = 200, sig.level = 0.05,
method = "with")
#> $sample_alloc
#> [1] 107 93
#>
#> $power
#> [1] 0.679
As we can see, the optimal way is to allocate 107 subjects to group 1 and 93 subjects to group 2. The corresponding power is 0.679.
We may wonder, if we were to analyze it traditionally without the
existing network, what would be the optimal sample allocation and power?
By changing the method
to without, we have:
# Analyze the new trial without the existing network
ssanma(p1 = 0.2, p2 = 0.3, enma_sigma = 0.3, N = 200, sig.level = 0.05,
method = "without")
#> $sample_alloc
#> [1] 107 93
#>
#> $power
#> [1] 0.37
The optimal sample allocation when we analyze the new trial traditionally is the same to previously. However, the power decreased greatly compared to analyzing it with the existing network.
We may also wonder, what’s the power if we allocate it evenly to each
group? The parameter allocation
can be used:
# Even allocation and analyze the new trial with the existing network
ssanma(p1 = 0.2, p2 = 0.3, enma_sigma = 0.3, N = 200,
sig.level = 0.05, method = "with", allocation = "even")
#> $sample_alloc
#> [1] 100 100
#>
#> $power
#> [1] 0.678
# Even allocation and analyze the new trial without the existing network
ssanma(p1 = 0.2, p2 = 0.3, enma_sigma = 0.3, N = 200,
sig.level = 0.05, method = "without", allocation = "even")
#> $sample_alloc
#> [1] 100 100
#>
#> $power
#> [1] 0.369
In this section, we will show how to use the netmeta
package to calculate the standard error of the estimated effect size
between two treatments in the existing network, which would be used as
the input parameter of the functions in OssaNMA
package and
to assist designing a new trial based on an existing NMA. An example
dataset is loaded for illustration:
# load the example dataset in package OssaNMA
data(BRDdat)
head(BRDdat)
#> studlab treat1 treat2 TE seTE
#> 1 1 No active control Florfenicol 1.817766 0.4198201
#> 2 2 No active control Enrofloxacin 3.471966 1.5027924
#> 3 3 No active control Enrofloxacin 3.201584 0.4781349
#> 4 4 No active control Enrofloxacin 1.434531 0.3878773
#> 5 5 No active control Enrofloxacin 3.197472 0.4938823
#> 6 6 No active control Enrofloxacin 1.945910 0.3854496
This example dataset represents a previously published network of interventions for the treatment of Bovine Respiratory Disease (BRD) in feedlot cattle (O’Connor, Yuan, Cullen, Coetzee, Da Silva, and Wang, 2016). The dataset is comprised of 98 trials, 13 treatments and 204 arms. Each row represents the summary statistics for a pairwise comparison between two treatment in a trial. See the meaning of each column below:
Let’s conduct a network meta-analysis(NMA) using this dataset:
library(netmeta)
#> Loading required package: meta
#> Loading 'meta' package (version 6.0-0).
#> Type 'help(meta)' for a brief overview.
#> Readers of 'Meta-Analysis with R (Use R!)' should install
#> older version of 'meta' package: https://tinyurl.com/dt4y5drs
#> Loading 'netmeta' package (version 2.5-0).
#> Type 'help("netmeta-package")' for a brief overview.
#> Readers of 'Meta-Analysis with R (Use R!)' should install
#> older version of 'netmeta' package: https://tinyurl.com/kyz6wjbb
<- netmeta(TE,seTE,treat1,treat2,studlab,
nma_res data=BRDdat,
sm="OR",comb.fixed = T,comb.random = F)
Assuming a new two-arm trial comparing Ceftiofur pin and Tildipirosin
is to be planned. To apply the functions in OssaNMA
to help
to plan the new trial, we need to have the standard error of the
estimated effect size between the two treatments, Ceftiofur pin and
Tildipirosin, from the existing network. We can get the value by:
<- nma_res$seTE.fixed['Ceftiofur pin','Tildipirosin']
enma_sigma
enma_sigma#> [1] 0.2231349
Also, we need to know the risk of two treatments in the new trial. Some options are:
Take the first option for example:
# The risk of NMA is calculate by pooling the arm-level data from the existing network.
# The arm-level data is not provided in the package so the value is given directly here.
<- 0.68
p_nac # extract the log odds ratio between NAC and two treatments from nma_res
<- nma_res$TE.fixed['No active control','Ceftiofur pin']
lor_nac_enro <- nma_res$TE.fixed['No active control','Tildipirosin']
lor_nac_flor # calculate risk of Ceftiofur pin, name it as p1
<- p_nac/(p_nac + exp(lor_nac_enro)*(1-p_nac))
p1 # calculate risk of Tildipirosin, name it as p2
<- p_nac/(p_nac + exp(lor_nac_flor)*(1-p_nac)) p2
Take a look at p1
and p2
:
p1#> [1] 0.1868955
p2#> [1] 0.2366667
With p1
, p2
, and enma_sigma
obtained from the existing NMA, we can solve the minimum required total
sample size for the new trial to achieve a pre-specified power using
ssnma()
or calculate the optimal sample size allocation to
each treatment group with a fixed total sample size to maximize the
power using ssanma()
, as how we applied the two functions
in the first two sections when we have specified values of the input
parameters.
See the application using the p1
, p2
, and
enma_sigma
obtained from the existing NMA below:
To solve the minimum required total sample size for the new trial to
achieve a pre-specified power of 0.8 and allocate it to each treatment
group under different allocation method (even or uneven) and analysis
method (with or without the existing network), ssnma()
can
be applied.
See the optimal sample size for each treatment group under different allocation method (even and uneven) and analysis method (with or without the existing network) below:
# Analyze the new trial with the existing network
ssnma(p1 = p1, p2 = p2, enma_sigma = enma_sigma, power.level = 0.8,
sig.level = 0.05, method = "with", allocation = "uneven")
#> $sample_size
#> [1] 853 782
#>
#> $power
#> [1] 0.8
# Analyze the new trial with the existing network and
# keep the sample size of each group to be the same
ssnma(p1 = p1, p2 = p2, enma_sigma = enma_sigma, power.level = 0.8,
sig.level = 0.05, method = "with", allocation = "even")
#> $sample_size
#> [1] 819 819
#>
#> $power
#> [1] 0.8
# Analyze the new trial without the existing network
ssnma(p1 = p1, p2 = p2, enma_sigma = enma_sigma, power.level = 0.8,
sig.level = 0.05, method = "without", allocation = "uneven")
#> $sample_size
#> [1] 1106 1015
#>
#> $power
#> [1] 0.8
# Analyze the new trial without the existing network and
# keep the sample size of each group to be the same
ssnma(p1 = p1, p2 = p2, enma_sigma = enma_sigma, power.level = 0.8,
sig.level = 0.05, method = "without", allocation = "even")
#> $sample_size
#> [1] 1062 1062
#>
#> $power
#> [1] 0.8
To calculate the optimal sample size allocation to each treatment
group with a fixed total sample size of 800 to maximize the power,
ssanma()
is used.
See the optimal sample size allocation for each treatment group and the corresponding power under different allocation method (even and uneven) and analysis method (with or without the existing network) below:
# Analyze the new trial with the existing network
ssanma(p1 = p1, p2 = p2, enma_sigma = enma_sigma, N = 800, sig.level = 0.05,
method = "with")
#> $sample_alloc
#> [1] 417 383
#>
#> $power
#> [1] 0.588
# Analyze the new trial without the existing network
ssanma(p1 = p1, p2 = p2, enma_sigma = enma_sigma, N = 800, sig.level = 0.05,
method = "without")
#> $sample_alloc
#> [1] 417 383
#>
#> $power
#> [1] 0.406
# Even allocation and analyze the new trial with the existing network
ssanma(p1 = p1, p2 = p2, enma_sigma = enma_sigma, N = 800,
sig.level = 0.05, method = "with", allocation = "even")
#> $sample_alloc
#> [1] 400 400
#>
#> $power
#> [1] 0.587
# Even allocation and analyze the new trial without the existing network
ssanma(p1 = p1, p2 = p2, enma_sigma = enma_sigma, N = 800,
sig.level = 0.05, method = "without", allocation = "even")
#> $sample_alloc
#> [1] 400 400
#>
#> $power
#> [1] 0.405