Skip to content

Commit cdf3c97

Browse files
authored
Merge pull request #48 from generable/develop
v0.3.0
2 parents ff81af1 + 75357d4 commit cdf3c97

12 files changed

Lines changed: 117 additions & 103 deletions

File tree

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: bmstate
22
Type: Package
33
Title: Bayesian multistate modeling
4-
Version: 0.2.11
4+
Version: 0.3.0
55
Authors@R:
66
c(person(given = "Juho",
77
family = "Timonen",

R/MultistateModel.R

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ MultistateModel <- R6::R6Class("MultistateModel",
4747
categorical = NULL,
4848
normalizer_locations = NULL,
4949
normalizer_scales = NULL,
50-
auc_normalizer_loc = 2000,
51-
auc_normalizer_scale = 1000,
50+
xpsr_normalizer_loc = 7.5,
51+
xpsr_normalizer_scale = 0.5,
5252
n_grid = NULL,
5353
simulate_log_hazard_multipliers = function(df_subjects, beta) {
5454
ts <- self$target_states()
5555
x <- self$covs()
56-
auc_norm <- self$get_auc_normalizers()
56+
xpsr_norm <- self$get_xpsr_normalizers()
5757
B <- length(ts)
5858
K <- length(x)
5959
checkmate::assert_matrix(beta, nrows = B, ncols = K)
@@ -64,10 +64,10 @@ MultistateModel <- R6::R6Class("MultistateModel",
6464
X <- df_subjects |> dplyr::select(tidyselect::all_of(x))
6565
X <- as.matrix(X)
6666
X_norm <- normalize_columns(X)
67-
if ("ss_auc" %in% x) {
68-
idx <- which(x == "ss_auc")
69-
x_norm <- (X[, idx] - auc_norm$loc) / auc_norm$scale
70-
check_normalized_covariate(x_norm, "ss_auc")
67+
if ("xpsr" %in% x) {
68+
idx <- which(x == "xpsr")
69+
x_norm <- (X[, idx] - xpsr_norm$loc) / xpsr_norm$scale
70+
check_normalized_covariate(x_norm, "xpsr")
7171
X_norm[, idx] <- x_norm
7272
}
7373
for (s in seq_len(S)) {
@@ -149,28 +149,28 @@ MultistateModel <- R6::R6Class("MultistateModel",
149149
invisible(NULL)
150150
},
151151

152-
#' @description Get normalization constants for AUC (PK)
152+
#' @description Get normalization constants for exposure (PK)
153153
#' @return list
154-
get_auc_normalizers = function() {
154+
get_xpsr_normalizers = function() {
155155
list(
156-
loc = private$auc_normalizer_loc,
157-
scale = private$auc_normalizer_scale
156+
loc = private$xpsr_normalizer_loc,
157+
scale = private$xpsr_normalizer_scale
158158
)
159159
},
160160

161-
#' @description Set normalization constants for AUC (side effect)
161+
#' @description Set normalization constants for exposure (side effect)
162162
#'
163163
#' @param loc Location
164164
#' @param scale Scale
165-
set_auc_normalizers = function(loc = 0, scale = 1) {
165+
set_xpsr_normalizers = function(loc = 0, scale = 1) {
166166
checkmate::assert_numeric(loc, lower = 0, len = 1)
167167
checkmate::assert_numeric(scale, lower = 0, len = 1)
168168
message(
169-
"setting auc normalizers to loc = ",
169+
"setting xpsr normalizers to loc = ",
170170
round(loc, 5), ", scale = ", round(scale, 5)
171171
)
172-
private$auc_normalizer_loc <- loc
173-
private$auc_normalizer_scale <- scale
172+
private$xpsr_normalizer_loc <- loc
173+
private$xpsr_normalizer_scale <- scale
174174
invisible(NULL)
175175
},
176176

@@ -211,7 +211,7 @@ MultistateModel <- R6::R6Class("MultistateModel",
211211
#' @param system A \code{\link{MultistateSystem}}
212212
#' @param covariates The names of the hazard covariates (excluding possible
213213
#' exposure estimated from PK model). Do not use reserved names
214-
#' \code{ss_auc} or \code{dose}.
214+
#' \code{xpsr} or \code{dose}.
215215
#' @param pk_model A \code{\link{PKModel}} or NULL.
216216
#' @param t_max Max time.
217217
#' @param num_knots Total number of spline knots.
@@ -232,7 +232,7 @@ MultistateModel <- R6::R6Class("MultistateModel",
232232
if (!all(categorical %in% covariates)) {
233233
stop("all categorical covariates should be also in covariates")
234234
}
235-
checkmate::assert_true(!("ss_auc" %in% covariates)) # special name
235+
checkmate::assert_true(!("xpsr" %in% covariates)) # special name
236236
checkmate::assert_true(!("dose" %in% covariates)) # special name
237237
checkmate::assert_class(system, "MultistateSystem")
238238
checkmate::assert_integerish(n_grid, lower = 10, len = 1)
@@ -310,7 +310,7 @@ MultistateModel <- R6::R6Class("MultistateModel",
310310
covs = function() {
311311
x <- private$hazard_covariates
312312
if (self$has_pk()) {
313-
x <- c(x, "ss_auc")
313+
x <- c(x, "xpsr")
314314
}
315315
unique(x)
316316
},

R/MultistateModelFit.R

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,9 @@ msmfit_covariate_effects <- function(fit) {
292292
df <- rbind(df, df_j)
293293
}
294294
if (fit$model$has_pk()) {
295-
rv <- as.vector(fit$get_draws("beta_auc")[1, 1, ])
295+
rv <- as.vector(fit$get_draws("beta_xpsr")[1, 1, ])
296296
df_j <- data.frame(
297-
covariate = "ss_auc", beta = rv,
297+
covariate = "xpsr", beta = rv,
298298
target_state_idx = fit$model$target_states()
299299
)
300300
df <- rbind(df, df_j)
@@ -344,9 +344,11 @@ mat2list <- function(mat) {
344344
#' @param oos Out-of-sample mode? If \code{FALSE}, the possible subject-specific
345345
#' fitted parameters are used. If \code{TRUE}, acting
346346
#' as if the subjects are new.
347+
#' @param log Get logarithm of params?
347348
#' @return A list with length equal to number of draws.
348-
msmfit_pk_params <- function(fit, oos = FALSE, data = NULL) {
349+
msmfit_pk_params <- function(fit, oos = FALSE, data = NULL, log = FALSE) {
349350
check_oos(oos, data)
351+
checkmate::assert_logical(log, len = 1)
350352
sd <- msmfit_stan_data(fit, data)
351353
S <- fit$num_draws()
352354

@@ -372,9 +374,9 @@ msmfit_pk_params <- function(fit, oos = FALSE, data = NULL) {
372374
# Call exposed Stan function for each draw (not optimal)
373375
out <- list()
374376
for (s in seq_len(S)) {
375-
theta <- NULL
377+
log_theta <- NULL
376378
if (sd$do_pk == 1) {
377-
theta <- compute_theta_pk(
379+
log_theta <- compute_log_theta_pk(
378380
mat2list(t(log_z[s, 1, , ])),
379381
log_mu[s, 1, ],
380382
log_sig[s, 1, ],
@@ -386,6 +388,11 @@ msmfit_pk_params <- function(fit, oos = FALSE, data = NULL) {
386388
mat2list(t(sd$x_V2))
387389
)
388390
}
391+
if (log) {
392+
theta <- log_theta
393+
} else {
394+
theta <- exp(log_theta)
395+
}
389396
out[[s]] <- theta
390397
}
391398
out
@@ -400,18 +407,18 @@ msmfit_exposure <- function(fit, oos = FALSE, data = NULL) {
400407

401408
# Get draws
402409
sd <- msmfit_stan_data(fit, data)
403-
pkpar <- msmfit_pk_params(fit, oos, data)
410+
log_pkpar <- msmfit_pk_params(fit, oos, data, log = TRUE)
404411

405412
# Call exposed Stan function
406413
S <- fit$num_draws()
407414
out <- list()
408415
for (s in seq_len(S)) {
409416
if (sd$do_pk == 1) {
410-
x_auc <- sd$dose_ss / (pkpar[[s]][, 2] * pkpar[[s]][, 3]) # D/(CL*V2)
417+
x_xpsr <- log_ss_area_under_conc(sd$dose_ss, log_pkpar[[s]]) # log D/(CL*V2)
411418
} else {
412-
x_auc <- NULL
419+
x_xpsr <- NULL
413420
}
414-
out[[s]] <- x_auc
421+
out[[s]] <- x_xpsr
415422
}
416423
out
417424
}
@@ -445,16 +452,16 @@ msmfit_log_hazard_multipliers <- function(fit, oos = FALSE, data = NULL) {
445452

446453
# Get draws
447454
sd <- msmfit_stan_data(fit, data)
448-
auc <- msmfit_exposure(fit, oos, data)
455+
xpsr <- msmfit_exposure(fit, oos, data)
449456
S <- fit$num_draws()
450457
beta_oth <- fit$get_draws_of("beta_oth")
451458
if (is.null(beta_oth)) {
452459
beta_oth <- array(0, dim = c(S, 1, 0, sd$N_trans_types))
453460
}
454461
if (sd$do_pk == 1) {
455-
beta_auc <- fit$get_draws_of("beta_auc")
462+
beta_xpsr <- fit$get_draws_of("beta_xpsr")
456463
} else {
457-
beta_auc <- array(0, dim = c(S, 1, 0, sd$N_trans_types))
464+
beta_xpsr <- array(0, dim = c(S, 1, 0, sd$N_trans_types))
458465
}
459466

460467
# Create x_haz_long (long version of hazard covariates vector)
@@ -465,14 +472,14 @@ msmfit_log_hazard_multipliers <- function(fit, oos = FALSE, data = NULL) {
465472
} else {
466473
x_haz_long <- array(0, dim = c(0, sd$N_int))
467474
}
468-
an <- fit$model$get_auc_normalizers()
475+
an <- fit$model$get_xpsr_normalizers()
469476

470477
# Call exposed Stan function for each draw (not optimal)
471478
out <- list()
472479
for (s in seq_len(S)) {
473480
if (sd$do_pk == 1) {
474-
ba <- list(beta_auc[s, 1, 1, ])
475-
aa <- list(auc[[s]][sd$idx_sub])
481+
ba <- list(beta_xpsr[s, 1, 1, ])
482+
aa <- list(xpsr[[s]][sd$idx_sub])
476483
} else {
477484
ba <- NULL
478485
aa <- NULL

R/PKModel.R

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,18 +102,18 @@ PKModel <- R6::R6Class("PKModel",
102102
conc
103103
},
104104

105-
#' @description Compute steady-state area under concentration curve over
106-
#' one dosing interval
105+
#' @description Compute exposure, which is the steady-state
106+
#' log area under concentration curve over one dosing interval
107107
#'
108108
#' @param theta parameter values
109109
#' @param dose dose
110110
#' @return A numeric value
111-
compute_ss_auc = function(theta, dose) {
111+
compute_xpsr = function(theta, dose) {
112112
CL <- theta[2]
113113
V2 <- theta[3]
114114
checkmate::assert_number(CL, lower = 0)
115115
checkmate::assert_number(dose, lower = 0)
116-
dose / (CL * V2)
116+
log(dose) - log(CL * V2)
117117
},
118118

119119
#' @description Simulate data with many subjects
@@ -159,17 +159,17 @@ PKModel <- R6::R6Class("PKModel",
159159
CONC <- dd$simulate_pk(t_obs, THETA, self$get_max_conc())
160160
df_out <- NULL
161161
for (n in seq_len(N)) {
162-
ss_auc <- self$compute_ss_auc(THETA[n, ], dd$dose_ss[n])
162+
xpsr <- self$compute_xpsr(THETA[n, ], dd$dose_ss[n])
163163
sid <- SUB_ID[n]
164164
conc <- (CONC |> dplyr::filter(.data$subject_id == sid))[["val"]]
165165
conc_noisy <- stats::rlnorm(2, meanlog = log(conc), sdlog = sigma)
166-
out <- c(t_obs[[n]], conc_noisy, ss_auc)
166+
out <- c(t_obs[[n]], conc_noisy, xpsr)
167167
df_out <- rbind(df_out, out)
168168
}
169169
df_out <- data.frame(df_out)
170170
df_out <- cbind(df_out, THETA)
171171
colnames(df_out) <- c(
172-
"t_pre", "t_post", "conc_pre", "conc_post", "ss_auc",
172+
"t_pre", "t_post", "conc_pre", "conc_post", "xpsr",
173173
"ka", "CL", "V2"
174174
)
175175
rownames(df_out) <- NULL

R/stan-data.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ create_stan_data_model <- function(model) {
4040
sd_t_grid <- create_stan_data_timegrid(model)
4141

4242
# PK options
43-
an <- model$get_auc_normalizers()
43+
an <- model$get_xpsr_normalizers()
4444
MC <- 1e-7
4545
if (model$has_pk()) {
4646
MC <- model$pk_model$get_max_conc()
@@ -49,9 +49,9 @@ create_stan_data_model <- function(model) {
4949
nc_ka = length(model$data_covs("ka")),
5050
nc_CL = length(model$data_covs("CL")),
5151
nc_V2 = length(model$data_covs("V2")),
52-
I_auc = as.numeric(model$has_pk()),
53-
auc_loc = an$loc,
54-
auc_scale = an$scale,
52+
I_xpsr = as.numeric(model$has_pk()),
53+
xpsr_loc = an$loc,
54+
xpsr_scale = an$scale,
5555
MAX_CONC = MC
5656
)
5757

R/stan.R

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,12 @@ fit_stan <- function(model, data,
101101
if (set_normalizers) {
102102
model$set_normalizers(data)
103103
if (!is.null(data$dosing)) {
104-
mu_CL <- exp(-2) # should match msm.stan
105-
mu_V2 <- exp(-2) # should match msm.stan
106-
aaa <- data$dosing$dose_ss / (mu_CL * mu_V2)
104+
log_mu_CL <- -2 # should match msm.stan
105+
log_mu_V2 <- -2 # should match msm.stan
106+
aaa <- log(data$dosing$dose_ss) - log_mu_CL - log_mu_V2
107107
loc <- mean(aaa)
108108
sca <- stats::sd(aaa)
109-
model$set_auc_normalizers(loc, sca)
109+
model$set_xpsr_normalizers(loc, sca)
110110
}
111111
}
112112

@@ -133,7 +133,7 @@ fit_stan <- function(model, data,
133133
# Return
134134
pars <- c(
135135
"weights", "log_w0", "beta_ka", "beta_V2", "beta_CL", "beta_oth",
136-
"beta_auc", "sigma_pk", "log_z_pk", "log_mu_pk", "log_sig_pk", "lp__"
136+
"beta_xpsr", "sigma_pk", "log_z_pk", "log_mu_pk", "log_sig_pk", "lp__"
137137
)
138138
draws <- create_rv_list(stan_fit, pars)
139139
diag <- NULL

0 commit comments

Comments
 (0)