Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update for Analysis Vignette #17

Merged
merged 50 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
87efc2b
minor formatting; adding newline breaks
stevegbrooks Feb 25, 2024
cae733a
added references.bib; adjusted .qmd for refs links
stevegbrooks Feb 25, 2024
bba4649
made prior spec more generic
stevegbrooks Feb 25, 2024
c497027
working on dose models; improved error message for getOptParams()
stevegbrooks Feb 25, 2024
3bd13bf
add caching; use explicit namespaces
stevegbrooks Feb 25, 2024
c6898a0
edit gitignore
stevegbrooks Feb 25, 2024
3b11a21
edit gitignore
stevegbrooks Feb 25, 2024
2d0bcdf
rm quarto render stuff
stevegbrooks Feb 25, 2024
09e9813
edit gitignore
stevegbrooks Feb 25, 2024
77697a5
added missing dose shapes
stevegbrooks Mar 2, 2024
4a6fbab
display treatment effects for dose groups
stevegbrooks Mar 2, 2024
d94f8d5
formatting for quarto
stevegbrooks Mar 2, 2024
974aee4
use display_params_table custom function for bmcp results
stevegbrooks Mar 2, 2024
dbf7b9f
add display for fit and bootstrap
stevegbrooks Mar 2, 2024
ba1077d
Addition of betaMod function
sebastianbossert Mar 22, 2024
f5fd273
Name betaMod updated
sebastianbossert Mar 22, 2024
f67a5fa
bracket bug
stevegbrooks Mar 25, 2024
8c5dc36
updated dose response model parameterization section
stevegbrooks Mar 25, 2024
e8f3ce1
minor edits
stevegbrooks Mar 27, 2024
c2ee055
...
stevegbrooks Mar 27, 2024
1af58cd
edits to readability, flow of analysis_vignette; allowed getModelFits…
stevegbrooks Mar 29, 2024
d1ea476
added vignette dependencies to suggests
stevegbrooks Apr 28, 2024
688918c
corrected spelling error for modelling
stevegbrooks Apr 28, 2024
b88194a
...
stevegbrooks Apr 28, 2024
b21820d
updated print method for BayesianMCP object
stevegbrooks Apr 28, 2024
eb3c846
change name to modeling
stevegbrooks Apr 28, 2024
8a35435
updated wordlist
stevegbrooks Apr 28, 2024
ce2a0a8
updated docs
stevegbrooks Apr 28, 2024
e750aa9
spelling
stevegbrooks Apr 28, 2024
18a6386
updated vignette to be more concise
stevegbrooks Apr 28, 2024
129d744
fixed bug in getBootstrapQuantiles that didnt return level for betaMo…
stevegbrooks Apr 29, 2024
fd3fad7
...
stevegbrooks Apr 29, 2024
e4b1612
correction of bug in beta function and inclusion of beta and quadrati…
Jun 12, 2024
1c86aa9
Minor changes in the formulation and deletion of one code chunk
Jun 24, 2024
f2ba43b
test
Jun 27, 2024
9f5db72
readd vignettes
Jun 28, 2024
6aa2904
Merge branch 'main' into update-analysis-vignette
Xyarz Jun 28, 2024
537d579
minor change on DESCRIPTION file
Jun 28, 2024
110fedf
refactor
Jun 28, 2024
acf3360
adjust and add quarto in gh actions
Jun 28, 2024
408e932
adjusted gh actions
Jun 28, 2024
73228fa
fixing minor things
Jun 28, 2024
a078450
adjustment based on function changes
Jun 28, 2024
830ef94
bug fix
Jun 28, 2024
46a6e20
removed explicit calls
Jun 28, 2024
2c8390e
minor
Jun 28, 2024
0420d18
rebuild
Jun 28, 2024
58b535b
minor
Jun 28, 2024
7fa55d3
further adjustments
Jun 28, 2024
97b937d
explicit install on workflow added
Jun 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ docs
^cran-comments\.md$
^cran_submission_script\.R$
^CRAN-SUBMISSION$
^vignettes/*_files$
1 change: 1 addition & 0 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
R_KEEP_PKG_SOURCE: yes

steps:
- uses: quarto-dev/quarto-actions/setup@v2
- uses: actions/checkout@v2

- uses: r-lib/actions/setup-pandoc@v2
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
R_KEEP_PKG_SOURCE: yes

steps:
- uses: quarto-dev/quarto-actions/setup@v2
- uses: actions/checkout@v2

- uses: r-lib/actions/setup-pandoc@v2
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ jobs:
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: quarto-dev/quarto-actions/setup@v2
- uses: actions/checkout@v2

- uses: r-lib/actions/setup-pandoc@v2

- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true

- name: Install JAGS
run: |
sudo apt-get update -y
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ jobs:
R_KEEP_PKG_SOURCE: yes

steps:
- uses: quarto-dev/quarto-actions/setup@v2
- uses: actions/checkout@v2

- uses: r-lib/actions/setup-pandoc@v2
Expand All @@ -40,6 +41,10 @@ jobs:
extra-packages: any::rcmdcheck
needs: check

- name: Install BayesianMCPMod
shell: bash
run: R CMD INSTALL --preclean .

- uses: r-lib/actions/check-r-package@v2
with:
upload-snapshots: true
12 changes: 7 additions & 5 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Authors@R: c(
person("Boehringer Ingelheim Pharma GmbH & Co. KG", role = c("cph", "fnd")),
person("Stephan", "Wojciekowski", , "[email protected]", role = c("aut", "cre")),
person("Lars", "Andersen", , "[email protected]", role = "aut"),
person("Steven", "Brooks", , "steven.brooks@boehringer-ingelheim.com", role = "ctb"),
person("Sebastian", "Bossert", , "sebastian.bossert@boehringer-ingelheim.com", role = "aut")
person("Sebastian", "Bossert", , "sebastian.bossert@boehringer-ingelheim.com", role = "aut"),
person("Steven", "Brooks", , "steven.brooks@boehringer-ingelheim.com", role = "ctb")
)
Description: Bayesian MCPMod (Fleischer et al. (2022)
<doi:10.1002/pst.2193>) is an innovative method that improves the
Expand Down Expand Up @@ -38,17 +38,19 @@ Imports:
RBesT,
stats
Suggests:
reactable,
tibble,
quarto,
clinDR,
dplyr,
knitr,
rmarkdown,
spelling,
testthat (>= 3.0.0)
VignetteBuilder:
knitr
VignetteBuilder: quarto
Config/testthat/edition: 3
Encoding: UTF-8
Language: en-US
LazyData: true
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.3
RoxygenNote: 7.3.1
1 change: 0 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ S3method(print,postList)
S3method(summary,postList)
export(assessDesign)
export(getBootstrapQuantiles)
export(getBootstrapSamples)
export(getContr)
export(getCritProb)
export(getESS)
Expand Down
8 changes: 4 additions & 4 deletions R/BMCPMod.R
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
#' @title assessDesign
#'.
#' @description This function performs simulation based trial design evaluations for a set of specified dose-response models

Check warning on line 3 in R/BMCPMod.R

View workflow job for this annotation

GitHub Actions / lint

file=R/BMCPMod.R,line=3,col=81,[line_length_linter] Lines should not be more than 80 characters. This line is 124 characters.
#'
#' @param n_patients Vector specifying the planned number of patients per dose group

Check warning on line 5 in R/BMCPMod.R

View workflow job for this annotation

GitHub Actions / lint

file=R/BMCPMod.R,line=5,col=81,[line_length_linter] Lines should not be more than 80 characters. This line is 84 characters.
#' @param mods An object of class "Mods" as specified in the DoseFinding package.

Check warning on line 6 in R/BMCPMod.R

View workflow job for this annotation

GitHub Actions / lint

file=R/BMCPMod.R,line=6,col=81,[line_length_linter] Lines should not be more than 80 characters. This line is 81 characters.
#' @param prior_list A prior_list object specifying the utilized prior for the different dose groups

Check warning on line 7 in R/BMCPMod.R

View workflow job for this annotation

GitHub Actions / lint

file=R/BMCPMod.R,line=7,col=81,[line_length_linter] Lines should not be more than 80 characters. This line is 101 characters.

Check warning on line 7 in R/BMCPMod.R

View workflow job for this annotation

GitHub Actions / lint

file=R/BMCPMod.R,line=7,col=101,[trailing_whitespace_linter] Trailing whitespace is superfluous.
#' @param sd A positive value, specification of assumed sd

Check warning on line 8 in R/BMCPMod.R

View workflow job for this annotation

GitHub Actions / lint

file=R/BMCPMod.R,line=8,col=59,[trailing_whitespace_linter] Trailing whitespace is superfluous.
#' @param n_sim Number of simulations to be performed
#' @param alpha_crit_val (Un-adjusted) Critical value to be used for the MCP testing step. Passed to the getCritProb() function for the calculation of adjusted critical values (on the probability scale). Default is 0.05.

Check warning on line 10 in R/BMCPMod.R

View workflow job for this annotation

GitHub Actions / lint

file=R/BMCPMod.R,line=10,col=81,[line_length_linter] Lines should not be more than 80 characters. This line is 220 characters.
#' @param simple Boolean variable defining whether simplified fit will be applied. Passed to the getModelFits function. Default FALSE.

Check warning on line 11 in R/BMCPMod.R

View workflow job for this annotation

GitHub Actions / lint

file=R/BMCPMod.R,line=11,col=81,[line_length_linter] Lines should not be more than 80 characters. This line is 134 characters.
#' @param reestimate Boolean variable defining whether critical value should be calculated with re-estimated contrasts (see getCritProb function for more details). Default FALSE

Check warning on line 12 in R/BMCPMod.R

View workflow job for this annotation

GitHub Actions / lint

file=R/BMCPMod.R,line=12,col=81,[line_length_linter] Lines should not be more than 80 characters. This line is 177 characters.
#' @param contr An object of class 'optContr' as created by the getContr() function. Allows specification of a fixed contrasts matrix. Default NULL

Check warning on line 13 in R/BMCPMod.R

View workflow job for this annotation

GitHub Actions / lint

file=R/BMCPMod.R,line=13,col=81,[line_length_linter] Lines should not be more than 80 characters. This line is 147 characters.
#' @param dr_means A vector, allows specification of individual (not model based) assumed effects per dose group. Default NULL
#'
#' @return Returns success probabilities for the different assumed dose-response shapes, attributes also includes information around average success rate (across all assumed models) and prior Effective sample size
Expand Down Expand Up @@ -361,7 +361,7 @@
#' crit_prob_adj = critVal,
#' simple = FALSE)
#'
#' @return Bayesian MCP test result as well as modelling result.
#' @return Bayesian MCP test result as well as modeling result.
#'
#' @export
performBayesianMCPMod <- function (
Expand Down Expand Up @@ -399,7 +399,7 @@
stop ("Argument 'contr' must be of type 'optContr'")

}

b_mcp <- performBayesianMCP(
posterior_list = posterior_list,
contr = contr,
Expand All @@ -408,8 +408,8 @@
fits_list <- lapply(seq_along(posterior_list), function (i) {

if (b_mcp[i, 1]) {
sign_models <- b_mcp[i, -c(1, 2)] > attr(b_mcp, "critProbAdj")

sign_models <- b_mcp[i, -c(1, 2)] > attr(b_mcp, "crit_prob_adj")

model_fits <- getModelFits(
models = model_shapes,
Expand Down
152 changes: 53 additions & 99 deletions R/bootstrapping.R
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
#' @title getBootstrapSamples
#' @title getBootstrapQuantiles
#'
#' @description A function for the calculation of bootstrapped model predictions.
#' Samples from the posterior distribution are drawn (via the RBesT function rmix()) and for every sample the simplified fitting step (see getModelFits() function) and a prediction is performed.
#' These fits are then used to identify the specified quantiles.
#' @description A function for the calculation of bootstrapped model predictions.
#' Samples from the posterior distribution are drawn (via the RBesT function rmix()) and for every sample the simplified fitting step (see getModelFits() function) and a prediction is performed.
#' These fits are then used to identify the specified quantiles.
#' This approach can be considered as the Bayesian equivalent of the frequentist bootstrap approach described in O'Quigley et al. (2017).
#' Instead of drawing n bootstrap samples from the sampling distribution of the trial dose-response estimates, here the samples are directly taken from the posterior distribution.
#' @references O'Quigley J, Iasonos A, Bornkamp B. 2017. Handbook of Methods for Designing, Monitoring, and Analyzing Dose-Finding Trials (1st ed.). Chapman and Hall/CRC. doi:10.1201/9781315151984
#' @param model_fits An object of class modelFits, i.e. information about fitted models & corresponding model coefficients as well as the posterior distribution that was the basis for the model fitting
#'
#' @param model_fits An object of class modelFits, i.e. information about fitted models & corresponding model coefficients as well as the posterior distribution that was the basis for the model fitting
#' @param quantiles A vector of quantiles that should be evaluated
#' @param n_samples Number of samples that should be drawn as basis for the bootstrapped quantiles
#' @param doses A vector of doses for which a prediction should be performed
#' @param avg_fit Boolean variable, defining whether an average fit (based on generalized AIC weights) should be performed in addition to the individual models. Default TRUE.
#'
#' @examples
#' posterior_list <- list(Ctrl = RBesT::mixnorm(comp1 = c(w = 1, m = 0, s = 1), sigma = 2),
#' DG_1 = RBesT::mixnorm(comp1 = c(w = 1, m = 3, s = 1.2), sigma = 2),
#' DG_2 = RBesT::mixnorm(comp1 = c(w = 1, m = 4, s = 1.5), sigma = 2) ,
#' DG_2 = RBesT::mixnorm(comp1 = c(w = 1, m = 4, s = 1.5), sigma = 2) ,
#' DG_3 = RBesT::mixnorm(comp1 = c(w = 1, m = 6, s = 1.2), sigma = 2) ,
#' DG_4 = RBesT::mixnorm(comp1 = c(w = 1, m = 6.5, s = 1.1), sigma = 2))
#' models <- c("exponential", "linear")
Expand All @@ -23,40 +25,43 @@
#' posterior = posterior_list,
#' dose_levels = dose_levels,
#' simple = TRUE)
#'
#' getBootstrapSamples(model_fits = fit,
#'
#' getBootstrapQuantiles(model_fits = fit,
#' quantiles = c(0.025, 0.5, 0.975),
#' n_samples = 10, # speeding up example run time
#' doses = c(0, 6, 8))
#'
#' @return A data frame with columns for model, dose, and bootstrapped samples
#'
#'
#' @return A data frame with columns for model, dose, and bootstrapped samples
#'
#' @export
getBootstrapSamples <- function (
getBootstrapQuantiles <- function (

model_fits,
quantiles,
n_samples = 1e3,
doses = NULL,
avg_fit = TRUE

) {

mu_hat_samples <- sapply(attr(model_fits, "posterior"),
RBesT::rmix, n = n_samples)
sd_hat <- summary.postList(attr(model_fits, "posterior"))[, 2]

dose_levels <- model_fits[[1]]$dose_levels
model_names <- names(model_fits)

quantile_probs <- sort(unique(quantiles))

if (is.null(doses)) {

doses <- seq(min(dose_levels), max(dose_levels), length.out = 100L)

}

preds <- apply(mu_hat_samples, 1, function (mu_hat) {

preds_mu_hat <- sapply(model_names, function (model) {

fit <- DoseFinding::fitMod(
dose = model_fits[[1]]$dose_levels,
resp = mu_hat,
Expand All @@ -65,101 +70,50 @@ getBootstrapSamples <- function (
type = "general",
bnds = DoseFinding::defBnds(
mD = max(model_fits[[1]]$dose_levels))[[model]])

preds <- stats::predict(fit, doseSeq = doses, predType = "ls-means")
attr(preds, "gAIC") <- DoseFinding::gAIC(fit)

return (preds)

}, simplify = FALSE)

preds_mu_mat <- do.call(rbind, preds_mu_hat)

if (avg_fit) {

avg_fit_indx <- which.min(sapply(preds_mu_hat, attr, "gAIC"))
preds_mu_mat <- rbind(preds_mu_mat, avgFit = preds_mu_mat[avg_fit_indx, ])

}

return (preds_mu_mat)

})

if (avg_fit) {

model_names <- c(model_names, "avgFit")

}

bs_samples <- as.data.frame(preds[order(rep(seq_along(model_names), length(doses))), ])
colnames(bs_samples) <- paste0("preds_", seq_len(n_samples))

bs_samples_data <- cbind(
model = rep(
x = factor(model_names,
levels = c("linear", "emax", "exponential",
"sigEmax", "logistic", "quadratic",
"avgFit")),
each = length(doses)),
dose = doses,
bs_samples)

# tidyr::pivot_longer(bs_samples_data, cols = contains("preds"))

return (bs_samples_data)

}

#' @title getBootstrapQuantiles
#'
#' @description Calculates quantiles from bootstrapped dose predictions.
#' Can be used to derive credible intervals to assess the uncertainty for the model fit.
#' @param bs_samples An object of class bootstrappedSample as created by getBootstrapSamples
#' @param quantiles A vector of quantiles that should be evaluated
#'
#' @examples
#' posterior_list <- list(Ctrl = RBesT::mixnorm(comp1 = c(w = 1, m = 0, s = 1), sigma = 2),
#' DG_1 = RBesT::mixnorm(comp1 = c(w = 1, m = 3, s = 1.2), sigma = 2),
#' DG_2 = RBesT::mixnorm(comp1 = c(w = 1, m = 4, s = 1.5), sigma = 2) ,
#' DG_3 = RBesT::mixnorm(comp1 = c(w = 1, m = 6, s = 1.2), sigma = 2) ,
#' DG_4 = RBesT::mixnorm(comp1 = c(w = 1, m = 6.5, s = 1.1), sigma = 2))
#' models <- c("exponential", "linear")
#' dose_levels <- c(0, 1, 2, 4, 8)
#' fit <- getModelFits(models = models,
#' posterior = posterior_list,
#' dose_levels = dose_levels,
#' simple = TRUE)
#'
#' bs_samples <- getBootstrapSamples(model_fits = fit,
#' n_samples = 10, # speeding up example run time
#' doses = c(0, 6, 8))
#'
#' getBootstrapQuantiles(bs_samples = bs_samples,
#' quantiles = c(0.025, 0.5, 0.975))
#' @return A data frame with entries doses, models, and quantiles
#'
#' @export
getBootstrapQuantiles <- function (
sort_indx <- order(rep(seq_along(model_names), length(doses)))
quant_mat <- t(apply(X = preds[sort_indx, ],
MARGIN = 1,
FUN = stats::quantile,
probs = quantile_probs))

bs_samples,
quantiles

) {

quantile_probs <- sort(unique(quantiles))

bs_quantiles <- t(apply(X = bs_samples[, -c(1, 2)],
MARGIN = 1,
FUN = stats::quantile,
probs = quantile_probs))

bs_quantiles_data <- cbind(
bs_samples[, c(1, 2)],
as.data.frame(bs_quantiles))

return (bs_quantiles_data)
cr_bounds_data <- cbind(
doses = doses,
models = rep(
x = factor(model_names, levels = model_names),
each = length(doses)),
as.data.frame(quant_mat))

return (cr_bounds_data)

}



Loading
Loading