Diff of /R/fromDataSimParam.R [000000] .. [f2e496]

Switch to unified view

a b/R/fromDataSimParam.R
1
#This file contains the definition of the class required for simulating
2
#subject event times in the from Data part of the package -i.e. the rate and
3
#shape used in the condtional Weibull distribution
4
5
setOldClass("survreg")
6
7
##' An S4 class containing the function required
8
##' to simulate conditional survival times
9
##' @slot type A character string describing the distribution used
10
##' for example "Weibull"
11
##' @slot generateParameterFunction A function with a single parameter Nsim which returns
12
##' a matrix with Nsim rows and columns Id(=1:Nsim) and the specific parameters needed by
13
##' conditionalFunction below. In the Weibull case these are the specific rate and shape 
14
##' parameters used for each simulation
15
##' @slot conditionalFunction A function with the following arguments t.conditional, params, HR.
16
##' t.conditional is a vector of current survival times, params is a row of the matrix returned
17
##' by generateParameterFunction and HR is a vector of 1s for subjects in control arm and the hazard ratio 
18
##' for subjects in the active arm (if HR argument to simulate is NULL then this is a vector of 1s). The function
19
##' then returns a vector of event times. 
20
##' @slot parameters A list of parameters used for the simulation. For the Weibull this is
21
##' rate, shape and sigma (the uncertainty matrix of the parameters - specifically the covariance matrix from survreg)
22
##' @aliases FromDataSimParam.class
23
##' @export
24
setClass("FromDataSimParam", 
25
         slots=list(type="character",
26
                    conditionalFunction="function",
27
                    generateParameterFunction="function",
28
                    parameters="list")
29
)
30
31
32
# Sample from a conditional Weibull distribution.
33
#
34
# This function is used as the conditionalFunction for
35
# a Weibull FromDataSimParam simulation and also used
36
# to simulate subject dropouts
37
#
38
# cdf: \code{F(t) = 1 - exp(-(t*rate)^shape)}
39
# subject to \code{t > t.conditional}
40
# Therefore all results will be \code{>t.conditional}
41
# @param t.conditional A vector of survival times subjects have already survived until
42
# @param params A named vector of parameters including shape and rate
43
# @param HR A vector of Hazard ratios for each subject (if =1 then subject is on control/only) arm
44
# @return A vector of survival times 
45
rcweibull <- function(t.conditional, params, HR) {
46
  params <- as.list(params)
47
  params$rate <- params$rate*(HR)^{1/params$shape}
48
  t.conditional <- t.conditional*params$rate
49
  ((t.conditional^params$shape + rexp(length(t.conditional)))^(1/params$shape))/params$rate
50
}
51
52
# Sample from a conditional loglogistic distribution.
53
#
54
# This function is used as the conditionalFunction for
55
# a loglogistic FromDataSimParam simulation and also used
56
# to simulate subject dropouts
57
#
58
#
59
# @param t.conditional A vector of survival times subjects have already survived until
60
# @param params A named vector of parameters including shape and rate
61
# @param HR A vector of Hazard ratios for each subject must be a vector of 1's for 
62
# the loglogistic, see rcweibull for more details
63
# @return A vector of survival times 
64
rcloglogistic <- function(t.conditional,params,HR){
65
  if(any(HR!=1)){
66
    stop("Cannot use HR argument with loglogistic model")
67
  }
68
  params <- as.list(params)
69
  
70
  retVal <- 1+(t.conditional*params$rate)^params$shape
71
  retVal <- retVal/runif(length(t.conditional)) - 1
72
  retVal^(1/params$shape)/params$rate
73
74
}
75
76
77
##' Method to create FromDataSimParam objects
78
##' @param object The object to derive the fromDataParam
79
##' @param type The type argument to be used in the FromDataSimParam type slot
80
##' @param ... Additional options to be passed into the function
81
##' @rdname FromDataParam-methods
82
##' @name FromDataParam
83
##' @export
84
setGeneric("FromDataParam",function(object,type,...) standardGeneric("FromDataParam"))
85
86
##' Create FromDataSimParam object from survreg model
87
##' @rdname FromDataParam-methods
88
##' @name FromDataParam
89
##' @aliases FromDataParam,survreg,character-method
90
##' @export
91
setMethod("FromDataParam",signature=c(object="survreg",type="character"),
92
  function(object,type){
93
            
94
    if(!object$dist %in% c("weibull","loglogistic")){
95
      stop("Invalid model for FromDataSimParam function")
96
    }
97
    
98
    if(object$dist != type){
99
      stop("Argument mismatch in FromDataParam")
100
    }
101
            
102
    rate <-  1/exp(object$coefficient)
103
    shape <- 1/object$scale
104
    sigma <- object$var 
105
            
106
    FromDataParam(type=type,rate=rate,shape=shape,sigma=sigma)
107
            
108
  }
109
)
110
111
##' @param rate The (mean) Weibull/loglogistic rate parameter for the simulations
112
##' @param shape The (mean) Weibull/loglogistic shape parameter for the simulations
113
##' @param sigma Advanced: The covariance (uncertainty) matrix used to sample single
114
##' simulation rates and shapes. The covariance matrix describes the uncertainty of
115
##' {-log(rate),-log(shape)} - i.e. the var matrix of a survreg Weibull/loglogistic survival model  
116
##' @rdname FromDataParam-methods
117
##' @aliases FromDataParam,missing,character-method
118
##' @name FromDataParam
119
##' @export
120
setMethod("FromDataParam",signature=c(object="missing",type="character"),
121
  function(object,type,rate,shape,sigma=matrix(c(0,0,0,0),nrow=2)){
122
         
123
    if(!type %in% c("weibull","loglogistic")){
124
      stop("Invalid type")
125
    }
126
       
127
    validate.fromData.arguments(rate,shape,sigma)
128
    
129
         
130
    parameters <- list(rate=rate,shape=shape,sigma=sigma)  
131
    
132
    generateParameterFunction <- function(Nsim){
133
      w.scale <- log(1/parameters$rate)
134
      w.shape <- 1/parameters$shape
135
      s <- rmvnorm(Nsim, mean = c(w.scale, log(w.shape)), sigma = parameters$sigma)
136
      cbind(Id=1:Nsim,
137
            rate=exp(-s[,1]), #rate (standard parameters) 
138
            shape=exp(-s[,2])) #shape (standard parameters)
139
    }
140
            
141
   
142
    conditionalFunction <-  if(type=="weibull") rcweibull else rcloglogistic
143
    
144
    new("FromDataSimParam",type=type,parameters=parameters,
145
        conditionalFunction=conditionalFunction,
146
        generateParameterFunction=generateParameterFunction)
147
  }
148
)
149
150
# Check the Weibull/loglogistic rate and shape parameters are sensible
151
# @param rate proposed rate
152
# @param shape proposed shape
153
# @param sigma proposed covariance matrix of -log(rate), -log(shape)
154
validate.fromData.arguments <- function(rate,shape,sigma){
155
  if(!is.numeric(rate) || length(rate) != 1 || rate <= 0){
156
    stop("Invalid rate argument")
157
  } 
158
  
159
  if(!is.numeric(shape) || length(shape) != 1 || shape <= 0){
160
    stop("Invalid shape argument")
161
  } 
162
  
163
  if(!is.matrix(sigma) || !is.numeric(sigma)){
164
    stop("Invalid uncertainty matrix argument, it must be a numeric matrix")
165
  }
166
  
167
  if(nrow(sigma)!=2 || ncol(sigma)!=2 || sigma[1,2]!=sigma[2,1]){
168
    stop("Invalid uncertainty matrix it must be a symmetric 2x2 matrix")
169
  }
170
  
171
  min.val <- 1e-15
172
  max.val <- 1e15
173
  
174
  if(rate < min.val || rate > max.val){
175
    stop(paste("The rate parameter=",rate," and is outside the range [",min.val,",",max.val,"]",
176
               " Is this correct",sep=""))
177
  }
178
  if(shape < min.val || shape > max.val){
179
    stop(paste("The shape parameter=",shape," and is outside the range [",min.val,",",max.val,"]",
180
               " Is this correct?",sep=""))
181
  }
182
}