a b/R/simQOutput.R
1
#Contains the functions associated with class SimQOutput for the 
2
#from data part of the project. See class definition below
3
4
##' A class containing the expected (and CI) dates for a specific item of interest
5
##'
6
##' For example subject recruitment, events occurring, or subject dropout. 
7
##' Each item of interest will have its own SimQOutput object. This class will
8
##' be created for the user and does not need to be manually created
9
##' 
10
##' As an example median[1] is the expected date of the first specific item of interest
11
##' whereas upper[1] is the upper CI of the first specific item of interest.
12
##' @slot median A vector of the expected (i.e median) dates 
13
##' of the first, second, ..., item of interest
14
##' The length of the vector is the total number of this type of item. 
15
##' @slot upper A vector of the expected dates for the upper CI 
16
##' of the first, second, ..., item of interest
17
##' @slot lower A vector of the expected dates for the lower CI
18
##'  of the first, second, ..., item of interest
19
##' @seealso \code{\link{simulate,EventModel,missing,missing-method}} \code{\link{FromDataResults-class}}
20
##' @export
21
setClass("SimQOutput", 
22
         slots=list(
23
           upper="Date",
24
           median="Date",
25
           lower="Date"
26
         )
27
)
28
29
# Constructor for \code{SimQOutput} object
30
# 
31
# See class description for further details
32
# @param upper A vector of the upper CI dates
33
# @param median A vector for the median dates
34
# @param lower A vector for the lower CI dates 
35
# @return A \code{SimQOutput} object
36
SimQOutput <- function(upper,median,lower){
37
  
38
  if(length(upper)!= length(median) || length(median) != length(lower)){
39
    stop("Invalid arguments when creating SimQOutput object")
40
  }
41
  
42
  
43
  new("SimQOutput",upper=upper,median=median,lower=lower)
44
  
45
}
46
47
48
# Create a SimQOutput object from a matrix of (numeric) Dates
49
# @param details An unsorted matrix with 1 column per subject
50
# and one row per simulation of numeric Dates
51
# @param limit limit and 1 - limit will be used as the quantile
52
# values to be calculated for the lower and upper slot returned SimQOutput object
53
# @param Nsim The number of rows in \code{details}
54
# @param event.type An unsorted matrix with 1 column per subject
55
# and one row per simulation of event.types (integers)
56
# @param non.inf.event.type Only dates in the details matrix which have event.type=
57
# non.inf.event.type will be taken into account for the SimQOutput object all others
58
# will be ignored
59
# @return A SimQOutput object with the median and quantiles derived from 
60
# the details matrix
61
SimQOutputFromMatrix <- function(details,limit,Nsim,event.type=NULL,non.inf.event.type=NULL){
62
  
63
  if(!is.null(event.type)){
64
    details[event.type!=non.inf.event.type] <- as.Date(Inf,origin="1970-01-01")
65
  }
66
  
67
  times <- apply(details,1,sort)
68
  if(class(times)=="numeric") times <- matrix(times,ncol=Nsim)
69
  times <- apply(times, 1, stats::quantile, prob=c(limit, 0.5, 1-limit))
70
  
71
  ans <- lapply(1:3,function(x){as.Date(times[x,],origin="1970-01-01")})
72
  
73
  w <- which(!(ans[[3]]==ans[[2]]& ans[[2]]==ans[[1]] & ans[[1]]==WithdrawnEventDate()))
74
  
75
  SimQOutput(
76
    upper = ans[[3]][w],
77
    median= ans[[2]][w], 
78
    lower = ans[[1]][w] 
79
  )
80
}
81
82
83
84
##' @name show
85
##' @rdname show-methods
86
##' @aliases show,SimQOutput-method
87
##' @export
88
setMethod("show",
89
          "SimQOutput",
90
function(object) {
91
  cat("Lower CI:\n")
92
  cat(str(object@lower))
93
  cat("\nMedian:\n")
94
  cat(str(object@median))
95
  cat("\nUpper CI:\n")
96
  cat(str(object@upper))
97
  cat("\n")
98
})
99
100
101
# Output the expected time a given number of events occur
102
# @param event.pred A vector of target event levels
103
# @param simQ A SimQOutput object (i.e. eventQuantiles slot of WeibullResults)
104
# @return A data frame containing the median times and confidence intervals for the target event levels
105
PredictGivenTargetEvents <- function(event.pred,simQ){
106
  
107
  if(any(event.pred <= 0 || event.pred > length(simQ@median))) 
108
    stop("Invalid event.pred value")
109
  
110
  ans <- lapply(event.pred,function(x){
111
    list(time=simQ@median[x],
112
         event=x,
113
         CI_low=simQ@lower[x],
114
         CI_high=simQ@upper[x])    
115
  })
116
  
117
  ans <- do.call(rbind.data.frame, ans)
118
  ans$time <- as.Date(ans$time,origin="1970-01-01")
119
  ans$CI_high <- as.Date(ans$CI_high,origin="1970-01-01")
120
  ans$CI_low <- as.Date(ans$CI_low,origin="1970-01-01")
121
  ans
122
}
123
124
# Output the expected (median) number of events for a given set of dates
125
# @param time.pred A vector of dates
126
# @param simQ A SimQOutput object (i.e. eventQuantiles slot of WeibullResults)
127
# @return A data frame containing the median  and confidence intervals for the number of events
128
# at the requested dates
129
PredictGivenDates <- function(time.pred,simQ){
130
  
131
  findEvents <- function(date,event.times){
132
    if(date < event.times[1]) return(0)
133
    if(date > event.times[length(event.times)]) return (length(event.times))
134
    
135
    start <- 0
136
    end <- length(event.times)
137
    
138
    while(end-start>1){
139
      centre <- floor((start+end)/2)
140
      if(date < event.times[centre]){
141
        end <- centre
142
      }
143
      else{
144
        start <- centre
145
      }
146
    }
147
    return(start)
148
    
149
  }
150
  
151
  ans <- lapply(time.pred,function(x){
152
    list(time=x,
153
         event=findEvents(x,simQ@median),
154
         CI_low=findEvents(x,simQ@upper), #These are the right way round!
155
         CI_high=findEvents(x,simQ@lower)
156
    )    
157
  })
158
  ans <- do.call(rbind.data.frame, ans)
159
  ans$time <- as.Date(ans$time,origin="1970-01-01")
160
  
161
  ans
162
  
163
}