Skip to content

Commit

Permalink
Merge branch 'release/v0.7.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
dmphillippo committed Sep 16, 2024
2 parents 452dbd1 + cef5019 commit 9b85017
Show file tree
Hide file tree
Showing 25 changed files with 185 additions and 87 deletions.
8 changes: 4 additions & 4 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ message: 'To cite package "multinma" in publications use:'
type: software
license: GPL-3.0-only
title: 'multinma: Bayesian Network Meta-Analysis of Individual and Aggregate Data'
version: 0.7.1
version: 0.7.2
doi: 10.5281/zenodo.3904454
abstract: Network meta-analysis and network meta-regression models for aggregate data,
individual patient data, and mixtures of both individual and aggregate data using
Expand All @@ -27,8 +27,8 @@ preferred-citation:
given-names: David M.
email: [email protected]
orcid: https://orcid.org/0000-0003-2672-7841
year: '2023'
notes: R package version 0.7.1
year: '2024'
notes: R package version 0.7.2
url: https://dmphillippo.github.io/multinma/
doi: 10.5281/zenodo.3904454
repository: https://CRAN.R-project.org/package=multinma
Expand Down Expand Up @@ -636,7 +636,7 @@ references:
email: [email protected]
orcid: https://orcid.org/0000-0002-9808-2344
year: '2024'
version: '>= 2.26.0'
version: '>= 2.32.9'
- type: software
title: testthat
abstract: 'testthat: Unit Testing for R'
Expand Down
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: multinma
Title: Bayesian Network Meta-Analysis of Individual and Aggregate Data
Version: 0.7.1
Version: 0.7.2
Authors@R:
person(given = c("David", "M."),
family = "Phillippo",
Expand Down Expand Up @@ -53,7 +53,7 @@ LinkingTo:
rstan (>= 2.26.0),
StanHeaders (>= 2.32.9)
SystemRequirements: GNU make
RoxygenNote: 7.3.1
RoxygenNote: 7.3.2
Roxygen: list(markdown = TRUE)
Suggests:
testthat (>= 2.1.0),
Expand Down
14 changes: 14 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# multinma 0.7.2

* Fix: Predictions for non-proportional hazards IPD NMA or ML-NMR survival
models using `aux_regression = ~.trt` were incorrectly omitting the treatment
effects on the auxiliary parameter(s) in some cases (#43).
* Fix: Calling `marginal_effects()` for survival outcomes with a single target
population previously gave an error.
* Fix: Predictions from exponential models where `aux_regression` had been
specified were giving an error (#44). `aux_regression` and `aux_by` have no
effect for exponential models since there are no auxiliary (shape) parameters
and are ignored, now with a warning.
* Fix: Avoid an error when trying to fit M-spline models combining IPD and AgD
in R versions prior to 4.1.0, due to integer coercion of factors by `c()`.

# multinma 0.7.1

* Fix: Producing survival/hazard/cumulative hazard predictions for survival
Expand Down
2 changes: 1 addition & 1 deletion R/integration.R
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#' \code{\link[randtoolbox:quasiRNG]{sobol()}}
#'
#' @return For the `nma_data` method, an object of class [nma_data]. For the
#' `data.frame` method, the input data frame is returned (as a [tibble]) with
#' `data.frame` method, the input data frame is returned (as a `tibble`) with
#' an added column for each covariate (prefixed with ".int_"), containing the
#' numerical integration points nested as length-`n_int` vectors within each
#' row. For `unnest_integration()`, a data frame with integration points
Expand Down
2 changes: 1 addition & 1 deletion R/marginal_effects.R
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ marginal_effects <- function(object,
vars <- intersect(c(".study", ".time", ".quantile", ".category"), colnames(pred_meta))

if (".time" %in% vars) {
pred_meta <- dplyr::group_by(pred_meta, .data$.study, .data$.trt) %>%
pred_meta <- { if (".study" %in% vars) dplyr::group_by(pred_meta, .data$.study, .data$.trt) else dplyr::group_by(pred_meta, .data$.trt) } %>%
dplyr::mutate(.time_id = 1:dplyr::n()) %>%
dplyr::ungroup()

Expand Down
41 changes: 31 additions & 10 deletions R/nma.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
#' `combine_network()`, or `add_integration()`
#' @param consistency Character string specifying the type of (in)consistency
#' model to fit, either `"consistency"`, `"ume"`, or `"nodesplit"`
#' @param trt_effects Character string specifying either `"fixed"` or `"random"` effects
#' @param trt_effects Character string specifying either `"fixed"` or `"random"`
#' effects
#' @param regression A one-sided model formula, specifying the prognostic and
#' effect-modifying terms for a regression model. Any references to treatment
#' should use the `.trt` special variable, for example specifying effect
Expand All @@ -28,7 +29,8 @@
#' multiple treatment comparisons to split in turn. By default, all possible
#' comparisons will be chosen (see [get_nodesplits()]).
#' @param prior_intercept Specification of prior distribution for the intercept
#' @param prior_trt Specification of prior distribution for the treatment effects
#' @param prior_trt Specification of prior distribution for the treatment
#' effects
#' @param prior_het Specification of prior distribution for the heterogeneity
#' (if `trt_effects = "random"`)
#' @param prior_het_type Character string specifying whether the prior
Expand Down Expand Up @@ -106,8 +108,8 @@
#' For the advanced user, the additional specials `.study` and `.trtclass` are
#' also available, and refer to studies and (if specified) treatment classes
#' respectively. When node-splitting models are fitted (`consistency =
#' "nodesplit"`) the special `.omega` is available, indicating the arms
#' to which the node-splitting inconsistency factor is added.
#' "nodesplit"`) the special `.omega` is available, indicating the arms to
#' which the node-splitting inconsistency factor is added.
#'
#' See \code{\link[multinma:priors]{?priors}} for details on prior
#' specification. Default prior distributions are available, but may not be
Expand Down Expand Up @@ -231,7 +233,8 @@
#'
#' @return `nma()` returns a [stan_nma] object, except when `consistency =
#' "nodesplit"` when a [nma_nodesplit] or [nma_nodesplit_df] object is
#' returned. `nma.fit()` returns a [stanfit] object.
#' returned. `nma.fit()` returns a \code{\link[rstan:stanfit-class]{stanfit}}
#' object.
#' @export
#'
#' @references
Expand Down Expand Up @@ -569,8 +572,23 @@ nma <- function(network,
abort("Cannot specify both `aux_by` and `aux_regression`.")
}

if (!is.null(aux_regression)) {
if (!likelihood %in% valid_lhood$survival) {
warn("Ignoring `aux_regression`, only supported for survival likelihoods at present.")
} else if (!has_aux) {
warn(glue::glue("Ignoring `aux_regression`, no auxiliary parameters in {likelihood} model."))
}
}

if (!rlang::quo_is_null(aux_by)) {
if (!likelihood %in% valid_lhood$survival) {
warn("Ignoring `aux_by`, only supported for survival likelihoods at present.")
} else if (!has_aux) {
warn(glue::glue("Ignoring `aux_by`, no auxiliary parameters in {likelihood} model."))
}
}

# Set up aux_regression
has_aux_regression <- FALSE
if (!is.null(aux_regression) && likelihood %in% valid_lhood$survival &&
has_aux &&
(has_ipd(network) || has_agd_arm(network))) {
Expand All @@ -586,6 +604,9 @@ nma <- function(network,
aux_regression <- update.formula(aux_regression, ~. -.study +1)
}
has_aux_regression <- TRUE
} else {
has_aux_regression <- FALSE
aux_regression <- NULL
}

# Set up aux_by
Expand Down Expand Up @@ -906,7 +927,7 @@ nma <- function(network,
observed = .data$.Surv[, "status"] == 1)
} else {
dplyr::tibble(.Surv = c(y_ipd$.Surv, y_agd_arm$.Surv),
.study = forcats::fct_drop(c(dat_ipd$.study, rep(dat_agd_arm$.study, times = dat_agd_arm$.sample_size))),
.study = forcats::fct_drop(forcats::fct_c(dat_ipd$.study, rep(dat_agd_arm$.study, times = dat_agd_arm$.sample_size))),
observed = .data$.Surv[, "status"] == 1)
}

Expand Down Expand Up @@ -2670,11 +2691,11 @@ make_nma_formula <- function(regression,
}

if (consistency == "ume") {
nma_formula <- update.formula(nma_formula, ~-1 + .study + .contr + .)
nma_formula <- update.formula(nma_formula, ~.study + .contr + . -1)
} else if (consistency == "nodesplit") {
nma_formula <- update.formula(nma_formula, ~-1 + .study + .trt + .omega + .)
nma_formula <- update.formula(nma_formula, ~.study + .trt + .omega + . -1)
} else {
nma_formula <- update.formula(nma_formula, ~-1 + .study + .trt + .)
nma_formula <- update.formula(nma_formula, ~.study + .trt + . -1)
}
} else {
if (consistency == "ume") {
Expand Down
23 changes: 14 additions & 9 deletions R/nma_data-class.R
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,9 @@ green <- function(...) {
#' Convert networks to graph objects
#'
#' The method `as.igraph()` converts `nma_data` objects into the form used by
#' the [igraph] package. The method `as_tbl_graph()` converts `nma_data` objects
#' into the form used by the [ggraph] and
#' the \link[igraph:igraph-package]{igraph} package. The method `as_tbl_graph()`
#' converts `nma_data` objects into the form used by the
#' \link[ggraph:ggraph-package]{ggraph} and
#' \link[tidygraph:tidygraph-package]{tidygraph} packages.
#'
#' @param x An [nma_data] object to convert
Expand Down Expand Up @@ -682,13 +683,16 @@ has_indirect <- function(network, trt1, trt2) {
#' Create a network plot from a `nma_data` network object.
#'
#' @param x A [nma_data] object to plot
#' @param ... Additional arguments passed to [ggraph()] and on to the layout
#' function
#' @param layout The type of layout to create. Any layout accepted by [ggraph()]
#' may be used, including all of the layout functions provided by [igraph].
#' @param circular Whether to use a circular representation. See [ggraph()].
#' @param ... Additional arguments passed to
#' \code{\link[ggraph:ggraph]{ggraph()}} and on to the layout function
#' @param layout The type of layout to create. Any layout accepted by
#' \code{\link[ggraph:ggraph]{ggraph()}} may be used, including all of the
#' layout functions provided by \link[igraph:igraph-package]{igraph}.
#' @param circular Whether to use a circular representation. See
#' \code{\link[ggraph:ggraph]{ggraph()}}.
#' @param weight_edges Weight edges by the number of studies? Default is `TRUE`.
#' @param weight_nodes Weight nodes by the total sample size? Default is `FALSE`.
#' @param weight_nodes Weight nodes by the total sample size? Default is
#' `FALSE`.
#' @param show_trt_class Colour treatment nodes by class, if `trt_class` is set?
#' Default is `FALSE`.
#' @param nudge Numeric value to nudge the treatment labels away from the nodes
Expand All @@ -705,7 +709,8 @@ has_indirect <- function(network, trt1, trt2) {
#' any aggregate data in the network, using the `sample_size` option of
#' `set_agd_*()`.
#'
#' @return A `ggplot` object, as produced by [ggraph()].
#' @return A `ggplot` object, as produced by
#' \code{\link[ggraph:ggraph]{ggraph()}}.
#' @export
#'
#' @examples ## Stroke prevention in atrial fibrillation
Expand Down
2 changes: 1 addition & 1 deletion R/nma_nodesplit-class.R
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ NULL
#' Print `nma_nodesplit_df` objects
#'
#' @param x A [nma_nodesplit_df] object
#' @param ... Further arguments passed to [print.stanfit()]
#' @param ... Further arguments passed to \code{\link[rstan:print.stanfit]{print.stanfit()}}
#'
#' @seealso The summary method [summary.nma_nodesplit_df()] summarises the
#' node-splitting results.
Expand Down
11 changes: 6 additions & 5 deletions R/nma_summary-class.R
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,10 @@ print.nma_summary <- function(x, ..., digits = 2, pars, include = TRUE) {
#' @param ref_line Numeric vector of positions for reference lines, by default
#' no reference lines are drawn
#'
#' @details Plotting is handled by [ggplot2] and the stats and geoms provided in
#' the [ggdist] package. As a result, the output is very flexible. Any
#' plotting stats provided by `ggdist` may be used, via the argument
#' `stat`.
#' @details Plotting is handled by \link[ggplot2:ggplot2-package]{ggplot2} and
#' the stats and geoms provided in the \link[ggdist:ggdist-package]{ggdist}
#' package. As a result, the output is very flexible. Any plotting stats
#' provided by `ggdist` may be used, via the argument `stat`.
#'
#' The default uses
#' \code{\link[ggdist:stat_pointinterval]{ggdist::stat_pointinterval()}}, to
Expand All @@ -179,7 +179,8 @@ print.nma_summary <- function(x, ..., digits = 2, pars, include = TRUE) {
#' bands, specify `point_interval = "mean_qi"` and `.width = 0.95`.
#'
#' A `ggplot` object is returned which can be further modified through the
#' usual [ggplot2] functions to add further aesthetics, geoms, themes, etc.
#' usual \link[ggplot2:ggplot2-package]{ggplot2} functions to add further
#' aesthetics, geoms, themes, etc.
#'
#' @return A `ggplot` object.
#'
Expand Down
18 changes: 10 additions & 8 deletions R/nodesplit_summary-class.R
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,14 @@ as.data.frame.nodesplit_summary <- function(x, ...) {
#' @param ref_line Numeric vector of positions for reference lines, by default
#' no reference lines are drawn.
#'
#' @details Plotting is handled by [ggplot2] and the stats and geoms provided in
#' the [ggdist] package. As a result, the output is very flexible. Any
#' plotting stats provided by `ggdist` may be used, via the argument `stat`.
#' The default `"dens_overlay"` is a special exception, which uses
#' \code{\link[ggplot2:geom_density]{ggplot2::geom_density()}}, to plot overlaid
#' densities. Additional arguments in `...` are passed to the `ggdist` stat,
#' to customise the output.
#' @details Plotting is handled by \link[ggplot2:ggplot2-package]{ggplot2} and
#' the stats and geoms provided in the \link[ggdist:ggdist-package]{ggdist}
#' package. As a result, the output is very flexible. Any plotting stats
#' provided by `ggdist` may be used, via the argument `stat`. The default
#' `"dens_overlay"` is a special exception, which uses
#' \code{\link[ggplot2:geom_density]{ggplot2::geom_density()}}, to plot
#' overlaid densities. Additional arguments in `...` are passed to the
#' `ggdist` stat, to customise the output.
#'
#' Alternative stats can be specified to produce different summaries. For
#' example, specify `stat = "[half]eye"` to produce (half) eye plots, or `stat
Expand All @@ -162,7 +163,8 @@ as.data.frame.nodesplit_summary <- function(x, ...) {
#' `vignette("slabinterval", package = "ggdist")`.
#'
#' A `ggplot` object is returned which can be further modified through the
#' usual [ggplot2] functions to add further aesthetics, geoms, themes, etc.
#' usual \link[ggplot2:ggplot2-package]{ggplot2} functions to add further
#' aesthetics, geoms, themes, etc.
#'
#' @return A `ggplot` object.
#' @seealso [summary.nma_nodesplit_df()]
Expand Down
11 changes: 10 additions & 1 deletion R/predict.R
Original file line number Diff line number Diff line change
Expand Up @@ -1704,7 +1704,16 @@ predict.stan_nma <- function(object, ...,
if (!aux_int) { #(length(setdiff(object$aux_by, c(".study", ".trt"))) == 0) {
aux_s <- grepl(paste0("\\[(", paste(aux_l, collapse = "|"), if (object$likelihood %in% c("mspline", "pexp")) ")," else ")\\]"),
dimnames(aux_array)[[3]])
aux_array_s <- aux_array[ , , aux_s, drop = FALSE]

# Add in arm-level aux regression terms, if present
if (!is.null(object$aux_regression)) {
aux_array_s <- make_aux_predict(aux = aux_array[ , , aux_s, drop = FALSE],
beta_aux = beta_aux,
X_aux = X_aux[ss[1], , drop = FALSE],
likelihood = object$likelihood)
} else {
aux_array_s <- aux_array[ , , aux_s, drop = FALSE]
}

} else {
# Aux regression or stratified aux pars within arm, need to expand these out over the individuals/integration points
Expand Down
4 changes: 2 additions & 2 deletions R/stan_nma-class.R
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ NULL
#' Print `stan_nma` objects
#'
#' @param x A [stan_nma] object
#' @param ... Further arguments passed to [print.stanfit()]
#' @param ... Further arguments passed to \code{\link[rstan:print.stanfit]{print.stanfit()}}
#'
#' @return `x` is returned invisibly.
#'
Expand Down Expand Up @@ -722,7 +722,7 @@ as.stanfit.default <- function(x, ...) {
#' array, matrix, or data frame.
#'
#' @param x A `stan_nma` object
#' @param ... Additional arguments passed to [as.array.stanfit()]
#' @param ... Additional arguments passed to \code{\link[rstan:as.array.stanfit]{as.array.stanfit()}}
#' @param pars Optional character vector of parameter names to include in output. If not specified, all parameters are used.
#' @param include Logical, are parameters in `pars` to be included (`TRUE`, default) or excluded (`FALSE`)?
#'
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ papers:
The `multinma` package can be cited as follows:

> Phillippo, D. M. (2024). *multinma: Bayesian Network Meta-Analysis of
> Individual and Aggregate Data*. R package version 0.7.1, doi:
> Individual and Aggregate Data*. R package version 0.7.2, doi:
> [10.5281/zenodo.3904454](https://doi.org/10.5281/zenodo.3904454).
When fitting ML-NMR models, please cite the methods paper:
Expand Down
14 changes: 4 additions & 10 deletions cran-comments.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
Require StanHeaders version 2.32.9 or later in LinkingTo, as requested, which
fixes the UBSAN warnings.

Confirmed that this fixes the sanitizer warnings with rocker/r-devel-san and
rhub clang-asan.
This is a minor bugfix release. Also addresses new CRAN check note "Rd \link{}
targets missing package anchors".

## Test environments
* rocker/r-devel-san
* rhub clang-asan
* local R installation (Windows 10), R 4.4.0
* win-builder (release, devel)
* local R installation (Windows 10), R 4.4.1
* Ubuntu 22.04.4 on GitHub Actions (release, devel, oldrel)
* Mac OS 14.4.1 on GitHub Actions (release)
* Mac OS 14.6.1 on GitHub Actions (release)
* Windows Server 2022 10.0.20348 on GitHub Actions (release)

## R CMD check results
Expand Down
2 changes: 1 addition & 1 deletion inst/CITATION
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
bibentry(bibtype = "Manual",
title = "multinma: Bayesian Network Meta-Analysis of Individual and Aggregate Data",
author = person(c("David", "M."), "Phillippo"),
year = ifelse(is.null(meta$Date), "2023", substr(meta$Date, 1, 4)),
year = ifelse(is.null(meta$Date), "2024", substr(meta$Date, 1, 4)),
note = sprintf("R package version %s", meta$Version),
url = "https://dmphillippo.github.io/multinma/",
doi = "10.5281/zenodo.3904454",
Expand Down
2 changes: 1 addition & 1 deletion man/add_integration.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/as.array.stan_nma.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions man/graph_conversion.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 9b85017

Please sign in to comment.