Skip to content

Commit f05da83

Browse files
committed
CRAN
1 parent ac468a0 commit f05da83

66 files changed

Lines changed: 3883 additions & 2028 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.DS_Store

0 Bytes
Binary file not shown.

.Rhistory

Lines changed: 502 additions & 502 deletions
Large diffs are not rendered by default.

DESCRIPTION

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
Package: BayesianPlatformDesignTimeTrend
22
Title: Simulate and Analyse Bayesian Platform Trial with Time Trend
3-
Version: 1.1.3
4-
Author: Ziyan Wang [aut, cre]
3+
Version: 1.2.0
4+
Author: Ziyan Wang [aut, cre],
5+
David Woods [ctb]
56
Maintainer: Ziyan Wang <zw7g20@soton.ac.uk>
67
Authors@R:
7-
person(given = "Ziyan",
8+
c(person(given = "Ziyan",
89
family = "Wang",
910
role = c("aut", "cre"),
10-
email = "zw7g20@soton.ac.uk")
11+
email = "zw7g20@soton.ac.uk"),
12+
person(given = "David",
13+
family = "Woods",
14+
role = c("ctb"),
15+
email = "D.Woods@southampton.ac.uk"))
1116
Description: Simulating the sequential multi-arm multi-stage or platform trial with Bayesian approach using the 'rstan' package, which provides the R interface for the Stan.
1217
This package supports fixed ratio and Bayesian adaptive randomization approaches for randomization.
1318
Additionally, it allows for the study of time trend problems in platform trials.
@@ -20,14 +25,14 @@ Description: Simulating the sequential multi-arm multi-stage or platform trial w
2025
The analysis methods of time trend effect in platform trial are described in:
2126
Saville et al. (2022) <doi:10.1177/17407745221112013> and
2227
Bofill Roig et al. (2022) <doi:10.1186/s12874-022-01683-w>.
23-
URL: https://github.com/ZXW834/PlatFormDesignTime
28+
URL: https://github.com/ZXW834/BayesianPlatformDesignTimeTrend
2429
Encoding: UTF-8
2530
Roxygen: list(markdown = TRUE)
2631
RoxygenNote: 7.2.3
2732
Biarch: true
2833
Depends:
2934
R (>= 4.0.0),
30-
rstan (>= 2.18.1)
35+
rstan (>= 2.26.1)
3136
Imports:
3237
methods,
3338
Rcpp (>= 0.12.0),
@@ -43,14 +48,18 @@ Imports:
4348
reshape (>= 0.8.8),
4449
BiocManager (>= 1.30.19),
4550
lhs (>= 1.1.6),
46-
laGP (>= 1.5-9)
51+
laGP (>= 1.5-9),
52+
RColorBrewer (>= 1.1-3),
53+
directlabels (>= 2023.8.25),
54+
ggpubr (>= 0.4.0),
55+
reshape2 (>= 1.4.4)
4756
LinkingTo:
4857
BH (>= 1.66.0),
4958
Rcpp (>= 0.12.0),
5059
RcppEigen (>= 0.3.3.3.0),
5160
RcppParallel (>= 5.0.1),
52-
StanHeaders (>= 2.18.0),
53-
rstan (>= 2.18.1)
61+
StanHeaders (>= 2.26.0),
62+
rstan (>= 2.26.1)
5463
SystemRequirements: GNU make, C++17
5564
License: MIT + file LICENSE
5665
Suggests:

NAMESPACE

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
export(ARmethod)
44
export(AdaptiveRandomisation)
55
export(Boundaryconstruction)
6-
export(FWER_disconjunctivepowerfunc)
76
export(GP.optim)
87
export(Initializetrialparameter)
98
export(Meanfunc)
@@ -16,19 +15,22 @@ export(Stopboundinf)
1615
export(Timetrend.fun)
1716
export(Trial.simulation)
1817
export(alphaspending)
18+
export(conjuncativepower_or_FWER)
1919
export(demo_Cutoffscreening)
2020
export(demo_Cutoffscreening.GP)
2121
export(demo_multscenario)
22+
export(disconjunctivepowerfunc)
2223
export(ibetabinomial.post)
2324
export(intbias)
2425
export(modelinf.fun)
25-
export(perHtypeIerror_powerfunc)
26+
export(perHtypeIerror_marginalpowerfunc)
2627
export(resultrtostats)
2728
export(resultrtostats.rand)
2829
export(resultstantoRfunc)
2930
export(resultstantoRfunc.rand)
3031
export(simulatetrial)
3132
export(stan.logisticmodeltrans)
33+
export(testing_and_armdropping)
3234
export(trtbias)
3335
export(trteffect)
3436
export(varfunc)
@@ -44,13 +46,18 @@ importFrom(boot,logit)
4446
importFrom(doParallel,registerDoParallel)
4547
importFrom(foreach,"%dopar%")
4648
importFrom(foreach,foreach)
49+
importFrom(grDevices,heat.colors)
50+
importFrom(graphics,image)
4751
importFrom(graphics,lines)
52+
importFrom(graphics,par)
53+
importFrom(graphics,points)
4854
importFrom(iterators,icount)
4955
importFrom(laGP,distance)
5056
importFrom(matrixStats,colVars)
5157
importFrom(rstan,rstan_options)
5258
importFrom(rstan,sampling)
5359
importFrom(stats,dbeta)
60+
importFrom(stats,dist)
5461
importFrom(stats,integrate)
5562
importFrom(stats,lm)
5663
importFrom(stats,model.matrix)
@@ -60,5 +67,6 @@ importFrom(stats,pnorm)
6067
importFrom(stats,predict)
6168
importFrom(stats,qnorm)
6269
importFrom(stats,rbinom)
70+
importFrom(stats,runif)
6371
importFrom(stats,var)
6472
useDynLib(BayesianPlatformDesignTimeTrend, .registration = TRUE)

NEWS.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,41 @@
1+
# Sept 30, 2023, BayesianPlatformDesignTimeTrend version 1.2.0
2+
## Summary of changes
3+
- This release corrects the boundary construction formula of OBF boundary;
4+
- This release adds internal functions of calculating conjunctive power, disconjunctive power and marginal power.
5+
- This release extend the type of hypothesis testing which are Oneside test and the two side test now;
6+
- This release implements method of cutoff screening for asymmetric boundary using Bayesian optimization. The cutoff screening for asymmetric boundary is released in this version (including No early stopping boundary, Pocock boundary and OBF boundary). The plot of boundary shape refers to the plot on github: https://github.com/ZXW834/BayesianPlatformDesignTimeTrend.
7+
- This release implements method of hyperparameter tuning for Trippa's adaptive randomisation approach. There are some flow chats in the tutorial and on the github.
8+
- This release adds my supervisor David Woods as the contributor to the package.
9+
10+
## Bugs
11+
- In OBF boundary construction, the boundary formula was $\theta_j=\phi \left(\sqrt{\frac{J}{j}c} \right)$ which is not the same as that in the reference which is $\theta_j=\phi \left(\sqrt{\frac{J}{j}}c \right)$. Although the original boundary formula works in trial simulation, the correction is still made.
12+
13+
## New feature
14+
- In previous version, the power function was only for disconjunctive power and FWER. In this version, the conjunctive power `conjuncativepower_or_FWER` and marginal power (per-hypothesis type I error) `perHtypeIerror_marginalpowerfunc` can also be calculated for the used of design evaluation and power optimisation in asymmetric boundary cutoff screening. The function to calculate disconjunctive power is renamed as `disconjunctivepowerfunc`.
15+
16+
- In previous version, the hypothesis testing during the interim analysis is $H_0$: $\pi_k = \pi_0$; $H_1$: $\pi_k \neq \pi_0$. Now we add one side test to only conclude for superiority: $H_0$: $\pi_k \leq \pi_0$; $H_1$: $\pi_k > \pi_0$.
17+
18+
- In previous version, the cutoff value can only be tuned for symmetric boundary. In this version, asymmetric boundary cutoff screening is added so that user can decide whether to use a more aggressive efficacy boundary with a more aggressive futility boundary (or a more conservative efficacy boundary with more conservative futility boundary). The asymmetric boundary screening process first select the type I error rate contour equal to the target, then pick a cutoff pair (eff, fut) that maximizes the power.
19+
20+
- In previous version, the Trippa's adaptive randomisation approach used fixed hyperparameters suggested in their paper. In this version, the hyperparameters a and b are tuned to optimise power when type I error (FWER) is controlled at target. This idea can be found on Trippa's paper (2012). We used a gaussian process model to smooth the contour plot. The pair (a, b) with highest predicted power will be exploit for hyperparameter screening until there are enough point overlapped on the contour plot. In addition, the hyperparameter point (a, b) can be pick in a crude way to save computation time via setting the maximum number of points to be looked at.
21+
122
# Aug 22, 2023, BayesianPlatformDesignTimeTrend version 1.1.3
223
This release fix one command in fix effect model analysis of main effect that is confusing.
324

4-
- I fixed the bug in function `resultrtostats`. THe calculation of "stats4" was the sum of main effect and interaction effect when using the model with interaction term (main * stage_continuous / main * stage_discrete). The sum was used to calculate the posterior probability of superior or inferior. However, "stats4" only represents the mean values of main effect in the final output matrix. The wrong value was given to "stats4". This is the same for "stats5" which is the standard errors of the main effect in the model
25+
## Bugs
26+
- I fixed the bug in function `resultrtostats`. The calculation of "stats4" was the sum of main effect and interaction effect when using the model with interaction term (main * stage_continuous / main * stage_discrete). The sum was used to calculate the posterior probability of superior or inferior. However, "stats4" only represents the mean values of main effect in the final output matrix. The wrong value was given to "stats4". This is the same for "stats5" which is the standard errors of the main effect in the model
527

628
# Jun 25, 2023, BayesianPlatformDesignTimeTrend version 1.1.2
729
This release fix two bugs.
830

31+
## Bugs
932
- I fixed the bug in function `GP.optim` where the formula of information weighed randomisation is wrong.
1033
- I fixed the bug in function `demo_Cutoffscreening` where the nextcutoff vector for sample may have only one element. This will lead to the error in function `sample` when you only want to sample one value greater than 1. The argument 'ntrials' in each example should be large (> 100) instead 2 to make the example more like an actual simulation example. I use ntrials = 2 in the example to speed up the check process.
1134

1235
# Jun 11, 2023, BayesianPlatformDesignTimeTrend version 1.1.1
1336
This release fix one bug reported by the cran team.
1437

38+
## Bugs
1539
- I fixed the bug in function `GP.optim` where the nextcutoff vector for sample may have only one element. This will lead to the error in function `sample` when you only want to sample one value greater than 1.
1640
- The argument 'ntrials' in each example should be large (> 100) instead 2 to make the example more like an actual simulation example. I use ntrials = 2 in the example to speed up the check process.
1741

R/Analysis_listofanalysisfunction.R

Lines changed: 113 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
#' @description This function reads in the output matrix of a number of trial replicates to calculate the error rate
33
#' @param res A list of output matrix of a number of trial replicates
44
#'
5-
#' @return Type I error rate or power of each treatment - control comparison
5+
#' @return "per-hypothesis" Type I error rate or power (marginal power) for each treatment - control comparison
66
#' @export
77
#'
88
#' @examples
99
#' \dontrun{perHtypeIerror_powerfunc(res)}
1010
#' @author Ziyan Wang
11-
perHtypeIerror_powerfunc = function(res) {
11+
perHtypeIerror_marginalpowerfunc = function(res) {
1212
colMeans(t(sapply(res, function(x) {
1313
resname = colnames(x)
1414
K = sum(stringr::str_detect(colnames(x), "H")) + 1
@@ -25,16 +25,16 @@ perHtypeIerror_powerfunc = function(res) {
2525
}
2626
})))
2727
}
28-
#' @title FWER_disconjunctivepowerfunc
28+
#' @title disconjunctivepowerfunc
2929
#' @description This function reads in the output matrix of a number of trial replicates to calculate the Family wise error rate or disconjunctive power
3030
#' @param res A list of output matrix of a number of trial replicates
3131
#'
32-
#' @return Family wise error rate or disconjunctive power
32+
#' @return Disconjunctive power
3333
#' @export
3434
#'
3535
#' @examples
36-
#' \dontrun{FWER_disconjunctivepowerfunc(res)}
37-
FWER_disconjunctivepowerfunc = function(res) {
36+
#' \dontrun{disconjunctivepowerfunc(res)}
37+
disconjunctivepowerfunc = function(res) {
3838
mean(sapply(res, function(x) {
3939
resname = colnames(x)
4040
K = sum(stringr::str_detect(colnames(x), "H")) + 1
@@ -47,6 +47,113 @@ FWER_disconjunctivepowerfunc = function(res) {
4747
}))
4848
}
4949

50+
#' @title conjuncativepower_or_FWER
51+
#'
52+
#' @description This function reads in the output matrix of a number of trial replicates to calculate the Family wise error rate or Conjunctive power
53+
#'
54+
#' @param res A list of output matrix of a number of trial replicates
55+
#' @param scenario The true scenario used to generate the res list
56+
#' @param test.type The indicator of whether using one side or two side testing.
57+
#' Please make sure that the input test.type does not conflicts to the data. Otherwise the conjunctive power calculation is wrong
58+
#'
59+
#' @return Family wise error rate or Conjunctive power
60+
#' @export
61+
#'
62+
#' @examples
63+
#' \dontrun{conjuncativepower_or_FWER(res)}
64+
conjuncativepower_or_FWER=function(res,scenario,test.type){
65+
K=mean(sapply(res,function(x){
66+
K=sum(stringr::str_detect(colnames(x),"H"))+1
67+
return(K)
68+
}))
69+
hypres=mean(sapply(res,function(x){
70+
stage=dim(x)[1]
71+
resname=colnames(x)
72+
K=sum(stringr::str_detect(colnames(x),"H"))+1
73+
74+
# True scenario construction
75+
if (sum(scenario-min(scenario))>0 & test.type == "Twoside"){
76+
sce = (scenario-scenario[1])[-1]!=0
77+
}
78+
else if (sum(scenario-min(scenario))>0 & test.type == "Oneside"){
79+
sce = (scenario-scenario[1])[-1]>0
80+
}
81+
else{
82+
sce = rep(0,K-1)
83+
}
84+
85+
# # Check whether the data output conflicts the test type. This will lead to error if the hypothesis test data input are all zero under the alternative
86+
# if (test.type == "Twoside"){
87+
# test.data = x[,(K-1+2*K+1):(K-1+2*K+K-1)]
88+
# superiorarm.loc = which((scenario-scenario[1])[-1]>0)
89+
# inferiorarm.loc = which((scenario-scenario[1])[-1]<0)
90+
# for (i in 1:length(inferiorarm.loc)){
91+
# if (test.data[min(which(is.na(test.data[,inferiorarm.loc[i]])))-1,inferiorarm.loc[i]] == 0){
92+
# stop("The data type used a Two side test while the input variable is one side.")
93+
# }
94+
# }
95+
# for (i in 1:length(superiorarm.loc)){
96+
# if (test.data[min(which(is.na(test.data[,superiorarm.loc[i]])))-1,superiorarm.loc[i]] == 0){
97+
# stop("The data type used a Two side test while the input variable is one side.")
98+
# }
99+
# }
100+
# }
101+
# else if (test.type == "Oneside"){
102+
# inferiorarm.loc = which((scenario-scenario[1])[-1]<0)
103+
# test.data = x[,(K-1+2*K+1):(K-1+2*K+K-1)]
104+
# # check if any inferior arm is identified to be inferior for one side test
105+
# for (i in 1:length(inferiorarm.loc)){
106+
# if (test.data[min(which(is.na(test.data[,inferiorarm.loc[i]])))-1,inferiorarm.loc[i]] == 1){
107+
# stop("The data type used a Two side test while the input variable is one side.")
108+
# }
109+
# }
110+
# }
111+
# else{
112+
# Stop("Input test.type is invalid.")
113+
# }
114+
#Indentify which hypothesis is rejected
115+
reject=which(matrix(x[,(K-1+2*K+1):(K-1+2*K+K-1)] %in% 1,ncol=K-1),1)[,2]
116+
drop.at=which(matrix(x[,(K-1+2*K+1):(K-1+2*K+K-1)] %in% 1,ncol=K-1),1)[,1]
117+
drop.at.all=rep(stage,K-1)
118+
drop.at.all[reject]=drop.at
119+
treatmentindex=seq(1,K-1)
120+
trtmean.loc=cbind(drop.at.all,treatmentindex)
121+
122+
res=matrix(x[,(K-1+2*K+1):(K-1+2*K+K-1)] %in% 1,ncol=K-1)
123+
result=rep(NA,K-1)
124+
for (i in 1:(K-1)){
125+
result[i] = res[trtmean.loc[i,1],trtmean.loc[i,2]]
126+
}
127+
if (sum(result == sce) == (K-1)){
128+
return(1)
129+
}
130+
else{
131+
return(0)
132+
}
133+
}))
134+
if (test.type == "Twoside"){
135+
if (sum(scenario-min(scenario))>0){
136+
current_scenario = "Alt"
137+
return(hypres)
138+
}
139+
else{
140+
current_scenario = "Null"
141+
return(1-hypres)
142+
}
143+
}
144+
else{
145+
if ((max(scenario)-scenario[1]) <= 0){
146+
current_scenario = "Null"
147+
return(1-hypres)
148+
}
149+
else{
150+
current_scenario = "Alt"
151+
return(hypres)
152+
}
153+
}
154+
155+
}
156+
50157
#' @title Meanfunc
51158
#' @description This function reads in the output matrix of a number of trial replicates to calculate mean treatment effect estimate.
52159
#' @param res A list of output matrix of a number of trial replicates

R/Demo_CutoffScreening.R

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ demo_Cutoffscreening = function(ntrials = 1000,
3333
max.ar = 0.75,
3434
rand.algo = "Urn",
3535
max.deviation = 3,
36+
test.type = "Twoside",
3637
model.inf = list(
3738
model = "tlr",
3839
ibb.inf = list(
@@ -104,7 +105,7 @@ demo_Cutoffscreening = function(ntrials = 1000,
104105
)
105106

106107
# perHtypeIerror=mean(perHtypeIerrorfunc(result))
107-
FWER = FWER_disconjunctivepowerfunc(result)
108+
FWER = conjuncativepower_or_FWER(result,input.info$response.probs,test.type = input.info$test.type)
108109
startgrid[j, 1] = FWER
109110
}
110111

@@ -151,7 +152,7 @@ demo_Cutoffscreening = function(ntrials = 1000,
151152
Random.inf = input.info$Random.inf,
152153
trend.inf = input.info$trend.inf
153154
)
154-
FWER = FWER_disconjunctivepowerfunc(restlr090five)
155+
FWER = conjuncativepower_or_FWER(restlr090five, input.info$response.probs,test.type = input.info$test.type)
155156
extendgrid[cutoffindex, 1] = FWER
156157
extendgrid$cutoff2 <- extendgrid$cutoff ^ 2
157158
quadratic.model <-

0 commit comments

Comments
 (0)