[f2e496]: / R / simulate.R

Download this file

174 lines (143 with data), 7.6 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#This file contains the simulate functions for the predict from
#data part of the package
##' @include eventModel.R
NULL
##' The simulate methods for EventPrediction package
##'
##'
##' These methods are for the predict from data part of the package
##' and simulate. All functions described here are wrappers for the
##' missing,missing,EventData,FromDataSimParams-method
##'
##' See the stats::simulate method for details of the stats simulate function
##'
##' @name simulate
##' @param object An \code{EventModel} object which contains both the data (slot event.data) and
##' the simulation parameters (slot simParams). If not stats::simulate will be called
##' @param data If used then this \code{EventData} object will be used when performing the simulations
##' instead of the \code{EventData} object within \code{fit}
##' @param SimParams A \code{FromDataSimParam} object,
##' overrides the simulated parameters from the \code{EventModel} object
##' @rdname simulate-methods
##' @param accrualGenerator An AccrualGenerator object used for recruiting additional subjects
##' @param Naccrual The number of additional subjects to be recruited
##' @param Nsim Number of simulations to run
##' @param limit Limit for the percentiles, default is 0.05 which corresponds
##' to [0.05, 0.95]
##' @param seed Integer for random number generator (for reproducability) By default NULL.
##' @param longlagsettings A LongLagSettings object to control the behaviour of the algorithm for subjects whos last date
##' is a long time from the analysis date. Using this argument can have a large impact on the results - see vignette for further details
##' @param HR The hazard ratio: an advanced option which allows two arm trials to be simulated. This replicates the
##' Predict from parameters functionality but uses the recruitment times found in \code{data}. See the vignette for
##' further details
##' @param r The allocation ratio: see \code{HR} argument.
##' @param dropout if subjects drop out in study (due to competing risks not as there is a finite follow up time)
##' then this argument should contain a list with proportion and time and optionally shape i.e.
##' \code{dropout=list(proportion=0.03,time=365,shape=1.2)} meaning in the absence of events 3% of subjects
##' will have dropped out after 365 days with a Weibull hazard rate with shape=1.2. If shape is not included then
##' it defaults to 1 (exponential rate). If dropout is NULL then no subjects will drop out
##' @param ... Additional arguments to be passed to the method
##' @docType methods
##' @return A \code{FromDataResults} object
##' @export
if(!isGeneric("simulate")){
setGeneric("simulate", function(object,data,SimParams,...) standardGeneric("simulate"))
}
##' @rdname simulate-methods
##' @name simulate
##' @aliases simulate,ANY,missing,missing-method
##' @export
setMethod("simulate",signature=c("ANY","missing","missing"),
function(object,...){
stats::simulate(object=object,...)
})
##' @rdname simulate-methods
##' @name simulate
##' @aliases simulate,EventModel,missing,missing-method
##' @export
setMethod("simulate",signature=c("EventModel","missing","missing"),function(object,...){
simulate(data=object@event.data,SimParams=object@simParams,...)
})
##' @rdname simulate-methods
##' @name simulate
##' @aliases simulate,EventModel,EventData,missing-method
##' @export
setMethod("simulate",signature=c("EventModel","EventData","missing"),function(object,data,...){
if(data@followup!=object@event.data@followup){
warning("Model data followup does not equal EventData followup. EventData followup will be used")
}
simulate(data=data,SimParams=object@simParams,...)
})
##' @rdname simulate-methods
##' @name simulate
##' @aliases simulate,EventModel,missing,FromDataSimParam-method
##' @export
setMethod("simulate",signature=c("EventModel","missing","FromDataSimParam"),function(object,SimParams,...){
simulate(data=object@event.data,SimParams=SimParams,...)
})
##' @rdname simulate-methods
##' @name simulate
##' @aliases simulate,missing,EventData,FromDataSimParam-method
##' @export
setMethod("simulate",signature=c("missing","EventData","FromDataSimParam"),
function(data,SimParams,accrualGenerator=NULL,Naccrual=0, Nsim=1e4, seed=NULL, limit=0.05,
longlagsettings=NULL,HR=NULL,r=NULL,dropout=NULL){
#validate the arguments
validate.simulate.arguments(accrualGenerator,Naccrual,Nsim,seed,
limit,longlagsettings,HR,r,data)
#calculate the dropout rate and shape for drop out
dropoutctrlSpec <- CtrlSpecFromList(dropout,eventtext="",1)[[1]]
dropout.shape <- if(is.null(dropout) || is.null(dropout$shape)) 1 else dropout$shape
dropout.rate <- log(2)^(1/dropout.shape)/dropoutctrlSpec@median
#set seed to be used
if(!is.null(seed)) set.seed(seed)
#pre-process data to deal with subjects censored
#a long time in the past
indat <- DealWithReportingLag(data@subject.data,longlagsettings)
#create matrix of subject recruitment times including additional
#accrual we have a matrix with 1 row per simulation, 1 column per subject
rec.details <- CalculateAccrualTimes(Naccrual,Nsim,indat$rand.date,accrualGenerator)
#calculate quantiles from the recruitment details matrix for storing in output
recQuantiles <- SimQOutputFromMatrix(rec.details,limit,Nsim)
#subset the recruitment details to get the new subjects
newrecs <- if(Naccrual!= 0) rec.details[,(ncol(rec.details)-Naccrual+1):ncol(rec.details)]
else NULL
#generate the simulation specific parameters
#e.g. rate and shape Weibull parameters used for each simulation
singleSimParams <- SimParams@generateParameterFunction(Nsim)
#perform the simulations
outcomes <-apply(singleSimParams, 1, PerformOneSimulation,
number.subjects=nrow(indat),
Naccrual=Naccrual,
indat=indat,newrecs=newrecs,HR=HR,r=r,
dropout.rate=dropout.rate,
dropout.shape=dropout.shape, followup=data@followup,
conditionalFunction=SimParams@conditionalFunction)
#post process the output
event.type <- sapply(outcomes,function(x){x$event.type})
if(class(event.type)=="numeric") event.type <- matrix(event.type,ncol=Nsim)
times <- sapply(outcomes,function(x){x$event.times})
if(class(times)=="numeric") times <- matrix(times,ncol=Nsim)
#calculate the quantiles for the events and dropouts
event.times <- t(times)
eventQuantiles <- SimQOutputFromMatrix(event.times,limit,Nsim,event.type=t(event.type),non.inf.event.type=0)
dropoutQuantiles <- SimQOutputFromMatrix(event.times,limit,Nsim,event.type=t(event.type),non.inf.event.type=1)
#use a dummy AccrualGenerator if one not given
if(is.null(accrualGenerator))
accrualGenerator <- new("AccrualGenerator",f=function(N){NULL},model="NONE",text="NONE")
return(new("FromDataResults",
eventQuantiles = eventQuantiles,
recQuantiles=recQuantiles,
limit = limit,
event.data = data,
accrualGenerator=accrualGenerator,
Naccrual=Naccrual,
time.pred.data=EmptyPredictionDF(),
event.pred.data=EmptyPredictionDF(),
singleSimDetails=SingleSimDetails(event.type=event.type,event.times=times,rec.times=t(rec.details)),
dropout.shape=dropout.shape,
dropout.rate=dropout.rate,
dropoutQuantiles=dropoutQuantiles,
simParams=SimParams
))
})