forked from kylebaron/learn
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhandson_opg_answer.Rmd
executable file
·265 lines (187 loc) · 4.74 KB
/
handson_opg_answer.Rmd
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
---
title: "Fc-OPG PK/PD in healthy post-menopausal women"
author: ""
date: ""
output:
html_document:
theme: united
---
<hr><div class = spacersm></div>
```{r,echo=FALSE}
knitr::opts_chunk$set(comment = '.', warning = FALSE, message = FALSE)
```
# Packages
```{r}
proj <- "models"
library(mrgsolve)
library(dplyr)
library(magrittr)
library(parallel)
library(ggplot2)
```
<hr><div class = spacer></div>
## Question
- What is the mean change from baseline 14 days after 3 mg/kg SC dose?
- What is the probability that mean CFB is greater than 40%?
<hr><div class = spacer></div>
# OPG model
```{r}
mod <- mread("opg", "model")
mod
```
Checkout the random effects structure
```{r}
revar(mod)
```
```{r}
mod %<>% mrgsolve:::collapse_omega()
mod %<>% mrgsolve:::collapse_sigma()
```
We can render this in to an `Rmarkdown` document
```{r,eval=FALSE}
mrgsolve:::render(mod)
```
<hr><div class = spacer></div>
# Load the simulated posterior
```{r}
post <- readRDS("data/opgpost.RDS") %>% sample_n(1000)
```
For most of our examples, we are taking output directly
from a NONMEM run. This example is a little different:
We have changed the column names from `THETA1`, `THETA2`
etc ... to `TVCL`, `TVVC` etc ...
```{r,eval=FALSE}
head(post)
inventory(mod,post)
```
```{r}
post <- mutate(post, TVVP1 = TVP1, TVVP2 = TVP2)
```
When working with results out of NONMEM, it is common to get
the `THETA` , `OMEGA` and `SIGMA` estimates all in a single
row in a data frame.
In order to get the information for `OMEGA` and `SIGMA` in to
the problem, we need to go into this data and
form matrices.
There are two specialized functions to help with this:
- `as_bmat` when the data is in block format
- `as_dmat` when the data is in diagonal format
```{r}
omegas <- as_bmat(post,"OMEGA")
sigmas <- as_bmat(post,"SIGMA")
```
Here is a simple dosing data set to simulate 100 patients with
3 mg/kg Fc-OPG SC x1
```{r}
sc3 <- expand.ev(ID=1:100, amt=210)
head(sc3)
```
We will get the observation design for the simulation
through a `tgrid` object
```{r}
des <- tgrid(end=-1,add=c(0,24*14))
des
```
When we do replicate simulation, it almost always pays off
to construct a function that will carry out one
replicate.
Arguments to the function are
- `i` the current simulation replicate
- `data` the dosing data set
- `des` the observation design
```{r}
sim <- function(i,data,des) {
mod %<>%
param(slice(post,i)) %>%
omat(omegas[[i]]) %>%
smat(sigmas[[i]])
mod %>%
Req(PDDV) %>%
mrgsim(data=data,tgrid=des,obsonly=TRUE) %>%
mutate(irep=i) %>%
mutate(TVIC50=mod$TVIC50, TVQ1=mod$TVQ1, TVVMAX=mod$TVVMAX)
}
```
Also note
- We update `param` with `ith` row from `post`
- We update `OMEGA` and `SIGMA` from the `ith` position
in the appropriate list of matrices
- We will capture the current
It is easy to test the function. The 10th replicate will
look like this
```{r}
sim(10,sc3,des)
```
Simulate reps
```{r}
options(mc.cores=8)
mcRNG()
set.seed(22223)
out <- mclapply(1:1000, mc.cores = 8, sim, data=sc3,des=des) %>% bind_rows
```
Summarise
- First, get the baseline `NTX`
- Then calculate percent CFB
```{r}
sum <-
out %>%
group_by(ID,irep) %>%
mutate(BASE = first(PDDV), dDV = 100*(PDDV-BASE)/BASE) %>%
ungroup
```
Filter down to week 2
```{r}
sum %<>% filter(time==336 & BASE >= 0)
```
Now, get the median
```{r}
summ <-
sum %>%
filter(time==336) %>%
group_by(irep) %>%
summarise(med = median(dDV))
```
<hr><div class = spacer></div>
## From the abstract
> Subsequent clinical trial simulations demonstrated that a single 3.0-mg/kg SC dose of Fc-OPG would be expected to produce, at 14 days post-dose, a median NTX percentage change from baseline of −45% (with a 95% prediction interval ranging from −34% to −60%)."
```{r}
ans <- signif(quantile(summ$med, c(0.5,0.025,0.975)),3)
paste0(ans[1], " (", ans[3],",",ans[2],")")
```
Median week-2 change from baseline with 95% interval
Probability that median cfb > 40%
```{r}
mean(summ$med < -40)
```
Plot the distribution of the week-2 change from baseline
```{r}
ggplot(summ, aes(x=med)) +
geom_histogram(fill="darkslateblue", col="grey")
```
<hr><div class = spacer></div>
# Sensitivity analysis
We are already set up to do the sensitivity analysis
```{r}
par <- dplyr::distinct(out,irep,TVIC50,TVQ1,TVVMAX)
head(par)
sens <- left_join(summ,par)
head(sens)
```
`TVIC50`
```{r}
ggplot(sens, aes(TVIC50, med)) +
geom_point(col="darkslateblue") +
geom_smooth(method="loess",col="red",lwd=2)
```
`TVVMAX`
```{r}
ggplot(sens, aes(TVVMAX, med)) +
geom_point(col="darkslateblue") +
geom_smooth(method="loess",col="red",lwd=2)
```
`TVQ`
```{r}
ggplot(sens, aes(TVQ1, med)) +
geom_point(col="darkslateblue") +
geom_smooth(method="loess",col="red",lwd=2)
```